@@ -580,12 +580,52 @@ static void apply_dir_rules(void)
580
580
581
581
/*** Control groups ***/
582
582
583
- static char cg_path [256 ];
583
+ struct cg_controller_desc {
584
+ const char * name ;
585
+ int optional ;
586
+ };
587
+
588
+ typedef enum {
589
+ CG_MEMORY = 0 ,
590
+ CG_CPUACCT ,
591
+ CG_CPUSET ,
592
+ CG_NUM_CONTROLLERS ,
593
+ } cg_controller ;
594
+
595
+ static const struct cg_controller_desc cg_controllers [CG_NUM_CONTROLLERS + 1 ] = {
596
+ [CG_MEMORY ] = { "memory" , 0 },
597
+ [CG_CPUACCT ] = { "cpuacct" , 0 },
598
+ [CG_CPUSET ] = { "cpuset" , 1 },
599
+ [CG_NUM_CONTROLLERS ] = { NULL , 0 },
600
+ };
601
+
602
+ #define FOREACH_CG_CONTROLLER (_controller ) \
603
+ for (cg_controller (_controller) = 0; \
604
+ (_controller) < CG_NUM_CONTROLLERS; (_controller)++)
605
+
606
+ static const char * cg_controller_name (cg_controller c )
607
+ {
608
+ return cg_controllers [c ].name ;
609
+ }
610
+
611
+ static const int cg_controller_optional (cg_controller c )
612
+ {
613
+ return cg_controllers [c ].optional ;
614
+ }
615
+
616
+ static char cg_name [256 ];
584
617
585
618
#define CG_BUFSIZE 1024
586
619
620
+ static void
621
+ cg_makepath (char * buf , size_t len , cg_controller c , const char * attr )
622
+ {
623
+ const char * cg_root = CONFIG_ISOLATE_CGROUP_ROOT ;
624
+ snprintf (buf , len , "%s/%s/%s/%s" , cg_root , cg_controller_name (c ), cg_name , attr );
625
+ }
626
+
587
627
static int
588
- cg_read (char * attr , char * buf )
628
+ cg_read (cg_controller controller , const char * attr , char * buf )
589
629
{
590
630
int maybe = 0 ;
591
631
if (attr [0 ] == '?' )
@@ -595,7 +635,7 @@ cg_read(char *attr, char *buf)
595
635
}
596
636
597
637
char path [256 ];
598
- snprintf (path , sizeof (path ), "%s/%s" , cg_path , attr );
638
+ cg_makepath (path , sizeof (path ), controller , attr );
599
639
600
640
int fd = open (path , O_RDONLY );
601
641
if (fd < 0 )
@@ -621,30 +661,47 @@ cg_read(char *attr, char *buf)
621
661
return 1 ;
622
662
}
623
663
624
- static void __attribute__((format (printf ,2 , 3 )))
625
- cg_write (char * attr , char * fmt , ...)
664
+ static void __attribute__((format (printf ,3 , 4 )))
665
+ cg_write (cg_controller controller , const char * attr , const char * fmt , ...)
626
666
{
667
+ int maybe = 0 ;
668
+ if (attr [0 ] == '?' )
669
+ {
670
+ attr ++ ;
671
+ maybe = 1 ;
672
+ }
673
+
627
674
va_list args ;
628
675
va_start (args , fmt );
629
676
630
677
char buf [CG_BUFSIZE ];
631
678
int n = vsnprintf (buf , sizeof (buf ), fmt , args );
632
679
if (n >= CG_BUFSIZE )
633
- die ("cg_writef : Value for attribute %s is too long" , attr );
680
+ die ("cg_write : Value for attribute %s is too long" , attr );
634
681
635
682
if (verbose > 1 )
636
683
msg ("CG: Write %s = %s" , attr , buf );
637
684
638
685
char path [256 ];
639
- snprintf (path , sizeof (path ), "%s/%s" , cg_path , attr );
686
+ cg_makepath (path , sizeof (path ), controller , attr );
640
687
641
688
int fd = open (path , O_WRONLY | O_TRUNC );
642
689
if (fd < 0 )
643
- die ("Cannot write %s: %m" , path );
690
+ {
691
+ if (maybe )
692
+ return ;
693
+ else
694
+ die ("Cannot write %s: %m" , path );
695
+ }
644
696
645
697
int written = write (fd , buf , n );
646
698
if (written < 0 )
647
- die ("Cannot set %s to %s: %m" , path , buf );
699
+ {
700
+ if (maybe )
701
+ return ;
702
+ else
703
+ die ("Cannot set %s to %s: %m" , path , buf );
704
+ }
648
705
if (written != n )
649
706
die ("Short write to %s (%d out of %d bytes)" , path , written , n );
650
707
@@ -662,8 +719,8 @@ cg_init(void)
662
719
if (!dir_exists (cg_root ))
663
720
die ("Control group filesystem at %s not mounted" , cg_root );
664
721
665
- snprintf (cg_path , sizeof (cg_path ), "%s/ box-%d" , cg_root , box_id );
666
- msg ("Using control group %s\n" , cg_path );
722
+ snprintf (cg_name , sizeof (cg_name ), "box-%d" , box_id );
723
+ msg ("Using control group %s\n" , cg_name );
667
724
}
668
725
669
726
static void
@@ -674,22 +731,27 @@ cg_prepare(void)
674
731
675
732
struct stat st ;
676
733
char buf [CG_BUFSIZE ];
734
+ char path [256 ];
677
735
678
- if ( stat ( cg_path , & st ) >= 0 || errno != ENOENT )
736
+ FOREACH_CG_CONTROLLER ( controller )
679
737
{
680
- msg ("Control group %s already exists, trying to empty it.\n" , cg_path );
681
- if (rmdir (cg_path ) < 0 )
682
- die ("Failed to reset control group %s: %m" , cg_path );
683
- }
738
+ cg_makepath (path , sizeof (path ), controller , "" );
739
+ if (stat (path , & st ) >= 0 || errno != ENOENT )
740
+ {
741
+ msg ("Control group %s already exists, trying to empty it.\n" , path );
742
+ if (rmdir (path ) < 0 )
743
+ die ("Failed to reset control group %s: %m" , path );
744
+ }
684
745
685
- if (mkdir (cg_path , 0777 ) < 0 )
686
- die ("Failed to create control group %s: %m" , cg_path );
746
+ if (mkdir (path , 0777 ) < 0 && !cg_controller_optional (controller ))
747
+ die ("Failed to create control group %s: %m" , path );
748
+ }
687
749
688
750
// If cpuset module is enabled, copy allowed cpus and memory nodes from parent group
689
- if (cg_read ("?../ cpuset.cpus" , buf ))
690
- cg_write ("cpuset.cpus" , "%s" , buf );
691
- if (cg_read ("?../ cpuset.mems" , buf ))
692
- cg_write ("cpuset.mems" , "%s" , buf );
751
+ if (cg_read (CG_CPUSET , "? cpuset.cpus" , buf ))
752
+ cg_write (CG_CPUSET , "cpuset.cpus" , "%s" , buf );
753
+ if (cg_read (CG_CPUSET , "? cpuset.mems" , buf ))
754
+ cg_write (CG_CPUSET , "cpuset.mems" , "%s" , buf );
693
755
}
694
756
695
757
static void
@@ -698,22 +760,24 @@ cg_enter(void)
698
760
if (!cg_enable )
699
761
return ;
700
762
701
- msg ("Entering control group %s\n" , cg_path );
763
+ msg ("Entering control group %s\n" , cg_name );
702
764
703
- struct stat st ;
704
- if (stat (cg_path , & st ) < 0 )
705
- die ("Control group %s does not exist: %m" , cg_path );
765
+ FOREACH_CG_CONTROLLER (controller )
766
+ {
767
+ if (cg_controller_optional (controller ))
768
+ cg_write (controller , "?tasks" , "%d\n" , (int ) getpid ());
769
+ else
770
+ cg_write (controller , "tasks" , "%d\n" , (int ) getpid ());
771
+ }
706
772
707
773
if (cg_memory_limit )
708
774
{
709
- cg_write ("memory.limit_in_bytes" , "%lld\n" , (long long ) cg_memory_limit << 10 );
710
- cg_write ("memory.memsw.limit_in_bytes" , "%lld\n" , (long long ) cg_memory_limit << 10 );
775
+ cg_write (CG_MEMORY , "memory.limit_in_bytes" , "%lld\n" , (long long ) cg_memory_limit << 10 );
776
+ cg_write (CG_MEMORY , "memory.memsw.limit_in_bytes" , "%lld\n" , (long long ) cg_memory_limit << 10 );
711
777
}
712
778
713
779
if (cg_timing )
714
- cg_write ("cpuacct.usage" , "0\n" );
715
-
716
- cg_write ("tasks" , "%d\n" , (int ) getpid ());
780
+ cg_write (CG_CPUACCT , "cpuacct.usage" , "0\n" );
717
781
}
718
782
719
783
static int
@@ -723,7 +787,7 @@ cg_get_run_time_ms(void)
723
787
return 0 ;
724
788
725
789
char buf [CG_BUFSIZE ];
726
- cg_read ("cpuacct.usage" , buf );
790
+ cg_read (CG_CPUACCT , "cpuacct.usage" , buf );
727
791
unsigned long long ns = atoll (buf );
728
792
return ns / 1000000 ;
729
793
}
@@ -738,9 +802,9 @@ cg_stats(void)
738
802
739
803
// Memory usage statistics
740
804
unsigned long long mem = 0 , memsw = 0 ;
741
- if (cg_read ("?memory.max_usage_in_bytes" , buf ))
805
+ if (cg_read (CG_MEMORY , "?memory.max_usage_in_bytes" , buf ))
742
806
mem = atoll (buf );
743
- if (cg_read ("?memory.memsw.max_usage_in_bytes" , buf ))
807
+ if (cg_read (CG_MEMORY , "?memory.memsw.max_usage_in_bytes" , buf ))
744
808
{
745
809
memsw = atoll (buf );
746
810
if (memsw > mem )
@@ -758,12 +822,24 @@ cg_remove(void)
758
822
if (!cg_enable )
759
823
return ;
760
824
761
- cg_read ("tasks" , buf );
762
- if (buf [0 ])
763
- die ("Some tasks left in control group %s, failed to remove it" , cg_path );
825
+ FOREACH_CG_CONTROLLER (controller )
826
+ {
827
+ if (cg_controller_optional (controller )) {
828
+ if (!cg_read (controller , "?tasks" , buf ))
829
+ continue ;
830
+ } else
831
+ cg_read (controller , "tasks" , buf );
832
+
833
+ if (buf [0 ])
834
+ die ("Some tasks left in controller %s of cgroup %s, failed to remove it" ,
835
+ cg_controller_name (controller ), cg_name );
764
836
765
- if (rmdir (cg_path ) < 0 )
766
- die ("Cannot remove control group %s: %m" , cg_path );
837
+ char path [256 ];
838
+ cg_makepath (path , sizeof (path ), controller , "" );
839
+
840
+ if (rmdir (path ) < 0 )
841
+ die ("Cannot remove control group %s: %m" , path );
842
+ }
767
843
}
768
844
769
845
/*** Disk quotas ***/
0 commit comments