-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit_cgroups.c
127 lines (108 loc) · 5.87 KB
/
init_cgroups.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
Early initialization of cgroup, start from the call of :
cgroup_init_early();
int __init cgroup_init_early(void)
{
static struct cgroup_sb_opts __initdata opts;
struct cgroup_subsys *ss;
...
...
init_cgroup_root(&cgrp_dfl_root, &opts);
cgrp_dfl_root.cgrp.self.flags |= CSS_NO_REF;
}
struct cgroup_root cgrp_dfl_root;
/* We already know that a process which is represented by the task_struct in the Linux kernel.
The task_struct does not contain direct link to a cgroup where this task is attached.
But it may be reached via css_set field of the task_struct. This css_set structure holds pointer to the array of subsystem states:*/
struct css_set{
...
...
...
struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
...
...
...
}
/*And via the cgroup_subsys_state, a process may get a cgroup that this process is attached to:*/
struct cgroup_subsys_state{
...
...
...
struct cgroup *cgroup;
...
...
...
}
So, the overall picture of cgroups related data structure is following:
+-------------+ +---------------------+ +------------->+---------------------+ +----------------+
| task_struct | | css_set | | | cgroup_subsys_state | | cgroup |
+-------------+ | | | +---------------------+ +----------------+
| | | | | | | | flags |
| | | | | +---------------------+ | cgroup.procs |
| | | | | | cgroup |--------->| id |
| | | | | +---------------------+ | .... |
|-------------+ |---------------------+----+ +----------------+
| cgroups | ------> | cgroup_subsys_state | array of cgroup_subsys_state
|-------------+ +---------------------+------------------>+---------------------+ +----------------+
| | | | | cgroup_subsys_state | | cgroup |
+-------------+ +---------------------+ +---------------------+ +----------------+
| | | flags |
+---------------------+ | cgroup.procs |
| cgroup |--------->| id |
+---------------------+ | .... |
| cgroup_subsys | +----------------+
+---------------------+
|
|
↓
+---------------------+
| cgroup_subsys |
+---------------------+
| id |
| name |
| css_online |
| css_offline |
| attach |
| .... |
+---------------------+
//represents mount options of cgroupfs.
//For example we may create named cgroup hierarchy (with name my_cgrp)
// with the name= option and without any subsystems:
//So, the init_cgroup_root fills the cgrp_dfl_root with the default values. The next thing is assigning initial css_set to the init_task which represents first process in the system:
RCU_INIT_POINTER(init_task.cgroups, &init_css_set);
/*And the last big thing in the cgroup_init_early function is initialization of early cgroups.
Here we go over all registered subsystems and assign unique identity number, name of a subsystem and call the cgroup_init_subsys function for subsystems which are marede as early*/
for_each_subsys(ss, i){
ss -> id = i;
ss -> name = cgroup_subsys_name[i];
if (ss -> early_init)
cgroup_init_subsys(ss, true);
}
$ mount -t cgroup -oname=my_cgrp, none /mnt/cgroups
struct cgroup_sb_opts {
u16 subsys_mask;
unsigned int flags;
char *release_agent;
bool cpuset_clone_children;
char *name;
bool none;
};
//variable ss has type cgroup_subsys, it represents a cgroup subsystem.
struct cgroup_subsys {
int (*css_online)(struct cgroup_subsys_state *css);
void (*css_offline)(struct cgroup_subsys_state *css);
...
...
...
bool early_init : 1;
int id;
const char *name;
struct cgroup_root *root;
...
...
...
}
/*Where for example css_online and css_offline callbacks are called
after a cgroup successfully will complete all allocations and a cgroup will be before releasing respectively.
The early_init flags marks subsysystems which may/should be initialized early.
The id and name fields represents unique identifier in the array of registered subsystems for a cgroup and name of a subsystem respectively.
The last - root fields represents pointer to the root of of a cgroup hierarchy.*/