blob: 4e0a26304e0e40f004d13835ab248e549b0f62de [file] [log] [blame]
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "germ/container.h"
#include <sys/types.h>
#include <base/bind.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/time/time.h>
namespace germ {
const pid_t kInvalidPid = -1;
Container::Container(const soma::ContainerSpec& spec)
: spec_(spec),
init_pid_(kInvalidPid),
state_(Container::State::STOPPED),
desired_state_(Container::State::RUNNING),
generation_(0) {}
Container::~Container() {}
bool Container::Launch(GermZygote* zygote) {
DCHECK_EQ(State::STOPPED, state_);
++generation_;
if (!zygote->StartContainer(spec_, &init_pid_)) {
return false;
}
state_ = State::RUNNING;
return true;
}
bool Container::Terminate(GermZygote* zygote, base::TimeDelta kill_delay) {
DCHECK_EQ(State::RUNNING, state_);
if (!Kill(zygote, SIGTERM)) {
return false;
}
// Note: zygote must outlive the message loop.
CHECK(base::MessageLoop::current()->task_runner()->PostDelayedTask(
FROM_HERE, base::Bind(&Container::SendSIGKILL, this, zygote, generation_),
kill_delay));
state_ = State::DYING;
return true;
}
void Container::SendSIGKILL(GermZygote* zygote, uint64 generation) {
if (generation != generation_ || state_ != State::DYING) {
return;
}
Kill(zygote, SIGKILL);
}
bool Container::Kill(GermZygote* zygote, int signal) {
CHECK_NE(kInvalidPid, init_pid_);
DCHECK(state_ == State::RUNNING || state_ == State::DYING);
return zygote->Kill(init_pid_, signal);
}
void Container::OnReap() {
DCHECK(state_ == State::RUNNING || state_ == State::DYING);
init_pid_ = kInvalidPid;
state_ = State::STOPPED;
}
std::ostream& operator<<(std::ostream& os, Container::State state) {
switch (state) {
case Container::State::STOPPED:
return os << "STOPPED";
case Container::State::RUNNING:
return os << "RUNNING";
case Container::State::DYING:
return os << "DYING";
}
NOTREACHED();
return os << "[invalid state]";
}
} // namespace germ