@@ -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)
439436void 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
487484void 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
609606void 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
635632void 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
10211018bool 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
10441041int 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