Skip to content

Commit

Permalink
Once more under the quotas: Quotas now must be enabled by new config …
Browse files Browse the repository at this point in the history
…parameter, to avoid errors when underlying FS does not support quotas.
  • Loading branch information
Martin Krulis committed Jan 9, 2021
1 parent 8d6f11b commit e23700a
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 10 deletions.
6 changes: 4 additions & 2 deletions examples/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ limits:
memory: 1048576 # KiB
extra-memory: 64 # KiB, will be added to memory limit
parallel: 0 # if parallel == 1, time and memory limits are merged
disk-size: 1048576 # KiB
disk-files: 100
# Enable disk quotas only if you have enabled them in your FS
disk-quotas: false
disk-size: 1048576 # KiB, ignored if disk-quotas == false
disk-files: 100 # ignored if disk-quotas == false
environ-variable: # environmental variables used inside sandbox
HOME: /box # do not change unless you know what are you doing
PATH: /usr/bin:/bin
Expand Down
5 changes: 5 additions & 0 deletions src/config/sandbox_limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ struct sandbox_limits {
* @warning This option is deprecated! Use @ref disk_size and @ref disk_files instead.
*/
std::size_t files_size = 0;
/**
* Whether disk quotas (disk_size and disk_files) are enabled.
* @warning Keep this false if underlying filesystem does not support quotas.
*/
bool disk_quotas = false;
/**
* Set disk quota to given number of kilobytes.
* @warning Underlying filesystem must support quotas.
Expand Down
3 changes: 3 additions & 0 deletions src/config/worker_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ worker_config::worker_config(const YAML::Node &config)
if (limits["parallel"] && limits["parallel"].IsScalar()) {
limits_.processes = limits["parallel"].as<std::size_t>();
} // no throw... can be omitted
if (limits["disk-quotas"] && limits["disk-quotas"].IsScalar()) {
limits_.disk_quotas = limits["disk-quotas"].as<bool>();
} // no throw... can be omitted
if (limits["disk-size"] && limits["disk-size"].IsScalar()) {
limits_.disk_size = limits["disk-size"].as<std::size_t>();
} // no throw... can be omitted
Expand Down
5 changes: 5 additions & 0 deletions src/helpers/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ std::shared_ptr<job_metadata> helpers::build_job_metadata(const YAML::Node &conf
} else {
sl->processes = SIZE_MAX; // set undefined value (max std::size_t)
}
if (lim["disk-quotas"] && lim["disk-quotas"].IsScalar()) {
sl->disk_quotas = lim["disk-quotas"].as<bool>();
} else {
sl->disk_quotas = false;
}
if (lim["disk-size"] && lim["disk-size"].IsScalar()) {
sl->disk_size = lim["disk-size"].as<std::size_t>();
} else {
Expand Down
21 changes: 13 additions & 8 deletions src/sandbox/isolate_sandbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,25 @@ void isolate_sandbox::isolate_init_child(int fd_0, int fd_1)
std::string box_id_arg("--box-id=" + std::to_string(id_));

// Exec isolate init command
const char *args[] {
std::vector<const char *> args {
isolate_binary_.c_str(),
"--cg",
box_id_arg.c_str(),
"--init",
nullptr,
};

std::string quota_arg;
if (limits_.disk_quotas) {
// Calculate number of required blocks - total number of bytes divided by block size
auto disk_size_blocks = (limits_.disk_size * 1024) / BLOCK_SIZE; // BLOCK_SIZE is from sys/mount.h
quota_arg = "--quota=" + std::to_string(disk_size_blocks) + "," + std::to_string(limits_.disk_files);
args.push_back(quota_arg.c_str());
}

args.push_back("--init");
args.push_back(nullptr);

// const_cast is ugly, but this is working with C code - execv does not modify its arguments
execvp(isolate_binary_.c_str(), const_cast<char **>(args));
execvp(isolate_binary_.c_str(), const_cast<char **>(&args[0]));

// never reached unless exec explodes in our face
log_and_throw(logger_, "Exec returned to child: ", strerror(errno));
Expand Down Expand Up @@ -323,10 +332,6 @@ char **isolate_sandbox::isolate_run_args(const std::string &binary, const std::v
vargs.push_back("--extra-time=" + std::to_string(limits_.extra_time));
if (limits_.stack_size != 0) { vargs.push_back("--stack=" + std::to_string(limits_.stack_size)); }
if (limits_.files_size != 0) { vargs.push_back("--fsize=" + std::to_string(limits_.files_size)); }
// Calculate number of required blocks - total number of bytes divided by block size (defined in sys/mount.h)
// Actually, the quotas are probably silently ignored in --run command, but it is not properly documented in isolate.
auto disk_size_blocks = (limits_.disk_size * 1024) / BLOCK_SIZE; // BLOCK_SIZE is from sys/mount.h
vargs.push_back("--quota=" + std::to_string(disk_size_blocks) + "," + std::to_string(limits_.disk_files));
if (!sandbox_config_->std_input.empty()) { vargs.push_back("--stdin=" + sandbox_config_->std_input); }
if (!sandbox_config_->std_output.empty()) { vargs.push_back("--stdout=" + sandbox_config_->std_output); }
if (!sandbox_config_->std_error.empty()) { vargs.push_back("--stderr=" + sandbox_config_->std_error); }
Expand Down

0 comments on commit e23700a

Please sign in to comment.