Skip to content

Commit f65f320

Browse files
committed
fix
1 parent 526ba4f commit f65f320

File tree

1 file changed

+119
-124
lines changed

1 file changed

+119
-124
lines changed

judge/runguard.cc

Lines changed: 119 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,12 @@ void write_meta(const char *key, const char *format, ...)
308308
va_start(ap,format);
309309

310310
if ( fprintf(metafile,"%s: ",key)<=0 ) {
311-
outputmeta = 0;
312311
error(0,"cannot write to file `%s'",metafilename);
313312
}
314313
if ( vfprintf(metafile,format,ap)<0 ) {
315-
outputmeta = 0;
316314
error(0,"cannot write to file `%s'(vfprintf)",metafilename);
317315
}
318316
if ( fprintf(metafile,"\n")<=0 ) {
319-
outputmeta = 0;
320317
error(0,"cannot write to file `%s'",metafilename);
321318
}
322319

@@ -439,11 +436,11 @@ void output_exit_time(int exitcode, double cpudiff)
439436
void check_remaining_procs()
440437
{
441438
char path[1024];
442-
if (is_cgroup_v2) {
443-
snprintf(path, 1023, "/sys/fs/cgroup/%scgroup.procs", cgroupname);
444-
} else {
445-
snprintf(path, 1023, "/sys/fs/cgroup/cpuacct%scgroup.procs", cgroupname);
446-
}
439+
if (is_cgroup_v2) {
440+
snprintf(path, 1023, "/sys/fs/cgroup/%scgroup.procs", cgroupname);
441+
} else {
442+
snprintf(path, 1023, "/sys/fs/cgroup/cpuacct%scgroup.procs", cgroupname);
443+
}
447444

448445
FILE *file = fopen(path, "r");
449446
if (file == nullptr) {
@@ -486,40 +483,40 @@ void output_cgroup_stats_v1(double *cputime)
486483

487484
void output_cgroup_stats_v2(double *cputime)
488485
{
489-
struct cgroup *cg;
490-
if ( (cg = cgroup_new_cgroup(cgroupname))==NULL ) error(0,"cgroup_new_cgroup");
491-
492-
int ret;
493-
if ((ret = cgroup_get_cgroup(cg)) != 0) error(ret,"get cgroup information");
494-
495-
struct cgroup_controller *cg_controller = cgroup_get_controller(cg, "memory");
496-
int64_t max_usage = 0;
497-
ret = cgroup_get_value_int64(cg_controller, "memory.peak", &max_usage);
498-
if ( ret == ECGROUPVALUENOTEXIST ) {
499-
write_meta("internal-warning", "Kernel too old and does not support memory.peak");
500-
} else if ( ret!=0 ) {
501-
error(ret,"get cgroup value memory.peak");
502-
}
503-
504-
// There is no need to check swap usage, as we limit it to 0.
505-
verbose("total memory used: %" PRId64 " kB", max_usage/1024);
506-
write_meta("memory-bytes","%" PRId64, max_usage);
507-
508-
struct cgroup_stat stat;
509-
void *handle;
510-
ret = cgroup_read_stats_begin("cpu", cgroupname, &handle, &stat);
511-
while (ret == 0) {
512-
verbose("cpu.stat: %s = %s", stat.name, stat.value);
513-
if (strcmp(stat.name, "usage_usec") == 0) {
514-
long long usec = strtoll(stat.value, NULL, 10);
515-
*cputime = usec / 1e6;
516-
}
517-
ret = cgroup_read_stats_next(&handle, &stat);
518-
}
519-
if ( ret!=ECGEOF ) error(ret,"get cgroup value cpu.stat");
520-
cgroup_read_stats_end(&handle);
521-
522-
cgroup_free(&cg);
486+
struct cgroup *cg;
487+
if ( (cg = cgroup_new_cgroup(cgroupname))==NULL ) error(0,"cgroup_new_cgroup");
488+
489+
int ret;
490+
if ((ret = cgroup_get_cgroup(cg)) != 0) error(ret,"get cgroup information");
491+
492+
struct cgroup_controller *cg_controller = cgroup_get_controller(cg, "memory");
493+
int64_t max_usage = 0;
494+
ret = cgroup_get_value_int64(cg_controller, "memory.peak", &max_usage);
495+
if ( ret == ECGROUPVALUENOTEXIST ) {
496+
write_meta("internal-warning", "Kernel too old and does not support memory.peak");
497+
} else if ( ret!=0 ) {
498+
error(ret,"get cgroup value memory.peak");
499+
}
500+
501+
// There is no need to check swap usage, as we limit it to 0.
502+
verbose("total memory used: %" PRId64 " kB", max_usage/1024);
503+
write_meta("memory-bytes","%" PRId64, max_usage);
504+
505+
struct cgroup_stat stat;
506+
void *handle;
507+
ret = cgroup_read_stats_begin("cpu", cgroupname, &handle, &stat);
508+
while (ret == 0) {
509+
verbose("cpu.stat: %s = %s", stat.name, stat.value);
510+
if (strcmp(stat.name, "usage_usec") == 0) {
511+
long long usec = strtoll(stat.value, NULL, 10);
512+
*cputime = usec / 1e6;
513+
}
514+
ret = cgroup_read_stats_next(&handle, &stat);
515+
}
516+
if ( ret!=ECGEOF ) error(ret,"get cgroup value cpu.stat");
517+
cgroup_read_stats_end(&handle);
518+
519+
cgroup_free(&cg);
523520

524521
}
525522

@@ -541,21 +538,21 @@ void cgroup_create()
541538
error(0,"cgroup_add_controller memory");
542539
}
543540

544-
int ret;
545-
if (is_cgroup_v2) {
546-
// TODO: do we want to set cpu.weight here as well?
547-
if (memsize != RLIM_INFINITY) {
548-
cgroup_add_value(int64, "memory.max", memsize);
549-
// TODO: Is this the behavior change that JohnB mentioned?
550-
cgroup_add_value(int64, "memory.swap.max", 0);
551-
} else {
552-
cgroup_add_value(string, "memory.max", "max");
553-
cgroup_add_value(string, "memory.swap.max", "max");
554-
}
555-
} else {
556-
cgroup_add_value(int64, "memory.limit_in_bytes", memsize);
557-
cgroup_add_value(int64, "memory.memsw.limit_in_bytes", memsize);
558-
}
541+
int ret;
542+
if (is_cgroup_v2) {
543+
// TODO: do we want to set cpu.weight here as well?
544+
if (memsize != RLIM_INFINITY) {
545+
cgroup_add_value(int64, "memory.max", memsize);
546+
// TODO: Is this the behavior change that JohnB mentioned?
547+
cgroup_add_value(int64, "memory.swap.max", 0);
548+
} else {
549+
cgroup_add_value(string, "memory.max", "max");
550+
cgroup_add_value(string, "memory.swap.max", "max");
551+
}
552+
} else {
553+
cgroup_add_value(int64, "memory.limit_in_bytes", memsize);
554+
cgroup_add_value(int64, "memory.memsw.limit_in_bytes", memsize);
555+
}
559556

560557
/* Set up cpu restrictions; we pin the task to a specific set of
561558
cpus. We also give it exclusive access to those cores, and set
@@ -608,28 +605,28 @@ void cgroup_attach()
608605

609606
void cgroup_kill()
610607
{
611-
/* kill any remaining tasks, and wait for them to be gone */
612-
if (is_cgroup_v2) {
613-
int size;
614-
do {
615-
pid_t* pids;
616-
int ret = cgroup_get_procs(cgroupname, "memory", &pids, &size);
617-
if (ret != 0) error(ret, "cgroup_get_procs");
618-
for(int i = 0; i < size; i++) {
619-
kill(pids[i], SIGKILL);
620-
}
621-
free(pids);
622-
} while (size > 0);
623-
} else {
624-
while(1) {
625-
void *handle = nullptr;
626-
pid_t pid;
627-
int ret = cgroup_get_task_begin(cgroupname, "memory", &handle, &pid);
628-
cgroup_get_task_end(&handle);
629-
if (ret == ECGEOF) break;
630-
kill(pid, SIGKILL);
631-
}
632-
}
608+
/* kill any remaining tasks, and wait for them to be gone */
609+
if (is_cgroup_v2) {
610+
int size;
611+
do {
612+
pid_t* pids;
613+
int ret = cgroup_get_procs(cgroupname, "memory", &pids, &size);
614+
if (ret != 0) error(ret, "cgroup_get_procs");
615+
for(int i = 0; i < size; i++) {
616+
kill(pids[i], SIGKILL);
617+
}
618+
free(pids);
619+
} while (size > 0);
620+
} else {
621+
while(1) {
622+
void *handle = nullptr;
623+
pid_t pid;
624+
int ret = cgroup_get_task_begin(cgroupname, "memory", &handle, &pid);
625+
cgroup_get_task_end(&handle);
626+
if (ret == ECGEOF) break;
627+
kill(pid, SIGKILL);
628+
}
629+
}
633630
}
634631

635632
void cgroup_delete()
@@ -638,19 +635,19 @@ void cgroup_delete()
638635
cg = cgroup_new_cgroup(cgroupname);
639636
if (!cg) error(0,"cgroup_new_cgroup");
640637

641-
if (cgroup_add_controller(cg, "cpu") == nullptr) error(0, "cgroup_add_controller cpu");
642-
if (!is_cgroup_v2) {
643-
if (cgroup_add_controller(cg, "cpuacct") == nullptr) error(0, "cgroup_add_controller cpuacct");
644-
}
638+
if (cgroup_add_controller(cg, "cpu") == nullptr) error(0, "cgroup_add_controller cpu");
639+
if (!is_cgroup_v2) {
640+
if (cgroup_add_controller(cg, "cpuacct") == nullptr) error(0, "cgroup_add_controller cpuacct");
641+
}
645642
if ( cgroup_add_controller(cg, "memory")==nullptr ) error(0,"cgroup_add_controller memory");
646643

647644
if ( cpuset!=nullptr && strlen(cpuset)>0 ) {
648645
if ( cgroup_add_controller(cg, "cpuset")==nullptr ) error(0,"cgroup_add_controller cpuset");
649646
}
650647
/* Clean up our cgroup */
651648
nanosleep(&cg_delete_delay,nullptr);
652-
int ret = cgroup_delete_cgroup_ext(cg, CGFLAG_DELETE_IGNORE_MIGRATION | CGFLAG_DELETE_RECURSIVE);
653-
// TODO: is this actually benign?
649+
int ret = cgroup_delete_cgroup_ext(cg, CGFLAG_DELETE_IGNORE_MIGRATION | CGFLAG_DELETE_RECURSIVE);
650+
// TODO: is this actually benign to ignore ECGOTHER here?
654651
if ( ret!=0 && ret!=ECGOTHER ) error(ret,"deleting cgroup");
655652

656653
cgroup_free(&cg);
@@ -865,14 +862,14 @@ void setrestrictions()
865862
}
866863

867864
/* Put the child process in the cgroup */
868-
if (is_cgroup_v2) {
869-
const char *controllers[] = { "memory", NULL };
870-
if (cgroup_change_cgroup_path(cgroupname, getpid(), controllers) != 0) {
871-
error(0, "Failed to move the process to the cgroup");
872-
}
873-
} else {
874-
cgroup_attach();
875-
}
865+
if (is_cgroup_v2) {
866+
const char *controllers[] = { "memory", NULL };
867+
if (cgroup_change_cgroup_path(cgroupname, getpid(), controllers) != 0) {
868+
error(0, "Failed to move the process to the cgroup");
869+
}
870+
} else {
871+
cgroup_attach();
872+
}
876873

877874
/* Run the command in a separate process group so that the command
878875
and all its children can be killed off with one signal. */
@@ -1019,26 +1016,26 @@ void pump_pipes(fd_set* readfds, size_t data_read[], size_t data_passed[])
10191016
}
10201017

10211018
bool cgroup_is_v2() {
1022-
bool ret = false;
1023-
FILE *fp = setmntent("/proc/mounts", "r");
1024-
if (!fp) {
1025-
perror("Error opening /proc/mounts");
1026-
return false;
1027-
}
1028-
1029-
struct mntent *entry;
1030-
while ((entry = getmntent(fp)) != nullptr) {
1031-
if (strcmp(entry->mnt_dir, "/sys/fs/cgroup") == 0) {
1032-
if (strcmp(entry->mnt_type, "cgroup2") == 0) {
1033-
ret = true;
1034-
}
1035-
break;
1036-
}
1037-
}
1038-
1039-
endmntent(fp);
1040-
1041-
return ret;
1019+
bool ret = false;
1020+
FILE *fp = setmntent("/proc/mounts", "r");
1021+
if (!fp) {
1022+
perror("Error opening /proc/mounts");
1023+
return false;
1024+
}
1025+
1026+
struct mntent *entry;
1027+
while ((entry = getmntent(fp)) != nullptr) {
1028+
if (strcmp(entry->mnt_dir, "/sys/fs/cgroup") == 0) {
1029+
if (strcmp(entry->mnt_type, "cgroup2") == 0) {
1030+
ret = true;
1031+
}
1032+
break;
1033+
}
1034+
}
1035+
1036+
endmntent(fp);
1037+
1038+
return ret;
10421039
}
10431040

10441041
int main(int argc, char **argv)
@@ -1215,7 +1212,7 @@ int main(int argc, char **argv)
12151212
cmdname = argv[optind];
12161213
cmdargs = argv+optind;
12171214

1218-
is_cgroup_v2 = cgroup_is_v2();
1215+
is_cgroup_v2 = cgroup_is_v2();
12191216

12201217
if ( outputmeta && (metafile = fopen(metafilename,"w"))==nullptr ) {
12211218
error(errno,"cannot open `%s'",metafilename);
@@ -1277,8 +1274,6 @@ int main(int argc, char **argv)
12771274
}
12781275
}
12791276

1280-
// cgroup_set_default_logger(CGROUP_LOG_DEBUG);
1281-
12821277
/* Make libcgroup ready for use */
12831278
ret = cgroup_init();
12841279
if ( ret!=0 ) {
@@ -1292,8 +1287,8 @@ int main(int argc, char **argv)
12921287
} else {
12931288
str[0] = 0;
12941289
}
1295-
snprintf(cgroupname, 255, "domjudge/dj_cgroup_%d_%.16s_%d.%06d/",
1296-
getpid(), str, (int) progstarttime.tv_sec, (int) progstarttime.tv_usec);
1290+
snprintf(cgroupname, 255, "domjudge/dj_cgroup_%d_%.16s_%d.%06d/",
1291+
getpid(), str, (int) progstarttime.tv_sec, (int) progstarttime.tv_usec);
12971292

12981293
cgroup_create();
12991294

@@ -1358,7 +1353,7 @@ int main(int argc, char **argv)
13581353
error(errno,"cannot start `%s', limit: %ld/%ld | ",cmdname, limit.rlim_cur, limit.rlim_max);
13591354

13601355
default: /* become watchdog */
1361-
verbose("child pid = %d", child_pid);
1356+
verbose("child pid = %d", child_pid);
13621357
/* Shed privileges, only if not using a separate child uid,
13631358
because in that case we may need root privileges to kill
13641359
the child process. Do not use Linux specific setresuid()
@@ -1542,11 +1537,11 @@ int main(int argc, char **argv)
15421537
check_remaining_procs();
15431538

15441539
double cputime = -1;
1545-
if (is_cgroup_v2) {
1546-
output_cgroup_stats_v2(&cputime);
1547-
} else {
1548-
output_cgroup_stats_v1(&cputime);
1549-
}
1540+
if (is_cgroup_v2) {
1541+
output_cgroup_stats_v2(&cputime);
1542+
} else {
1543+
output_cgroup_stats_v1(&cputime);
1544+
}
15501545
cgroup_kill();
15511546
cgroup_delete();
15521547

0 commit comments

Comments
 (0)