cgroups: support for PIDs

This commit is contained in:
Robert Swiecki 2017-04-20 17:48:20 +02:00
parent 730991baff
commit cc5d4b65c9
3 changed files with 92 additions and 3 deletions

View File

@ -36,7 +36,7 @@
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
bool cgroupInitNsFromParent(struct nsjconf_t *nsjconf, pid_t pid) static bool cgroupInitNsFromParentMem(struct nsjconf_t *nsjconf, pid_t pid)
{ {
if (nsjconf->cgroup_mem_max == (size_t) 0) { if (nsjconf->cgroup_mem_max == (size_t) 0) {
return true; return true;
@ -85,12 +85,62 @@ bool cgroupInitNsFromParent(struct nsjconf_t *nsjconf, pid_t pid)
return true; return true;
} }
void cgroupFinishFromParent(struct nsjconf_t *nsjconf, pid_t pid) static bool cgroupInitNsFromParentPids(struct nsjconf_t *nsjconf, pid_t pid)
{
if (nsjconf->cgroup_pids_max == (size_t) 0) {
return true;
}
char pids_cgroup_path[PATH_MAX];
snprintf(pids_cgroup_path, sizeof(pids_cgroup_path), "%s/%s/NSJAIL.%d",
nsjconf->cgroup_pids_mount, nsjconf->cgroup_pids_parent, (int)pid);
LOG_D("Create '%s' for PID=%d", pids_cgroup_path, (int)pid);
if (mkdir(pids_cgroup_path, 0700) == -1 && errno != EEXIST) {
PLOG_E("mkdir('%s', 0711) failed", pids_cgroup_path);
return false;
}
char fname[PATH_MAX];
if (nsjconf->cgroup_pids_max != (size_t) 0) {
char pids_max_str[512];
snprintf(pids_max_str, sizeof(pids_max_str), "%zu", nsjconf->cgroup_pids_max);
snprintf(fname, sizeof(fname), "%s/pids.max", pids_cgroup_path);
LOG_D("Setting '%s' to '%s'", fname, pids_max_str);
if (utilWriteBufToFile(fname, pids_max_str, strlen(pids_max_str), O_WRONLY) ==
false) {
LOG_E("Could not update pids cgroup max limit");
return false;
}
}
char pid_str[512];
snprintf(pid_str, sizeof(pid_str), "%d", (int)pid);
snprintf(fname, sizeof(fname), "%s/tasks", pids_cgroup_path);
LOG_D("Adding PID='%s' to '%s'", pid_str, fname);
if (utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY) == false) {
LOG_E("Could not update pids cgroup task list");
return false;
}
return true;
}
bool cgroupInitNsFromParent(struct nsjconf_t * nsjconf, pid_t pid)
{
if (cgroupInitNsFromParentMem(nsjconf, pid) == false) {
return false;
}
if (cgroupInitNsFromParentPids(nsjconf, pid) == false) {
return false;
}
return true;
}
void cgroupFinishFromParentMem(struct nsjconf_t *nsjconf, pid_t pid)
{ {
if (nsjconf->cgroup_mem_max == (size_t) 0) { if (nsjconf->cgroup_mem_max == (size_t) 0) {
return; return;
} }
char mem_cgroup_path[PATH_MAX]; char mem_cgroup_path[PATH_MAX];
snprintf(mem_cgroup_path, sizeof(mem_cgroup_path), "%s/%s/NSJAIL.%d", snprintf(mem_cgroup_path, sizeof(mem_cgroup_path), "%s/%s/NSJAIL.%d",
nsjconf->cgroup_mem_mount, nsjconf->cgroup_mem_parent, (int)pid); nsjconf->cgroup_mem_mount, nsjconf->cgroup_mem_parent, (int)pid);
@ -101,6 +151,27 @@ void cgroupFinishFromParent(struct nsjconf_t *nsjconf, pid_t pid)
return; return;
} }
void cgroupFinishFromParentPids(struct nsjconf_t *nsjconf, pid_t pid)
{
if (nsjconf->cgroup_pids_max == (size_t) 0) {
return;
}
char pids_cgroup_path[PATH_MAX];
snprintf(pids_cgroup_path, sizeof(pids_cgroup_path), "%s/%s/NSJAIL.%d",
nsjconf->cgroup_pids_mount, nsjconf->cgroup_pids_parent, (int)pid);
LOG_D("Remove '%s'", pids_cgroup_path);
if (rmdir(pids_cgroup_path) == -1) {
PLOG_W("rmdir('%s') failed", pids_cgroup_path);
}
return;
}
void cgroupFinishFromParent(struct nsjconf_t *nsjconf, pid_t pid)
{
cgroupFinishFromParentMem(nsjconf, pid);
cgroupFinishFromParentPids(nsjconf, pid);
}
bool cgroupInitNs(void) bool cgroupInitNs(void)
{ {
return true; return true;

View File

@ -324,6 +324,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
.cgroup_mem_mount = "/sys/fs/cgroup/memory", .cgroup_mem_mount = "/sys/fs/cgroup/memory",
.cgroup_mem_parent = "NSJAIL", .cgroup_mem_parent = "NSJAIL",
.cgroup_mem_max = (size_t)0, .cgroup_mem_max = (size_t)0,
.cgroup_pids_mount = "/sys/fs/cgroup/pids",
.cgroup_pids_parent = "NSJAIL",
.cgroup_pids_max = (size_t)0,
.iface_no_lo = false, .iface_no_lo = false,
.iface = NULL, .iface = NULL,
.iface_vs_ip = "0.0.0.0", .iface_vs_ip = "0.0.0.0",
@ -419,6 +422,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
{{"cgroup_mem_max", required_argument, NULL, 0x0801}, "Maximum number of bytes to use in the group (default: '0' - disabled)"}, {{"cgroup_mem_max", required_argument, NULL, 0x0801}, "Maximum number of bytes to use in the group (default: '0' - disabled)"},
{{"cgroup_mem_mount", required_argument, NULL, 0x0802}, "Location of memory cgroup FS (default: '/sys/fs/cgroup/memory')"}, {{"cgroup_mem_mount", required_argument, NULL, 0x0802}, "Location of memory cgroup FS (default: '/sys/fs/cgroup/memory')"},
{{"cgroup_mem_parent", required_argument, NULL, 0x0803}, "Which pre-existing memory cgroup to use as a parent (default: 'NSJAIL')"}, {{"cgroup_mem_parent", required_argument, NULL, 0x0803}, "Which pre-existing memory cgroup to use as a parent (default: 'NSJAIL')"},
{{"cgroup_pids_max", required_argument, NULL, 0x0811}, "Maximum number of pids in a cgroup (default: '0' - disabled)"},
{{"cgroup_pids_mount", required_argument, NULL, 0x0812}, "Location of pids cgroup FS (default: '/sys/fs/cgroup/pids')"},
{{"cgroup_pids_parent", required_argument, NULL, 0x0813}, "Which pre-existing pids cgroup to use as a parent (default: 'NSJAIL')"},
{{"iface_no_lo", no_argument, NULL, 0x700}, "Don't bring up the 'lo' interface"}, {{"iface_no_lo", no_argument, NULL, 0x700}, "Don't bring up the 'lo' interface"},
{{"iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'"}, {{"iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'"},
{{"iface_vs_ip", required_argument, NULL, 0x701}, "IP of the 'vs' interface"}, {{"iface_vs_ip", required_argument, NULL, 0x701}, "IP of the 'vs' interface"},
@ -686,6 +692,15 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
case 0x803: case 0x803:
nsjconf->cgroup_mem_parent = optarg; nsjconf->cgroup_mem_parent = optarg;
break; break;
case 0x811:
nsjconf->cgroup_pids_max = (size_t) strtoull(optarg, NULL, 0);
break;
case 0x812:
nsjconf->cgroup_pids_mount = optarg;
break;
case 0x813:
nsjconf->cgroup_pids_parent = optarg;
break;
case 'P': case 'P':
if ((nsjconf->kafel_file = fopen(optarg, "r")) == NULL) { if ((nsjconf->kafel_file = fopen(optarg, "r")) == NULL) {
PLOG_F("Couldn't open '%s'", optarg); PLOG_F("Couldn't open '%s'", optarg);

View File

@ -146,6 +146,9 @@ struct nsjconf_t {
const char *cgroup_mem_mount; const char *cgroup_mem_mount;
const char *cgroup_mem_parent; const char *cgroup_mem_parent;
size_t cgroup_mem_max; size_t cgroup_mem_max;
const char *cgroup_pids_mount;
const char *cgroup_pids_parent;
size_t cgroup_pids_max;
FILE *kafel_file; FILE *kafel_file;
char *kafel_string; char *kafel_string;
TAILQ_HEAD(uidlist, idmap_t) uids; TAILQ_HEAD(uidlist, idmap_t) uids;