aboutsummaryrefslogtreecommitdiffstats
path: root/executor/executor_linux.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-03-22 13:24:02 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-03-25 12:46:05 +0200
commit2675f920652cc9218b4b3dc513c76b0546a5a5ae (patch)
tree8ae9084acf230839d4b7f2eeef2ba4549ee8d35d /executor/executor_linux.cc
parent2e9d905410db5615d2e7d3418979d79249ac74f6 (diff)
sys/linux: add cgroup descriptions
Diffstat (limited to 'executor/executor_linux.cc')
-rw-r--r--executor/executor_linux.cc97
1 files changed, 0 insertions, 97 deletions
diff --git a/executor/executor_linux.cc b/executor/executor_linux.cc
index facd0a5f0..dcb2e78cb 100644
--- a/executor/executor_linux.cc
+++ b/executor/executor_linux.cc
@@ -119,103 +119,6 @@ int main(int argc, char** argv)
return 1;
}
-void loop()
-{
- // Tell parent that we are ready to serve.
- reply_handshake();
- checkpoint_net_namespace();
-
- for (int iter = 0;; iter++) {
- // Create a new private work dir for this test (removed at the end of the loop).
- char cwdbuf[256];
- sprintf(cwdbuf, "./%d", iter);
- if (mkdir(cwdbuf, 0777))
- fail("failed to mkdir");
-
- // TODO: consider moving the read into the child.
- // Potentially it can speed up things a bit -- when the read finishes
- // we already have a forked worker process.
- receive_execute(false);
- int pid = fork();
- if (pid < 0)
- fail("clone failed");
- if (pid == 0) {
- prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
- setpgrp();
- if (chdir(cwdbuf))
- fail("failed to chdir");
- close(kInPipeFd);
- close(kOutPipeFd);
- if (flag_enable_tun) {
- // Read all remaining packets from tun to better
- // isolate consequently executing programs.
- flush_tun();
- }
- output_pos = output_data;
- execute_one();
- debug("worker exiting\n");
- doexit(0);
- }
- debug("spawned worker pid %d\n", pid);
-
- // We used to use sigtimedwait(SIGCHLD) to wait for the subprocess.
- // But SIGCHLD is also delivered when a process stops/continues,
- // so it would require a loop with status analysis and timeout recalculation.
- // SIGCHLD should also unblock the usleep below, so the spin loop
- // should be as efficient as sigtimedwait.
- int status = 0;
- uint64 start = current_time_ms();
- uint64 last_executed = start;
- uint32 executed_calls = __atomic_load_n(output_data, __ATOMIC_RELAXED);
- for (;;) {
- int res = waitpid(-1, &status, __WALL | WNOHANG);
- int errno0 = errno;
- if (res == pid) {
- debug("waitpid(%d)=%d (%d)\n", pid, res, errno0);
- break;
- }
- usleep(1000);
- // Even though the test process executes exit at the end
- // and execution time of each syscall is bounded by 20ms,
- // this backup watchdog is necessary and its performance is important.
- // The problem is that exit in the test processes can fail (sic).
- // One observed scenario is that the test processes prohibits
- // exit_group syscall using seccomp. Another observed scenario
- // is that the test processes setups a userfaultfd for itself,
- // then the main thread hangs when it wants to page in a page.
- // Below we check if the test process still executes syscalls
- // and kill it after 200ms of inactivity.
- uint64 now = current_time_ms();
- uint32 now_executed = __atomic_load_n(output_data, __ATOMIC_RELAXED);
- if (executed_calls != now_executed) {
- executed_calls = now_executed;
- last_executed = now;
- }
- if ((now - start < 3 * 1000) && (now - last_executed < 500))
- continue;
- debug("waitpid(%d)=%d (%d)\n", pid, res, errno0);
- debug("killing\n");
- kill(-pid, SIGKILL);
- kill(pid, SIGKILL);
- for (;;) {
- int res = waitpid(-1, &status, __WALL);
- debug("waitpid(%d)=%d (%d)\n", pid, res, errno);
- if (res == pid)
- break;
- }
- break;
- }
- status = WEXITSTATUS(status);
- if (status == kFailStatus)
- fail("child failed");
- if (status == kErrorStatus)
- error("child errored");
- reply_execute(0);
- remove_dir(cwdbuf);
- reset_net_namespace();
- }
-}
-
long execute_syscall(call_t* c, long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8)
{
if (c->call)