| 642 | |
| 643 | |
| 644 | int MesosContainerizerLaunch::execute() |
| 645 | { |
| 646 | if (flags.help) { |
| 647 | cerr << flags.usage(); |
| 648 | return EXIT_SUCCESS; |
| 649 | } |
| 650 | |
| 651 | // The existence of the `runtime_directory` flag implies that we |
| 652 | // want to checkpoint the container's status upon exit. |
| 653 | if (flags.runtime_directory.isSome()) { |
| 654 | containerStatusPath = path::join( |
| 655 | flags.runtime_directory.get(), |
| 656 | containerizer::paths::STATUS_FILE); |
| 657 | |
| 658 | Try<int_fd> open = os::open( |
| 659 | containerStatusPath.get(), |
| 660 | O_WRONLY | O_CREAT | O_CLOEXEC, |
| 661 | S_IRUSR | S_IWUSR); |
| 662 | |
| 663 | if (open.isError()) { |
| 664 | cerr << "Failed to open file for writing the container status" |
| 665 | << " '" << containerStatusPath.get() << "':" |
| 666 | << " " << open.error() << endl; |
| 667 | exitWithStatus(EXIT_FAILURE); |
| 668 | } |
| 669 | |
| 670 | containerStatusFd = open.get(); |
| 671 | } |
| 672 | |
| 673 | #ifndef __WINDOWS__ |
| 674 | // We need a signal fence here to ensure that `containerStatusFd` is |
| 675 | // actually written to memory and not just to a temporary register. |
| 676 | // Without this, it's possible that the signal handler we are about |
| 677 | // to install would never see the correct value since there's no |
| 678 | // guarantee that it is written to memory until this function |
| 679 | // completes (which won't happen for a really long time because we |
| 680 | // do a blocking `waitpid()` below). |
| 681 | std::atomic_signal_fence(std::memory_order_relaxed); |
| 682 | |
| 683 | // Install signal handlers for all incoming signals. |
| 684 | Try<Nothing> signals = installSignalHandlers(); |
| 685 | if (signals.isError()) { |
| 686 | cerr << "Failed to install signal handlers: " << signals.error() << endl; |
| 687 | exitWithStatus(EXIT_FAILURE); |
| 688 | } |
| 689 | #else |
| 690 | // We need a handle to the job object which this container is associated with. |
| 691 | // Without this handle, the job object would be destroyed by the OS when the |
| 692 | // agent exits (or crashes), making recovery impossible. By holding a handle, |
| 693 | // we tie the lifetime of the job object to the container itself. In this way, |
| 694 | // a recovering agent can reattach to the container by opening a new handle to |
| 695 | // the job object. |
| 696 | const pid_t pid = ::GetCurrentProcessId(); |
| 697 | const Try<std::wstring> name = os::name_job(pid); |
| 698 | if (name.isError()) { |
| 699 | cerr << "Failed to create job object name from pid: " << name.error() |
| 700 | << endl; |
| 701 | exitWithStatus(EXIT_FAILURE); |
nothing calls this directly
no test coverage detected