Skip to content
This repository has been archived by the owner on Feb 18, 2021. It is now read-only.

Commit

Permalink
add freeze functions
Browse files Browse the repository at this point in the history
  • Loading branch information
szdytom committed Sep 26, 2020
1 parent cee7f90 commit 80800f4
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 28 deletions.
2 changes: 2 additions & 0 deletions include/ssandbox/cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class cgroup_unit {
std::string get(std::string file);
void remove();

std::string get_subsys_type();

private:
std::string _subsys_type;
std::string _unit_name;
Expand Down
2 changes: 1 addition & 1 deletion include/ssandbox/limits/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class limit_info_t {
limit_info_t();
~limit_info_t();

void set_uid(std::string uid);
void set_up(std::string uid, ssandbox::limits_manager* mgr);
void apply(pid_t container_pid);
void wait();

Expand Down
12 changes: 9 additions & 3 deletions include/ssandbox/sandbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,23 @@ struct _sandbox_prepar_info {

class container {
public:
sandbox_t* cfg;
void start();
ssandbox::run_result_t wait();
void stop();

void freeze();
void thaw();

private:
pid_t _container_pid;
_sandbox_prepar_info* prepar_config;
std::unique_ptr<char[]> container_stack;
_sandbox_prepar_info* _prepar_config;
limits_manager* _limiter;
std::unique_ptr<char[]> _container_stack;

void _clear();

public:
sandbox_t* cfg;
};

} // namespace ssandbox
Expand Down
4 changes: 4 additions & 0 deletions src/cgroup/unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ std::string ssandbox::cgroup_unit::get(std::string file) {

void ssandbox::cgroup_unit::remove() {
std::filesystem::remove(this->_unit_path);
}

std::string ssandbox::cgroup_unit::get_subsys_type() {
return this->_subsys_type;
}
19 changes: 16 additions & 3 deletions src/limits/resources/freeze.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,24 @@
#include "ssandbox/limits/resource.h"

void ssandbox::limits_manager::freeze(bool limit) {
auto cs = ssandbox::cgroup_subsystem("freezer");
auto c = cs.create(fmt::format("ssandbox_{}", this->_uid));
ssandbox::cgroup_unit* c;

bool flag = false;
for (auto x : this->_used_cgroup) {
if (x->get_subsys_type() == "freezer") {
c = x;
flag = true;
}
}

if (!flag) {
auto cs = ssandbox::cgroup_subsystem("freezer");
c = cs.create(fmt::format("ssandbox_{}", this->_uid));
}

c->write("tasks", std::to_string(this->_pid));
c->write("freezer.state", limit ? "FROZEN" : "THAWED");

this->_used_cgroup.push_back(c);
if (!flag)
this->_used_cgroup.push_back(c);
}
5 changes: 2 additions & 3 deletions src/limits/resources/info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
#include "ssandbox/utils/exceptions.h"

ssandbox::limit_info_t::limit_info_t() {
this->_limiter = new limits_manager;

this->_cpu = -1;
this->_memory = -1;
this->_time = -1;
Expand All @@ -18,8 +16,9 @@ ssandbox::limit_info_t::~limit_info_t() {
delete this->_limiter;
}

void ssandbox::limit_info_t::set_uid(std::string uid) {
void ssandbox::limit_info_t::set_up(std::string uid, ssandbox::limits_manager* mgr) {
this->_uid = uid;
this->_limiter = mgr;
this->_limiter->set_uid(this->_uid);
}

Expand Down
47 changes: 29 additions & 18 deletions src/sandbox.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,28 @@ int entry_handle(void* cfg_ptr) {
void ssandbox::container::start() {
/* create stack space for child to use */
/* new will throw out a alloc_error if fail, so we don't need to handle nullptr */
this->container_stack.reset(new char[cfg->stack_size]);
char* container_stack_ptr = container_stack.get();
this->_container_stack.reset(new char[cfg->stack_size]);
char* container_stack_ptr = _container_stack.get();

/* Set UID at different classes */
cfg->fs->set_uid(cfg->uid);
cfg->limit_config.set_uid(cfg->uid);
/* Set UID in different classes */
this->cfg->fs->set_uid(this->cfg->uid);

this->prepar_config = new ssandbox::_sandbox_prepar_info;
this->prepar_config->cfg = cfg;
this->prepar_config->semaphore = new ssandbox::semaphore;
/* prepar resource limiter */
this->_limiter = new ssandbox::limits_manager;
this->cfg->limit_config.set_up(this->cfg->uid, this->_limiter);

this->_prepar_config = new ssandbox::_sandbox_prepar_info;
this->_prepar_config->cfg = this->cfg;
this->_prepar_config->semaphore = new ssandbox::semaphore;

int clone_flags = SIGCHLD | CLONE_VM | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS;
if (!cfg->enable_network)
if (!this->cfg->enable_network)
clone_flags |= CLONE_NEWNET;

this->_container_pid = clone((ssandbox::container_func_t)entry_handle,
container_stack_ptr + cfg->stack_size, /* reverse memory */
clone_flags,
(void*)prepar_config);
(void*)_prepar_config);

if (this->_container_pid == -1)
/* clone process failed */
Expand All @@ -76,10 +79,10 @@ void ssandbox::container::start() {
user_ns_mgr->set_gid_map(this->_container_pid, 0, getgid(), 1);

/* set limits */
cfg->limit_config.apply(this->_container_pid);
this->cfg->limit_config.apply(this->_container_pid);

/* send semaphore */
prepar_config->semaphore->post(0);
_prepar_config->semaphore->post(0);
}

ssandbox::run_result_t ssandbox::container::wait() {
Expand All @@ -91,7 +94,7 @@ ssandbox::run_result_t ssandbox::container::wait() {

/* get resource usages */
ssandbox::run_result_t res;
res.time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - this->prepar_config->start_time);
res.time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - this->_prepar_config->start_time);
res.exit_status = sstatus;

/* clear others up */
Expand All @@ -107,14 +110,22 @@ void ssandbox::container::stop() {
}

void ssandbox::container::_clear() {
cfg->limit_config.wait();
this->cfg->limit_config.wait();

/* clear mounted fs */
cfg->fs->umount_all();
this->cfg->fs->umount_all();

delete this->prepar_config->semaphore;
delete this->prepar_config;
delete this->_prepar_config->semaphore;
delete this->_prepar_config;

/* free memory inside unique_ptr */
this->container_stack.reset(nullptr);
this->_container_stack.reset(nullptr);
}

void ssandbox::container::freeze() {
this->_limiter->freeze();
}

void ssandbox::container::thaw() {
this->_limiter->freeze(false);
}

0 comments on commit 80800f4

Please sign in to comment.