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 2016/12/05 05:42:33 UTC
[1/9] mesos git commit: Added an I/O switchboard test with TTY
enabled.
Repository: mesos
Updated Branches:
refs/heads/master 97696a06b -> 61e2dc1d8
Added an I/O switchboard test with TTY enabled.
Review: https://reviews.apache.org/r/54294
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/61e2dc1d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/61e2dc1d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/61e2dc1d
Branch: refs/heads/master
Commit: 61e2dc1d8cf853179a2d423fedfc972653ea5db2
Parents: fd142a0
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Dec 1 22:12:16 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
.../containerizer/io_switchboard_tests.cpp | 88 ++++++++++++++++++--
1 file changed, 83 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/61e2dc1d/src/tests/containerizer/io_switchboard_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/io_switchboard_tests.cpp b/src/tests/containerizer/io_switchboard_tests.cpp
index d2db61e..ebf9bc7 100644
--- a/src/tests/containerizer/io_switchboard_tests.cpp
+++ b/src/tests/containerizer/io_switchboard_tests.cpp
@@ -23,10 +23,12 @@
#include <stout/json.hpp>
#include <stout/os.hpp>
+#include <stout/path.hpp>
#include <stout/protobuf.hpp>
#include <stout/uuid.hpp>
#include <mesos/http.hpp>
+#include <mesos/mesos.hpp>
#include <mesos/agent/agent.hpp>
@@ -35,6 +37,7 @@
#include "slave/containerizer/mesos/io/switchboard.hpp"
+#include "tests/environment.hpp"
#include "tests/mesos.hpp"
namespace http = process::http;
@@ -45,8 +48,13 @@ namespace unix = process::network::unix;
using mesos::agent::Call;
-
+using mesos::internal::slave::Fetcher;
using mesos::internal::slave::IOSwitchboardServer;
+using mesos::internal::slave::MesosContainerizer;
+
+using mesos::internal::slave::state::SlaveState;
+
+using mesos::slave::ContainerTermination;
using process::Future;
using process::Owned;
@@ -57,11 +65,11 @@ namespace mesos {
namespace internal {
namespace tests {
-class IOSwitchboardTest : public TemporaryDirectoryTest {};
+#ifndef __WINDOWS__
+class IOSwitchboardServerTest : public TemporaryDirectoryTest {};
-#ifndef __WINDOWS__
-TEST_F(IOSwitchboardTest, ServerRedirectLog)
+TEST_F(IOSwitchboardServerTest, ServerRedirectLog)
{
int stdoutPipe[2];
int stderrPipe[2];
@@ -150,7 +158,7 @@ TEST_F(IOSwitchboardTest, ServerRedirectLog)
}
-TEST_F(IOSwitchboardTest, ServerAttachOutput)
+TEST_F(IOSwitchboardServerTest, ServerAttachOutput)
{
Try<int> nullFd = os::open("/dev/null", O_RDWR);
ASSERT_SOME(nullFd);
@@ -294,6 +302,76 @@ TEST_F(IOSwitchboardTest, ServerAttachOutput)
EXPECT_EQ(data, stdoutReceived);
EXPECT_EQ(data, stderrReceived);
}
+
+
+class IOSwitchboardTest
+ : public ContainerizerTest<slave::MesosContainerizer> {};
+
+
+// The test verifies the output redirection of the container with TTY
+// allocated for the container.
+TEST_F(IOSwitchboardTest, OutputRedirectionWithTTY)
+{
+ slave::Flags flags = CreateSlaveFlags();
+ flags.launcher = "posix";
+ flags.isolation = "posix/cpu";
+ flags.io_switchboard_enable_server = true;
+
+ Fetcher fetcher;
+
+ Try<MesosContainerizer*> create = MesosContainerizer::create(
+ flags,
+ false,
+ &fetcher);
+
+ ASSERT_SOME(create);
+
+ Owned<MesosContainerizer> containerizer(create.get());
+
+ SlaveState state;
+ state.id = SlaveID();
+
+ AWAIT_READY(containerizer->recover(state));
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
+
+ Try<string> directory = environment->mkdtemp();
+ ASSERT_SOME(directory);
+
+ // Print 'Hello' to stdout and 'World' to stderr. Since the
+ // container requests a TTY. Both will be redirected to the same
+ // terminal device and logged in 'stdout' in the sandbox.
+ ExecutorInfo executorInfo = createExecutorInfo(
+ "executor",
+ "printf Hello; printf World 1>&2",
+ "cpus:1");
+
+ // Request a tty for the container.
+ executorInfo.mutable_container()->set_type(ContainerInfo::MESOS);
+ executorInfo.mutable_container()->mutable_tty_info();
+
+ Future<bool> launch = containerizer->launch(
+ containerId,
+ None(),
+ executorInfo,
+ directory.get(),
+ None(),
+ SlaveID(),
+ map<string, string>(),
+ true); // TODO(benh): Ever want to test not checkpointing?
+
+ AWAIT_ASSERT_TRUE(launch);
+
+ Future<Option<ContainerTermination>> wait = containerizer->wait(containerId);
+
+ AWAIT_READY(wait);
+ ASSERT_SOME(wait.get());
+ ASSERT_TRUE(wait.get()->has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait.get()->status());
+
+ EXPECT_SOME_EQ("HelloWorld", os::read(path::join(directory.get(), "stdout")));
+}
#endif // __WINDOWS__
} // namespace tests {
[2/9] mesos git commit: Allowed subprocess to take duplicated FDs.
Posted by ji...@apache.org.
Allowed subprocess to take duplicated FDs.
Review: https://reviews.apache.org/r/54351
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c7f953aa
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c7f953aa
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c7f953aa
Branch: refs/heads/master
Commit: c7f953aadcead297d8119e0c3564b8a2f67b518e
Parents: d6bc482
Author: Jie Yu <yu...@gmail.com>
Authored: Sat Dec 3 23:53:00 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
.../include/process/posix/subprocess.hpp | 66 +++++++++++---------
.../include/process/windows/subprocess.hpp | 29 +++++----
3rdparty/libprocess/src/subprocess.cpp | 12 ++--
3 files changed, 62 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/c7f953aa/3rdparty/libprocess/include/process/posix/subprocess.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/posix/subprocess.hpp b/3rdparty/libprocess/include/process/posix/subprocess.hpp
index aa4609d..60f40ea 100644
--- a/3rdparty/libprocess/include/process/posix/subprocess.hpp
+++ b/3rdparty/libprocess/include/process/posix/subprocess.hpp
@@ -27,6 +27,7 @@
#include <stout/check.hpp>
#include <stout/error.hpp>
#include <stout/foreach.hpp>
+#include <stout/hashset.hpp>
#include <stout/nothing.hpp>
#include <stout/lambda.hpp>
#include <stout/none.hpp>
@@ -70,6 +71,15 @@ inline pid_t defaultClone(const lambda::function<int()>& func)
namespace internal {
+inline void close(const hashset<int>& fds)
+{
+ foreach (int fd, fds) {
+ if (fd >= 0) {
+ os::close(fd);
+ }
+ }
+}
+
// This function will invoke `os::close` on all specified file
// descriptors that are valid (i.e., not `None` and >= 0).
inline void close(
@@ -77,17 +87,14 @@ inline void close(
const OutputFileDescriptors& stdoutfds,
const OutputFileDescriptors& stderrfds)
{
- int fds[6] = {
- stdinfds.read, stdinfds.write.getOrElse(-1),
- stdoutfds.read.getOrElse(-1), stdoutfds.write,
- stderrfds.read.getOrElse(-1), stderrfds.write
- };
-
- foreach (int fd, fds) {
- if (fd >= 0) {
- os::close(fd);
- }
- }
+ close({
+ stdinfds.read,
+ stdinfds.write.getOrElse(-1),
+ stdoutfds.read.getOrElse(-1),
+ stdoutfds.write,
+ stderrfds.read.getOrElse(-1),
+ stderrfds.write
+ });
}
@@ -98,10 +105,13 @@ inline Try<Nothing> cloexec(
const OutputFileDescriptors& stdoutfds,
const OutputFileDescriptors& stderrfds)
{
- int fds[6] = {
- stdinfds.read, stdinfds.write.getOrElse(-1),
- stdoutfds.read.getOrElse(-1), stdoutfds.write,
- stderrfds.read.getOrElse(-1), stderrfds.write
+ hashset<int> fds = {
+ stdinfds.read,
+ stdinfds.write.getOrElse(-1),
+ stdoutfds.read.getOrElse(-1),
+ stdoutfds.write,
+ stderrfds.read.getOrElse(-1),
+ stderrfds.write
};
foreach (int fd, fds) {
@@ -167,6 +177,10 @@ inline int childMain(
// parent has closed stdin/stdout/stderr when calling this
// function (in that case, a dup'ed file descriptor may have the
// same file descriptor number as stdin/stdout/stderr).
+ //
+ // We also need to ensure that we don't "double close" any file
+ // descriptors in the case where one of stdinfds.read,
+ // stdoutfds.write, or stdoutfds.write are equal.
if (stdinfds.read != STDIN_FILENO &&
stdinfds.read != STDOUT_FILENO &&
stdinfds.read != STDERR_FILENO) {
@@ -174,12 +188,15 @@ inline int childMain(
}
if (stdoutfds.write != STDIN_FILENO &&
stdoutfds.write != STDOUT_FILENO &&
- stdoutfds.write != STDERR_FILENO) {
+ stdoutfds.write != STDERR_FILENO &&
+ stdoutfds.write != stdinfds.read) {
::close(stdoutfds.write);
}
if (stderrfds.write != STDIN_FILENO &&
stderrfds.write != STDOUT_FILENO &&
- stderrfds.write != STDERR_FILENO) {
+ stderrfds.write != STDERR_FILENO &&
+ stderrfds.write != stdinfds.read &&
+ stderrfds.write != stdoutfds.write) {
::close(stderrfds.write);
}
@@ -313,6 +330,10 @@ inline Try<pid_t> cloneChild(
return error;
}
+ // Close the child-ends of the file descriptors that are created by
+ // this function.
+ internal::close({stdinfds.read, stdoutfds.write, stderrfds.write});
+
if (blocking) {
os::close(pipes[0]);
@@ -329,12 +350,6 @@ inline Try<pid_t> cloneChild(
os::close(pipes[1]);
- // Close the child-ends of the file descriptors that are created
- // by this function.
- os::close(stdinfds.read);
- os::close(stdoutfds.write);
- os::close(stderrfds.write);
-
// Ensure the child is killed.
::kill(pid, SIGKILL);
@@ -357,11 +372,6 @@ inline Try<pid_t> cloneChild(
// Ensure the child is killed.
::kill(pid, SIGKILL);
- // Close the child-ends of the file descriptors that are created
- // by this function.
- os::close(stdinfds.read);
- os::close(stdoutfds.write);
- os::close(stderrfds.write);
return Error("Failed to synchronize child process");
}
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/c7f953aa/3rdparty/libprocess/include/process/windows/subprocess.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/windows/subprocess.hpp b/3rdparty/libprocess/include/process/windows/subprocess.hpp
index f452f67..e2ba752 100644
--- a/3rdparty/libprocess/include/process/windows/subprocess.hpp
+++ b/3rdparty/libprocess/include/process/windows/subprocess.hpp
@@ -23,6 +23,7 @@
#include <stout/error.hpp>
#include <stout/foreach.hpp>
+#include <stout/hashset.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
#include <stout/try.hpp>
@@ -44,6 +45,15 @@ using OutputFileDescriptors = Subprocess::IO::OutputFileDescriptors;
namespace internal {
+inline void close(const hashset<HANDLE>& fds)
+{
+ foreach (HANDLE fd, fds) {
+ if (fd != INVALID_HANDLE_VALUE) {
+ os::close(fd);
+ }
+ }
+}
+
// This function will invoke `os::close` on all specified file
// descriptors that are valid (i.e., not `None` and >= 0).
inline void close(
@@ -51,17 +61,14 @@ inline void close(
const OutputFileDescriptors& stdoutfds,
const OutputFileDescriptors& stderrfds)
{
- HANDLE fds[6] = {
- stdinfds.read, stdinfds.write.getOrElse(INVALID_HANDLE_VALUE),
- stdoutfds.read.getOrElse(INVALID_HANDLE_VALUE), stdoutfds.write,
- stderrfds.read.getOrElse(INVALID_HANDLE_VALUE), stderrfds.write
- };
-
- foreach (HANDLE fd, fds) {
- if (fd != INVALID_HANDLE_VALUE) {
- os::close(fd);
- }
- }
+ close({
+ stdinfds.read,
+ stdinfds.write.getOrElse(INVALID_HANDLE_VALUE),
+ stdoutfds.read.getOrElse(INVALID_HANDLE_VALUE),
+ stdoutfds.write,
+ stderrfds.read.getOrElse(INVALID_HANDLE_VALUE),
+ stderrfds.write
+ });
}
// Retrieves system environment in a `std::map`, ignoring
http://git-wip-us.apache.org/repos/asf/mesos/blob/c7f953aa/3rdparty/libprocess/src/subprocess.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/subprocess.cpp b/3rdparty/libprocess/src/subprocess.cpp
index b3efb9c..340fc32 100644
--- a/3rdparty/libprocess/src/subprocess.cpp
+++ b/3rdparty/libprocess/src/subprocess.cpp
@@ -327,17 +327,17 @@ Try<Subprocess> subprocess(
return error;
}
+ // Close the child-ends of the file descriptors that are created
+ // by this function.
+ // TODO(jieyu): We should move the closing of FDs to
+ // 'createChildProcess' to be consistent with the posix path.
+ internal::close({stdinfds.read, stdoutfds.write, stderrfds.write});
+
process.data->processInformation = processInformation.get();
process.data->pid = processInformation.get().dwProcessId;
#endif // __WINDOWS__
}
- // Close the child-ends of the file descriptors that are created
- // by this function.
- os::close(stdinfds.read);
- os::close(stdoutfds.write);
- os::close(stderrfds.write);
-
// For any pipes, store the parent side of the pipe so that
// the user can communicate with the subprocess.
process.data->in = stdinfds.write;
[4/9] mesos git commit: Added a check to require I/O switchboard
server for TTY support.
Posted by ji...@apache.org.
Added a check to require I/O switchboard server for TTY support.
Review: https://reviews.apache.org/r/54289
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a43d57b6
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a43d57b6
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a43d57b6
Branch: refs/heads/master
Commit: a43d57b6b54d152fd38733b666dd4b4a0cf25f95
Parents: 97696a0
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Dec 1 13:42:11 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
src/slave/containerizer/mesos/io/switchboard.cpp | 7 +++++++
1 file changed, 7 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/a43d57b6/src/slave/containerizer/mesos/io/switchboard.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/io/switchboard.cpp b/src/slave/containerizer/mesos/io/switchboard.cpp
index 778367a..2362f1b 100644
--- a/src/slave/containerizer/mesos/io/switchboard.cpp
+++ b/src/slave/containerizer/mesos/io/switchboard.cpp
@@ -171,6 +171,13 @@ Future<Option<ContainerLaunchInfo>> IOSwitchboard::_prepare(
#endif
if (!flags.io_switchboard_enable_server) {
+ // TTY support requires I/O switchboard server so that stdio can
+ // be properly redirected to logger.
+ if (containerConfig.has_container_info() &&
+ containerConfig.container_info().has_tty_info()) {
+ return Failure("TTY support requires I/O switchboard server");
+ }
+
ContainerLaunchInfo launchInfo;
ContainerIO* out = launchInfo.mutable_out();
[8/9] mesos git commit: Supported TTY in I/O switchboard.
Posted by ji...@apache.org.
Supported TTY in I/O switchboard.
Review: https://reviews.apache.org/r/54293
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/fd142a0d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/fd142a0d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/fd142a0d
Branch: refs/heads/master
Commit: fd142a0d7b7ec27fdcffc3d679db46edc9432de3
Parents: c7f953a
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Dec 1 18:16:06 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
include/mesos/slave/containerizer.proto | 3 +
src/slave/containerizer/mesos/containerizer.cpp | 5 +
.../containerizer/mesos/io/switchboard.cpp | 280 ++++++++++++++-----
.../containerizer/mesos/io/switchboard.hpp | 31 +-
.../containerizer/mesos/io/switchboard_main.cpp | 1 +
src/slave/containerizer/mesos/launch.cpp | 10 +
.../containerizer/io_switchboard_tests.cpp | 2 +
7 files changed, 251 insertions(+), 81 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/fd142a0d/include/mesos/slave/containerizer.proto
----------------------------------------------------------------------
diff --git a/include/mesos/slave/containerizer.proto b/include/mesos/slave/containerizer.proto
index 33b4c23..c70d437 100644
--- a/include/mesos/slave/containerizer.proto
+++ b/include/mesos/slave/containerizer.proto
@@ -212,6 +212,9 @@ message ContainerLaunchInfo {
optional ContainerIO in = 11;
optional ContainerIO out = 12;
optional ContainerIO err = 13;
+
+ // (POSIX only) The slave path of the pseudo terminal.
+ optional string tty_slave_path = 14;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/fd142a0d/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index a7e2665..13cf757 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -1272,6 +1272,11 @@ Future<bool> MesosContainerizerProcess::_launch(
return Failure("Multiple isolators specify stderr");
}
+ if (isolatorLaunchInfo->has_tty_slave_path() &&
+ launchInfo.has_tty_slave_path()) {
+ return Failure("Multiple isolators specify tty");
+ }
+
launchInfo.MergeFrom(isolatorLaunchInfo.get());
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/fd142a0d/src/slave/containerizer/mesos/io/switchboard.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/io/switchboard.cpp b/src/slave/containerizer/mesos/io/switchboard.cpp
index 2362f1b..d5211b9 100644
--- a/src/slave/containerizer/mesos/io/switchboard.cpp
+++ b/src/slave/containerizer/mesos/io/switchboard.cpp
@@ -14,6 +14,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <stdio.h>
+#include <stdlib.h>
+
#include <list>
#include <map>
#include <string>
@@ -38,6 +41,10 @@
#include <stout/path.hpp>
#include <stout/recordio.hpp>
+#ifndef __WINDOWS__
+#include <stout/posix/os.hpp>
+#endif // __WINDOWS__
+
#include <mesos/http.hpp>
#include <mesos/type_utils.hpp>
@@ -64,6 +71,7 @@ namespace unix = process::network::unix;
using std::string;
+using process::ErrnoFailure;
using process::Failure;
using process::Future;
using process::Owned;
@@ -170,11 +178,13 @@ Future<Option<ContainerLaunchInfo>> IOSwitchboard::_prepare(
}
#endif
+ bool hasTTY = containerConfig.has_container_info() &&
+ containerConfig.container_info().has_tty_info();
+
if (!flags.io_switchboard_enable_server) {
// TTY support requires I/O switchboard server so that stdio can
// be properly redirected to logger.
- if (containerConfig.has_container_info() &&
- containerConfig.container_info().has_tty_info()) {
+ if (hasTTY) {
return Failure("TTY support requires I/O switchboard server");
}
@@ -220,78 +230,175 @@ Future<Option<ContainerLaunchInfo>> IOSwitchboard::_prepare(
" '" + stringify(containerId) + "'");
}
+ // Return the set of fds that should be sent to the
+ // container and dup'd onto its stdin/stdout/stderr.
+ ContainerLaunchInfo launchInfo;
+
// Manually construct pipes instead of using `Subprocess::PIPE`
// so that the ownership of the FDs is properly represented. The
// `Subprocess` spawned below owns one end of each pipe and will
// be solely responsible for closing that end. The ownership of
// the other end will be passed to the caller of this function
// and eventually passed to the container being launched.
- int infds[2];
- int outfds[2];
- int errfds[2];
+ int stdinToFd = -1;
+ int stdoutFromFd = -1;
+ int stderrFromFd = -1;
// A list of file decriptors we've opened so far.
- vector<int> fds = {};
+ hashset<int> openedFds = {};
+
+ // A list of file descriptors that will be passed to the I/O
+ // switchboard. We need to close those file descriptors once the
+ // I/O switchboard server is forked.
+ hashset<int> ioSwitchboardFds = {};
- // Helper for closing the list of file
- // descriptors we've opened so far.
- auto close = [](const vector<int>& fds) {
+ // Helper for closing a set of file descriptors.
+ auto close = [](const hashset<int>& fds) {
foreach (int fd, fds) {
os::close(fd);
}
};
- Try<Nothing> pipe = os::pipe(infds);
- if (pipe.isError()) {
- close(fds);
- return Failure("Failed to create stdin pipe: " + pipe.error());
- }
+ // Setup a pseudo terminal for the container.
+ if (hasTTY) {
+ // TODO(jieyu): Consider moving all TTY related method to stout.
+ // For instance, 'stout/posix/tty.hpp'.
- fds.push_back(infds[0]);
- fds.push_back(infds[1]);
+ // Set flag 'O_NOCTTY' so that the terminal device will not become
+ // the controlling terminal for the process.
+ int master = posix_openpt(O_RDWR | O_NOCTTY | O_CLOEXEC);
+ if (master == -1) {
+ return Failure("Failed to open a master pseudo terminal");
+ }
- pipe = os::pipe(outfds);
- if (pipe.isError()) {
- close(fds);
- return Failure("Failed to create stdout pipe: " + pipe.error());
- }
+ openedFds.insert(master);
- fds.push_back(outfds[0]);
- fds.push_back(outfds[1]);
+ Try<string> slavePath = os::ptsname(master);
+ if (slavePath.isError()) {
+ close(openedFds);
+ return Failure("Failed to get the slave pseudo terminal path: " +
+ slavePath.error());
+ }
- pipe = os::pipe(errfds);
- if (pipe.isError()) {
- close(fds);
- return Failure("Failed to create stderr pipe: " + pipe.error());
- }
+ // Unlock the slave end of the pseudo terminal.
+ if (unlockpt(master) != 0) {
+ close(openedFds);
+ return ErrnoFailure("Failed to unlock the slave pseudo terminal");
+ }
+
+ // Set proper permission and ownership for the device.
+ if (grantpt(master) != 0) {
+ close(openedFds);
+ return ErrnoFailure("Failed to grant the slave pseudo terminal");
+ }
- fds.push_back(errfds[0]);
- fds.push_back(errfds[1]);
+ if (containerConfig.has_user()) {
+ Try<Nothing> chown = os::chown(
+ containerConfig.user(),
+ slavePath.get(),
+ false);
- Try<Nothing> cloexec = os::cloexec(infds[0]);
- if (cloexec.isError()) {
- close(fds);
- return Failure("Failed to cloexec infds.read: " + cloexec.error());
- }
+ if (chown.isError()) {
+ close(openedFds);
+ return Failure("Failed to chown the slave pseudo terminal: " +
+ chown.error());
+ }
+ }
+
+ // Open the slave end of the pseudo terminal. The opened file
+ // descriptor will be dup'ed to stdin/out/err of the container.
+ Try<int> slave = os::open(slavePath.get(), O_RDWR | O_NOCTTY | O_CLOEXEC);
+ if (slave.isError()) {
+ return Failure("Failed to open the slave pseudo terminal: " +
+ slave.error());
+ }
- cloexec = os::cloexec(outfds[1]);
- if (cloexec.isError()) {
- close(fds);
- return Failure("Failed to cloexec outfds.write: " + cloexec.error());
+ openedFds.insert(slave.get());
+
+ LOG(INFO) << "Allocated pseudo terminal '" << slavePath.get()
+ << "' for container " << containerId;
+
+ stdinToFd = master;
+ stdoutFromFd = master;
+ stderrFromFd = master;
+
+ launchInfo.mutable_in()->set_type(ContainerIO::FD);
+ launchInfo.mutable_in()->set_fd(slave.get());
+
+ launchInfo.mutable_out()->set_type(ContainerIO::FD);
+ launchInfo.mutable_out()->set_fd(slave.get());
+
+ launchInfo.mutable_err()->set_type(ContainerIO::FD);
+ launchInfo.mutable_err()->set_fd(slave.get());
+
+ launchInfo.set_tty_slave_path(slavePath.get());
+ } else {
+ int infds[2];
+ int outfds[2];
+ int errfds[2];
+
+ Try<Nothing> pipe = os::pipe(infds);
+ if (pipe.isError()) {
+ close(openedFds);
+ return Failure("Failed to create stdin pipe: " + pipe.error());
+ }
+
+ openedFds.insert(infds[0]);
+ openedFds.insert(infds[1]);
+
+ pipe = os::pipe(outfds);
+ if (pipe.isError()) {
+ close(openedFds);
+ return Failure("Failed to create stdout pipe: " + pipe.error());
+ }
+
+ openedFds.insert(outfds[0]);
+ openedFds.insert(outfds[1]);
+
+ pipe = os::pipe(errfds);
+ if (pipe.isError()) {
+ close(openedFds);
+ return Failure("Failed to create stderr pipe: " + pipe.error());
+ }
+
+ openedFds.insert(errfds[0]);
+ openedFds.insert(errfds[1]);
+
+ stdinToFd = infds[1];
+ stdoutFromFd = outfds[0];
+ stderrFromFd = errfds[0];
+
+ launchInfo.mutable_in()->set_type(ContainerIO::FD);
+ launchInfo.mutable_in()->set_fd(infds[0]);
+
+ launchInfo.mutable_out()->set_type(ContainerIO::FD);
+ launchInfo.mutable_out()->set_fd(outfds[1]);
+
+ launchInfo.mutable_err()->set_type(ContainerIO::FD);
+ launchInfo.mutable_err()->set_fd(errfds[1]);
}
- cloexec = os::cloexec(errfds[1]);
- if (cloexec.isError()) {
- close(fds);
- return Failure("Failed to cloexec errfds.write: " + cloexec.error());
+ // Make sure all file descriptors opened have CLOEXEC set.
+ foreach (int fd, openedFds) {
+ Try<Nothing> cloexec = os::cloexec(fd);
+ if (cloexec.isError()) {
+ close(openedFds);
+ return Failure("Failed to set cloexec: " + cloexec.error());
+ }
}
+ ioSwitchboardFds.insert(stdinToFd);
+ ioSwitchboardFds.insert(stdoutFromFd);
+ ioSwitchboardFds.insert(stderrFromFd);
+
// Set up our flags to send to the io switchboard server process.
IOSwitchboardServerFlags switchboardFlags;
- switchboardFlags.stdin_to_fd = infds[1];
- switchboardFlags.stdout_from_fd = outfds[0];
+ switchboardFlags.tty = hasTTY;
+
+ // We use the default values for other file descriptor flags. Since
+ // I/O switchboard server's stdout and stderr will be redirected to
+ // the logger, we explicitly set the flags here.
switchboardFlags.stdout_to_fd = STDOUT_FILENO;
- switchboardFlags.stderr_from_fd = errfds[0];
switchboardFlags.stderr_to_fd = STDERR_FILENO;
if (containerConfig.container_class() == ContainerClass::DEBUG) {
@@ -321,17 +428,30 @@ Future<Option<ContainerLaunchInfo>> IOSwitchboard::_prepare(
map<string, string>(),
None(),
{},
- {Subprocess::ChildHook::SETSID()});
+ {Subprocess::ChildHook::SETSID(),
+ Subprocess::ChildHook::DUP2(
+ stdinToFd,
+ IOSwitchboardServer::STDIN_TO_FD),
+ Subprocess::ChildHook::DUP2(
+ stdoutFromFd,
+ IOSwitchboardServer::STDOUT_FROM_FD),
+ Subprocess::ChildHook::DUP2(
+ stderrFromFd,
+ IOSwitchboardServer::STDERR_FROM_FD)});
if (child.isError()) {
- close(fds);
+ close(openedFds);
return Failure("Failed to create io switchboard"
" server process: " + child.error());
}
- os::close(infds[1]);
- os::close(outfds[0]);
- os::close(errfds[0]);
+ close(ioSwitchboardFds);
+
+ // We remove the already closed file descriptors from 'openedFds' so
+ // that we don't close multiple times if failures happen below.
+ foreach (int fd, ioSwitchboardFds) {
+ openedFds.erase(fd);
+ }
// Now that the child has come up, we checkpoint the socket
// address we told it to bind to so we can access it later.
@@ -343,7 +463,7 @@ Future<Option<ContainerLaunchInfo>> IOSwitchboard::_prepare(
path, switchboardFlags.socket_path);
if (checkpointed.isError()) {
- close(fds);
+ close(openedFds);
return Failure("Failed to checkpoint container's socket path to"
" '" + path + "': " + checkpointed.error());
}
@@ -353,19 +473,6 @@ Future<Option<ContainerLaunchInfo>> IOSwitchboard::_prepare(
child->pid(),
process::reap(child->pid())));
- // Return the set of fds that should be sent to the
- // container and dup'd onto its stdin/stdout/stderr.
- ContainerLaunchInfo launchInfo;
-
- launchInfo.mutable_in()->set_type(ContainerIO::FD);
- launchInfo.mutable_in()->set_fd(infds[0]);
-
- launchInfo.mutable_out()->set_type(ContainerIO::FD);
- launchInfo.mutable_out()->set_fd(outfds[1]);
-
- launchInfo.mutable_err()->set_type(ContainerIO::FD);
- launchInfo.mutable_err()->set_fd(errfds[1]);
-
return launchInfo;
#endif // __WINDOWS__
}
@@ -435,13 +542,19 @@ Future<Nothing> IOSwitchboard::cleanup(
#ifndef __WINDOWS__
-constexpr char IOSwitchboardServer::NAME[];
+const char IOSwitchboardServer::NAME[] = "mesos-io-switchboard";
+const int IOSwitchboardServer::STDIN_TO_FD = STDERR_FILENO + 1;
+const int IOSwitchboardServer::STDOUT_FROM_FD = STDERR_FILENO + 2;
+const int IOSwitchboardServer::STDERR_FROM_FD = STDERR_FILENO + 3;
+const int IOSwitchboardServer::STDOUT_TO_FD = STDERR_FILENO + 4;
+const int IOSwitchboardServer::STDERR_TO_FD = STDERR_FILENO + 5;
class IOSwitchboardServerProcess : public Process<IOSwitchboardServerProcess>
{
public:
IOSwitchboardServerProcess(
+ bool _tty,
int _stdinToFd,
int _stdoutFromFd,
int _stdoutToFd,
@@ -507,6 +620,7 @@ private:
const string& data,
const agent::ProcessIO::Data::Type& type);
+ bool tty;
int stdinToFd;
int stdoutFromFd;
int stdoutToFd;
@@ -524,6 +638,7 @@ private:
Try<Owned<IOSwitchboardServer>> IOSwitchboardServer::create(
+ bool tty,
int stdinToFd,
int stdoutFromFd,
int stdoutToFd,
@@ -556,6 +671,7 @@ Try<Owned<IOSwitchboardServer>> IOSwitchboardServer::create(
}
return new IOSwitchboardServer(
+ tty,
stdinToFd,
stdoutFromFd,
stdoutToFd,
@@ -567,6 +683,7 @@ Try<Owned<IOSwitchboardServer>> IOSwitchboardServer::create(
IOSwitchboardServer::IOSwitchboardServer(
+ bool tty,
int stdinToFd,
int stdoutFromFd,
int stdoutToFd,
@@ -575,6 +692,7 @@ IOSwitchboardServer::IOSwitchboardServer(
const unix::Socket& socket,
bool waitForConnection)
: process(new IOSwitchboardServerProcess(
+ tty,
stdinToFd,
stdoutFromFd,
stdoutToFd,
@@ -601,6 +719,7 @@ Future<Nothing> IOSwitchboardServer::run()
IOSwitchboardServerProcess::IOSwitchboardServerProcess(
+ bool _tty,
int _stdinToFd,
int _stdoutFromFd,
int _stdoutToFd,
@@ -608,7 +727,8 @@ IOSwitchboardServerProcess::IOSwitchboardServerProcess(
int _stderrToFd,
const unix::Socket& _socket,
bool _waitForConnection)
- : stdinToFd(_stdinToFd),
+ : tty(_tty),
+ stdinToFd(_stdinToFd),
stdoutFromFd(_stdoutFromFd),
stdoutToFd(_stdoutToFd),
stderrFromFd(_stderrFromFd),
@@ -638,14 +758,24 @@ Future<Nothing> IOSwitchboardServerProcess::run()
lambda::_1,
agent::ProcessIO::Data::STDOUT)});
- Future<Nothing> stderrRedirect = process::io::redirect(
- stderrFromFd,
- stderrToFd,
- 4096,
- {defer(self(),
- &Self::outputHook,
- lambda::_1,
- agent::ProcessIO::Data::STDERR)});
+ // NOTE: We don't need to redirect stderr if TTY is enabled. If
+ // TTY is enabled for the container, stdout and stderr for the
+ // container will be redirected to the slave end of the pseudo
+ // terminal device. Both stdout and stderr of the container will
+ // both coming out from the master end of the pseudo terminal.
+ Future<Nothing> stderrRedirect;
+ if (tty) {
+ stderrRedirect = Nothing();
+ } else {
+ stderrRedirect = process::io::redirect(
+ stderrFromFd,
+ stderrToFd,
+ 4096,
+ {defer(self(),
+ &Self::outputHook,
+ lambda::_1,
+ agent::ProcessIO::Data::STDERR)});
+ }
// Set the future once our IO redirects finish. On failure,
// fail the future.
http://git-wip-us.apache.org/repos/asf/mesos/blob/fd142a0d/src/slave/containerizer/mesos/io/switchboard.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/io/switchboard.hpp b/src/slave/containerizer/mesos/io/switchboard.hpp
index 23c66bb..839665a 100644
--- a/src/slave/containerizer/mesos/io/switchboard.hpp
+++ b/src/slave/containerizer/mesos/io/switchboard.hpp
@@ -113,9 +113,17 @@ class IOSwitchboardServerProcess;
class IOSwitchboardServer
{
public:
- static constexpr char NAME[] = "mesos-io-switchboard";
+ static const char NAME[];
+
+ // Constant FD numbers used by I/O switchboard server.
+ static const int STDIN_TO_FD;
+ static const int STDOUT_FROM_FD;
+ static const int STDERR_FROM_FD;
+ static const int STDOUT_TO_FD;
+ static const int STDERR_TO_FD;
static Try<process::Owned<IOSwitchboardServer>> create(
+ bool tty,
int stdinToFd,
int stdoutFromFd,
int stdoutToFd,
@@ -130,6 +138,7 @@ public:
private:
IOSwitchboardServer(
+ bool tty,
int stdinToFd,
int stdoutFromFd,
int stdoutToFd,
@@ -164,27 +173,36 @@ struct IOSwitchboardServerFlags : public virtual flags::FlagsBase
"well as launch arbitrary subcommands inside a container and attach to\n"
"its stdin/stdout/stderr.\n");
+ add(&IOSwitchboardServerFlags::tty,
+ "tty",
+ "If a pseudo terminal has been allocated for the container.");
+
add(&IOSwitchboardServerFlags::stdin_to_fd,
"stdin_to_fd",
- "The file descriptor where incoming stdin data should be written.");
+ "The file descriptor where incoming stdin data should be written.",
+ IOSwitchboardServer::STDIN_TO_FD);
add(&IOSwitchboardServerFlags::stdout_from_fd,
"stdout_from_fd",
- "The file descriptor that should be read to consume stdout data.");
+ "The file descriptor that should be read to consume stdout data.",
+ IOSwitchboardServer::STDOUT_FROM_FD);
add(&IOSwitchboardServerFlags::stdout_to_fd,
"stdout_to_fd",
"A file descriptor where data read from\n"
- "'stdout_from_fd' should be redirected to.");
+ "'stdout_from_fd' should be redirected to.",
+ IOSwitchboardServer::STDOUT_TO_FD);
add(&IOSwitchboardServerFlags::stderr_from_fd,
"stderr_from_fd",
- "The file descriptor that should be read to consume stderr data.");
+ "The file descriptor that should be read to consume stderr data.",
+ IOSwitchboardServer::STDERR_FROM_FD);
add(&IOSwitchboardServerFlags::stderr_to_fd,
"stderr_to_fd",
"A file descriptor where data read from\n"
- "'stderr_from_fd' should be redirected to.");
+ "'stderr_from_fd' should be redirected to.",
+ IOSwitchboardServer::STDERR_TO_FD);
add(&IOSwitchboardServerFlags::wait_for_connection,
"wait_for_connection",
@@ -197,6 +215,7 @@ struct IOSwitchboardServerFlags : public virtual flags::FlagsBase
"io switchboard should attach itself to.");
}
+ bool tty;
int stdin_to_fd;
int stdout_from_fd;
int stdout_to_fd;
http://git-wip-us.apache.org/repos/asf/mesos/blob/fd142a0d/src/slave/containerizer/mesos/io/switchboard_main.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/io/switchboard_main.cpp b/src/slave/containerizer/mesos/io/switchboard_main.cpp
index 5800217..aff6c21 100644
--- a/src/slave/containerizer/mesos/io/switchboard_main.cpp
+++ b/src/slave/containerizer/mesos/io/switchboard_main.cpp
@@ -38,6 +38,7 @@ int main(int argc, char** argv)
}
Try<Owned<IOSwitchboardServer>> server = IOSwitchboardServer::create(
+ flags.tty,
flags.stdin_to_fd,
flags.stdout_from_fd,
flags.stdout_to_fd,
http://git-wip-us.apache.org/repos/asf/mesos/blob/fd142a0d/src/slave/containerizer/mesos/launch.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/launch.cpp b/src/slave/containerizer/mesos/launch.cpp
index d78ca4d..f90fce2 100644
--- a/src/slave/containerizer/mesos/launch.cpp
+++ b/src/slave/containerizer/mesos/launch.cpp
@@ -356,6 +356,16 @@ int MesosContainerizerLaunch::execute()
}
}
+#ifndef __WINDOWS__
+ if (launchInfo.has_tty_slave_path()) {
+ Try<Nothing> setctty = os::setctty(STDIN_FILENO);
+ if (setctty.isError()) {
+ cerr << "Failed to set control tty: " << setctty.error() << endl;
+ exitWithStatus(EXIT_FAILURE);
+ }
+ }
+#endif // __WINDOWS__
+
#ifdef __linux__
if (flags.namespace_mnt_target.isSome()) {
string path = path::join(
http://git-wip-us.apache.org/repos/asf/mesos/blob/fd142a0d/src/tests/containerizer/io_switchboard_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/io_switchboard_tests.cpp b/src/tests/containerizer/io_switchboard_tests.cpp
index d82f22b..d2db61e 100644
--- a/src/tests/containerizer/io_switchboard_tests.cpp
+++ b/src/tests/containerizer/io_switchboard_tests.cpp
@@ -96,6 +96,7 @@ TEST_F(IOSwitchboardTest, ServerRedirectLog)
"mesos-io-switchboard-" + UUID::random().toString());
Try<Owned<IOSwitchboardServer>> server = IOSwitchboardServer::create(
+ false,
nullFd.get(),
stdoutPipe[0],
stdoutFd.get(),
@@ -203,6 +204,7 @@ TEST_F(IOSwitchboardTest, ServerAttachOutput)
"mesos-io-switchboard-" + UUID::random().toString());
Try<Owned<IOSwitchboardServer>> server = IOSwitchboardServer::create(
+ false,
nullFd.get(),
stdoutFd.get(),
nullFd.get(),
[7/9] mesos git commit: Added os::dup2 to stout.
Posted by ji...@apache.org.
Added os::dup2 to stout.
Review: https://reviews.apache.org/r/54349
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f0350822
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f0350822
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f0350822
Branch: refs/heads/master
Commit: f0350822dbfa8ee599a4748b79887b46bab11eac
Parents: 9248867
Author: Jie Yu <yu...@gmail.com>
Authored: Sat Dec 3 11:22:24 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
3rdparty/stout/include/stout/posix/os.hpp | 13 +++++++++++++
1 file changed, 13 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/f0350822/3rdparty/stout/include/stout/posix/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/posix/os.hpp b/3rdparty/stout/include/stout/posix/os.hpp
index a8f7108..09196be 100644
--- a/3rdparty/stout/include/stout/posix/os.hpp
+++ b/3rdparty/stout/include/stout/posix/os.hpp
@@ -475,6 +475,19 @@ inline Try<Nothing> pipe(int pipe_fd[2])
}
+inline Try<Nothing> dup2(int oldFd, int newFd)
+{
+ while (::dup2(oldFd, newFd) == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return ErrnoError();
+ }
+ }
+ return Nothing();
+}
+
+
inline Try<std::string> ptsname(int master)
{
// 'ptsname' is not thread safe. Therefore, we use mutex here to
[3/9] mesos git commit: Added os::ptsname to stout.
Posted by ji...@apache.org.
Added os::ptsname to stout.
Review: https://reviews.apache.org/r/54291
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5ee6f4f3
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5ee6f4f3
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5ee6f4f3
Branch: refs/heads/master
Commit: 5ee6f4f3ff2ad2e10cd2b3430f20c883b2f5b384
Parents: 4df544f
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Dec 1 17:13:09 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
3rdparty/stout/include/stout/posix/os.hpp | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/5ee6f4f3/3rdparty/stout/include/stout/posix/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/posix/os.hpp b/3rdparty/stout/include/stout/posix/os.hpp
index c37e64d..72e69a00 100644
--- a/3rdparty/stout/include/stout/posix/os.hpp
+++ b/3rdparty/stout/include/stout/posix/os.hpp
@@ -45,10 +45,13 @@
#include <list>
#include <map>
+#include <mutex>
#include <set>
#include <string>
#include <vector>
+#include <stout/synchronized.hpp>
+
#include <stout/os/close.hpp>
#include <stout/os/environment.hpp>
#include <stout/os/fcntl.hpp>
@@ -469,6 +472,23 @@ inline Try<Nothing> pipe(int pipe_fd[2])
return Nothing();
}
+
+inline Try<std::string> ptsname(int master)
+{
+ // 'ptsname' is not thread safe. Therefore, we use mutex here to
+ // make this method thread safe.
+ // TODO(jieyu): Consider using ptsname_r for linux.
+ static std::mutex* mutex = new std::mutex;
+
+ synchronized (mutex) {
+ const char* slavePath = ::ptsname(master);
+ if (slavePath == nullptr) {
+ return ErrnoError();
+ }
+ return slavePath;
+ }
+}
+
} // namespace os {
#endif // __STOUT_POSIX_OS_HPP__
[6/9] mesos git commit: Added a ErrnoFailure similar to ErrnoError.
Posted by ji...@apache.org.
Added a ErrnoFailure similar to ErrnoError.
Review: https://reviews.apache.org/r/54290
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4df544f7
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4df544f7
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4df544f7
Branch: refs/heads/master
Commit: 4df544f794b6df36017310b69ce72ed9a181bdaa
Parents: a43d57b
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Dec 1 17:12:57 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
3rdparty/libprocess/include/process/future.hpp | 30 +++++++++++++++++++++
1 file changed, 30 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/4df544f7/3rdparty/libprocess/include/process/future.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/future.hpp b/3rdparty/libprocess/include/process/future.hpp
index 175214a..26bf585 100644
--- a/3rdparty/libprocess/include/process/future.hpp
+++ b/3rdparty/libprocess/include/process/future.hpp
@@ -44,6 +44,8 @@
#include <stout/synchronized.hpp>
#include <stout/try.hpp>
+#include <stout/os/strerror.hpp>
+
namespace process {
// Forward declarations (instead of include to break circular dependency).
@@ -76,6 +78,7 @@ class WeakFuture;
// Forward declaration of Failure.
struct Failure;
+struct ErrnoFailure;
// Definition of a "shared" future. A future can hold any
@@ -97,6 +100,8 @@ public:
/*implicit*/ Future(const Failure& failure);
+ /*implicit*/ Future(const ErrnoFailure& failure);
+
/*implicit*/ Future(const Future<T>& that);
/*implicit*/ Future(Future<T>&& that);
@@ -536,6 +541,23 @@ struct Failure
};
+struct ErrnoFailure : public Failure
+{
+ ErrnoFailure() : ErrnoFailure(errno) {}
+
+ explicit ErrnoFailure(int _code)
+ : Failure(os::strerror(_code)), code(_code) {}
+
+ explicit ErrnoFailure(const std::string& message)
+ : ErrnoFailure(errno, message) {}
+
+ ErrnoFailure(int _code, const std::string& message)
+ : Failure(message + ": " + os::strerror(_code)), code(_code) {}
+
+ const int code;
+};
+
+
// Forward declaration to use as friend below.
namespace internal {
template <typename U>
@@ -928,6 +950,14 @@ Future<T>::Future(const Failure& failure)
template <typename T>
+Future<T>::Future(const ErrnoFailure& failure)
+ : data(new Data())
+{
+ fail(failure.message);
+}
+
+
+template <typename T>
Future<T>::Future(const Future<T>& that)
: data(that.data) {}
[9/9] mesos git commit: Added a DUP2 child hook to Subprocess.
Posted by ji...@apache.org.
Added a DUP2 child hook to Subprocess.
Review: https://reviews.apache.org/r/54350
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/d6bc482a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/d6bc482a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/d6bc482a
Branch: refs/heads/master
Commit: d6bc482ac40063a5b37f672b2591a07d3ebc3c4d
Parents: f035082
Author: Jie Yu <yu...@gmail.com>
Authored: Sun Dec 4 13:14:59 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
3rdparty/libprocess/include/process/subprocess_base.hpp | 7 +++++++
3rdparty/libprocess/src/subprocess.cpp | 10 ++++++++++
2 files changed, 17 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/d6bc482a/3rdparty/libprocess/include/process/subprocess_base.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/subprocess_base.hpp b/3rdparty/libprocess/include/process/subprocess_base.hpp
index 1d02454..0d9c74a 100644
--- a/3rdparty/libprocess/include/process/subprocess_base.hpp
+++ b/3rdparty/libprocess/include/process/subprocess_base.hpp
@@ -199,6 +199,13 @@ public:
*/
static ChildHook SETSID();
+#ifndef __WINDOWS__
+ /**
+ * `ChildHook` for duplicating a file descriptor.
+ */
+ static ChildHook DUP2(int oldFd, int newFd);
+#endif // __WINDOWS__
+
/**
* `ChildHook` for starting a Supervisor process monitoring
* and killing the child process if the parent process terminates.
http://git-wip-us.apache.org/repos/asf/mesos/blob/d6bc482a/3rdparty/libprocess/src/subprocess.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/subprocess.cpp b/3rdparty/libprocess/src/subprocess.cpp
index 284e22e..b3efb9c 100644
--- a/3rdparty/libprocess/src/subprocess.cpp
+++ b/3rdparty/libprocess/src/subprocess.cpp
@@ -91,6 +91,16 @@ Subprocess::ChildHook Subprocess::ChildHook::SETSID()
}
+#ifndef __WINDOWS__
+Subprocess::ChildHook Subprocess::ChildHook::DUP2(int oldFd, int newFd)
+{
+ return Subprocess::ChildHook([oldFd, newFd]() -> Try<Nothing> {
+ return os::dup2(oldFd, newFd);
+ });
+}
+#endif // __WINDOWS__
+
+
#ifdef __linux__
inline void signalHandler(int signal)
{
[5/9] mesos git commit: Added os::setctty to stout.
Posted by ji...@apache.org.
Added os::setctty to stout.
Review: https://reviews.apache.org/r/54292
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/9248867b
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/9248867b
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/9248867b
Branch: refs/heads/master
Commit: 9248867b8401bd9c034f5759198f113d4621ee88
Parents: 5ee6f4f
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Dec 1 18:15:04 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Sun Dec 4 21:41:51 2016 -0800
----------------------------------------------------------------------
3rdparty/stout/include/stout/posix/os.hpp | 11 +++++++++++
1 file changed, 11 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/9248867b/3rdparty/stout/include/stout/posix/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/posix/os.hpp b/3rdparty/stout/include/stout/posix/os.hpp
index 72e69a00..a8f7108 100644
--- a/3rdparty/stout/include/stout/posix/os.hpp
+++ b/3rdparty/stout/include/stout/posix/os.hpp
@@ -35,6 +35,8 @@
#include <unistd.h>
#include <utime.h>
+#include <sys/ioctl.h>
+
#ifdef __linux__
#include <linux/version.h>
#include <sys/sysinfo.h>
@@ -489,6 +491,15 @@ inline Try<std::string> ptsname(int master)
}
}
+
+inline Try<Nothing> setctty(int fd)
+{
+ if (ioctl(fd, TIOCSCTTY, nullptr) == -1) {
+ return ErrnoError();
+ }
+ return Nothing();
+}
+
} // namespace os {
#endif // __STOUT_POSIX_OS_HPP__