@@ -859,9 +859,15 @@ static int get_realtime_budget(void)
859859}
860860
861861/* stolen from corosync */
862+
863+ #define LEGACY_CGROUP_PROC_PIDS "/sys/fs/cgroup/cpu/tasks"
864+ #define UNIFIED_CGROUP_PROC_PIDS "/sys/fs/cgroup/cgroup.procs"
865+
862866static int sbd_move_to_root_cgroup (bool enforce_root_cgroup ) {
863867 FILE * f ;
864- int res = -1 ;
868+ int res = -1 , num ;
869+ char * rt_rq_name = NULL ;
870+ const char * root_pids = LEGACY_CGROUP_PROC_PIDS ;
865871
866872 /*
867873 * /sys/fs/cgroup is hardcoded, because most of Linux distributions are now
@@ -870,13 +876,53 @@ static int sbd_move_to_root_cgroup(bool enforce_root_cgroup) {
870876 * This feature is expected to be removed as soon as systemd gets support
871877 * for managing RT configuration.
872878 */
873- f = fopen ("/sys/fs/cgroup/cpu/cpu.rt_runtime_us" , "rt" );
874- if (f == NULL ) {
875- cl_log (LOG_DEBUG , "cpu.rt_runtime_us doesn't exist -> "
879+ do {
880+ f = fopen ("/sys/fs/cgroup/cpu/cpu.rt_runtime_us" , "rt" );
881+ if (f ) {
882+ break ;
883+ }
884+ /* CONFIG_RT_GROUP_SCHED might still be enabled with cgroup-v2
885+ cgroup.procs on cgroup-toplevel tells us we have cgroup-v2
886+ (handy as we already need that to be in selinux-policy)
887+ and name of rt_rq(s) in /proc/sched_debug tells us that
888+ CONFIG_RT_GROUP_SCHED is enabled
889+ cgroup-v2 has been around for a while in the kernel and it
890+ is no mutual exclusive compile-time-configuration - so
891+ checking what is actually mounted to go with what is there
892+ */
893+ f = fopen (UNIFIED_CGROUP_PROC_PIDS , "rt" );
894+ if (f ) {
895+ fclose (f );
896+ f = fopen ("/proc/sched_debug" , "rt" );
897+ if (f ) {
898+ while (((num = fscanf (f , "rt_rq[%*[^]]]:%m[^\n]\n" ,
899+ & rt_rq_name )) != EOF ) &&
900+ (rt_rq_name == NULL )) {
901+ /* consume a line */
902+ if ((num > 0 ) || (fscanf (f , "%*[^\n]" ) == EOF ) ||
903+ (fscanf (f , "\n" ) == EOF )) {
904+ break ;
905+ }
906+ }
907+ /* no hierarchical rt-budget distribution with
908+ cgroup-v2 so far - thus checking for budget is
909+ useless
910+ */
911+ if (rt_rq_name ) {
912+ free (rt_rq_name );
913+ enforce_root_cgroup = true;
914+ root_pids = UNIFIED_CGROUP_PROC_PIDS ;
915+ break ;
916+ }
917+ fclose (f );
918+ }
919+ }
920+ cl_log (LOG_DEBUG , "cpu.rt_runtime_us doesn't exist & "
921+ "/proc/sched_debug doesn't contain rt_rq[...]:/ -> "
876922 "system without cgroup or with disabled CONFIG_RT_GROUP_SCHED" );
877923 res = 0 ;
878924 goto exit_res ;
879- }
925+ } while ( 0 );
880926 fclose (f );
881927
882928 if ((!enforce_root_cgroup ) && (get_realtime_budget () > 0 )) {
@@ -886,21 +932,23 @@ static int sbd_move_to_root_cgroup(bool enforce_root_cgroup) {
886932 goto exit_res ;
887933 }
888934
889- f = fopen ("/sys/fs/cgroup/cpu/tasks" , "w" );
935+ f = fopen (root_pids , "w" );
890936 if (f == NULL ) {
891- cl_log (LOG_WARNING , "Can't open cgroups tasks file for writing" );
937+ cl_log (LOG_WARNING , "Can't open %s for writing" , root_pids );
892938
893939 goto exit_res ;
894940 }
895941
896942 if (fprintf (f , "%jd\n" , (intmax_t )getpid ()) <= 0 ) {
897- cl_log (LOG_WARNING , "Can't write sbd pid into cgroups tasks file" );
943+ cl_log (LOG_WARNING , "Can't write sbd pid into %s" , root_pids );
898944 goto close_and_exit_res ;
899945 }
900946
947+ res = 0 ;
948+
901949close_and_exit_res :
902950 if (fclose (f ) != 0 ) {
903- cl_log (LOG_WARNING , "Can't close cgroups tasks file" );
951+ cl_log (LOG_WARNING , "Can't close %s" , root_pids );
904952 goto exit_res ;
905953 }
906954
0 commit comments