143 lines
3.2 KiB
C
143 lines
3.2 KiB
C
#include "container.h"
|
|
#include "cgroup.h"
|
|
|
|
#define MEMORY "1073741824"
|
|
#define SHARES "256"
|
|
#define PIDS "64"
|
|
#define WEIGHT "10"
|
|
|
|
struct cgrp_control {
|
|
char control[256];
|
|
struct cgrp_setting {
|
|
char name[256];
|
|
char value[256];
|
|
} **settings;
|
|
};
|
|
|
|
static struct cgrp_setting add_to_tasks = {
|
|
.name = "tasks",
|
|
.value = "0"
|
|
};
|
|
|
|
static struct cgrp_control *cgrps[] = {
|
|
& (struct cgrp_control) {
|
|
.control = "memory",
|
|
.settings = (struct cgrp_setting *[]) {
|
|
& (struct cgrp_setting) {
|
|
.name = "memory.limit_in_bytes",
|
|
.value = MEMORY
|
|
},
|
|
& (struct cgrp_setting) {
|
|
.name = "memory.kmem.limit_in_bytes",
|
|
.value = MEMORY
|
|
},
|
|
&add_to_tasks,
|
|
NULL
|
|
}
|
|
},
|
|
& (struct cgrp_control) {
|
|
.control = "cpu",
|
|
.settings = (struct cgrp_setting *[]) {
|
|
& (struct cgrp_setting) {
|
|
.name = "cpu.shares",
|
|
.value = SHARES
|
|
},
|
|
&add_to_tasks,
|
|
NULL
|
|
}
|
|
},
|
|
& (struct cgrp_control) {
|
|
.control = "pids",
|
|
.settings = (struct cgrp_setting *[]) {
|
|
& (struct cgrp_setting) {
|
|
.name = "pids.max",
|
|
.value = PIDS
|
|
},
|
|
&add_to_tasks,
|
|
NULL
|
|
}
|
|
},
|
|
NULL
|
|
};
|
|
|
|
int resources(struct child_config *config)
|
|
{
|
|
fprintf(stderr, "=> setting cgroups...");
|
|
for (struct cgrp_control **cgrp = cgrps; *cgrp; cgrp++) {
|
|
char dir[PATH_MAX] = {0};
|
|
fprintf(stderr, "%s...", (*cgrp)->control);
|
|
if (snprintf(dir, sizeof(dir), "/sys/fs/cgroup/%s/%s",
|
|
(*cgrp)->control, config->hostname) == -1) {
|
|
return -1;
|
|
}
|
|
if (mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR)) {
|
|
fprintf(stderr, "mkdir %s failed: %m\n", dir);
|
|
return -1;
|
|
}
|
|
for (struct cgrp_setting **setting = (*cgrp)->settings; *setting; setting++) {
|
|
char path[PATH_MAX] = {0};
|
|
int fd = 0;
|
|
if (snprintf(path, sizeof(path), "%s/%s", dir,
|
|
(*setting)->name) == -1) {
|
|
fprintf(stderr, "snprintf failed: %m\n");
|
|
return -1;
|
|
}
|
|
if ((fd = open(path, O_WRONLY)) == -1) {
|
|
fprintf(stderr, "opening %s failed: %m\n", path);
|
|
return -1;
|
|
}
|
|
if (write(fd, (*setting)->value, strlen((*setting)->value)) == -1) {
|
|
fprintf(stderr, "writing to %s failed: %m\n", path);
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
close(fd);
|
|
}
|
|
}
|
|
fprintf(stderr, "done.\n");
|
|
fprintf(stderr, "=> setting rlimit...");
|
|
if (setrlimit(RLIMIT_NOFILE,
|
|
& (struct rlimit) {
|
|
.rlim_max = FD_COUNT,
|
|
.rlim_cur = FD_COUNT,
|
|
})) {
|
|
fprintf(stderr, "failed: %m\n");
|
|
return 1;
|
|
}
|
|
fprintf(stderr, "done.\n");
|
|
return 0;
|
|
}
|
|
|
|
int free_resources(struct child_config *config)
|
|
{
|
|
fprintf(stderr, "=> cleaning cgroups...");
|
|
for (struct cgrp_control **cgrp = cgrps; *cgrp; cgrp++) {
|
|
char dir[PATH_MAX] = {0};
|
|
char task[PATH_MAX] = {0};
|
|
int task_fd = 0;
|
|
if (snprintf(dir, sizeof(dir), "/sys/fs/cgroup/%s/%s",
|
|
(*cgrp)->control, config->hostname) == -1
|
|
|| snprintf(task, sizeof(task), "/sys/fs/cgroup/%s/tasks",
|
|
(*cgrp)->control) == -1) {
|
|
fprintf(stderr, "snprintf failed: %m\n");
|
|
return -1;
|
|
}
|
|
if ((task_fd = open(task, O_WRONLY)) == -1) {
|
|
fprintf(stderr, "opening %s failed: %m\n", task);
|
|
return -1;
|
|
}
|
|
if (write(task_fd, "0", 2) == -1) {
|
|
fprintf(stderr, "writing to %s failed: %m\n", task);
|
|
close(task_fd);
|
|
return -1;
|
|
}
|
|
close(task_fd);
|
|
if (rmdir(dir)) {
|
|
fprintf(stderr, "rmdir %s failed: %m", dir);
|
|
return -1;
|
|
}
|
|
}
|
|
fprintf(stderr, "done.\n");
|
|
return 0;
|
|
}
|