@@ -161,35 +161,6 @@ move_process_to_cgroup (pid_t pid, const char *subsystem, const char *path, libc
161
161
return ret ;
162
162
}
163
163
164
- int
165
- libcrun_get_current_unified_cgroup (char * * path , bool absolute , libcrun_error_t * err )
166
- {
167
- cleanup_free char * content = NULL ;
168
- size_t content_size ;
169
- char * from , * to ;
170
- int ret ;
171
-
172
- ret = read_all_file (PROC_SELF_CGROUP , & content , & content_size , err );
173
- if (UNLIKELY (ret < 0 ))
174
- return ret ;
175
-
176
- from = strstr (content , "0::" );
177
- if (UNLIKELY (from == NULL ))
178
- return crun_make_error (err , 0 , "cannot find cgroup2 for the current process" );
179
-
180
- from += 3 ;
181
- to = strchr (from , '\n' );
182
- if (UNLIKELY (to == NULL ))
183
- return crun_make_error (err , 0 , "cannot parse `%s`" , PROC_SELF_CGROUP );
184
- * to = '\0' ;
185
-
186
- if (absolute )
187
- return append_paths (path , err , CGROUP_ROOT , from , NULL );
188
-
189
- * path = xstrdup (from );
190
- return 0 ;
191
- }
192
-
193
164
#ifndef CGROUP2_SUPER_MAGIC
194
165
# define CGROUP2_SUPER_MAGIC 0x63677270
195
166
#endif
@@ -237,10 +208,61 @@ libcrun_get_cgroup_mode (libcrun_error_t *err)
237
208
return cgroup_mode ;
238
209
}
239
210
211
+ int
212
+ libcrun_get_cgroup_process (pid_t pid , char * * path , bool absolute , libcrun_error_t * err )
213
+ {
214
+ cleanup_free char * content = NULL ;
215
+ char proc_cgroup_file [64 ];
216
+ char * cg_path = NULL ;
217
+ size_t content_size ;
218
+ char * controller ;
219
+ char * saveptr ;
220
+ int cgroup_mode ;
221
+ bool has_data ;
222
+ int ret ;
223
+
224
+ cgroup_mode = libcrun_get_cgroup_mode (err );
225
+ if (UNLIKELY (cgroup_mode < 0 ))
226
+ return cgroup_mode ;
227
+
228
+ if (pid == 0 )
229
+ strcpy (proc_cgroup_file , PROC_SELF_CGROUP );
230
+ else
231
+ sprintf (proc_cgroup_file , "/proc/%d/cgroup" , pid );
232
+
233
+ ret = read_all_file (proc_cgroup_file , & content , & content_size , err );
234
+ if (UNLIKELY (ret < 0 ))
235
+ return ret ;
236
+
237
+ for (has_data = read_proc_cgroup (content , & saveptr , NULL , & controller , & cg_path );
238
+ has_data ;
239
+ has_data = read_proc_cgroup (NULL , & saveptr , NULL , & controller , & cg_path ))
240
+ {
241
+ if (cgroup_mode == CGROUP_MODE_UNIFIED )
242
+ {
243
+ if (strcmp (controller , "" ) == 0 && strlen (cg_path ) > 0 )
244
+ goto found ;
245
+ }
246
+ else
247
+ {
248
+ if (strcmp (controller , "memory" ))
249
+ goto found ;
250
+ }
251
+ }
252
+
253
+ return crun_make_error (err , 0 , "cannot find cgroup for the process" );
254
+
255
+ found :
256
+ if (absolute )
257
+ return append_paths (path , err , CGROUP_ROOT , cg_path , NULL );
258
+
259
+ * path = xstrdup (cg_path );
260
+ return 0 ;
261
+ }
262
+
240
263
static int
241
264
read_pids_cgroup (int dfd , bool recurse , pid_t * * pids , size_t * n_pids , size_t * allocated , libcrun_error_t * err )
242
265
{
243
- __attribute__ ((unused )) cleanup_close int clean_dfd = dfd ;
244
266
cleanup_close int tasksfd = -1 ;
245
267
cleanup_free char * buffer = NULL ;
246
268
char * saveptr = NULL ;
@@ -287,11 +309,11 @@ read_pids_cgroup (int dfd, bool recurse, pid_t **pids, size_t *n_pids, size_t *a
287
309
if (UNLIKELY (dir == NULL ))
288
310
return crun_make_error (err , errno , "open cgroup sub-directory" );
289
311
/* Now dir owns the dfd descriptor. */
290
- clean_dfd = -1 ;
312
+ dfd = -1 ;
291
313
292
314
for (de = readdir (dir ); de ; de = readdir (dir ))
293
315
{
294
- int nfd ;
316
+ cleanup_close int nfd = -1 ;
295
317
296
318
if (strcmp (de -> d_name , "." ) == 0 || strcmp (de -> d_name , ".." ) == 0 )
297
319
continue ;
@@ -346,22 +368,16 @@ rmdir_all_fd (int dfd)
346
368
size_t i , n_pids = 0 , allocated = 0 ;
347
369
cleanup_close int child_dfd = -1 ;
348
370
int tmp ;
349
- int child_dfd_clone ;
350
371
351
372
child_dfd = openat (dfd , name , O_DIRECTORY | O_CLOEXEC );
352
373
if (child_dfd < 0 )
353
374
return child_dfd ;
354
375
355
- /* read_pids_cgroup takes ownership for the fd, so dup it. */
356
- child_dfd_clone = dup (child_dfd );
357
- if (LIKELY (child_dfd_clone >= 0 ))
376
+ ret = read_pids_cgroup (child_dfd , true, & pids , & n_pids , & allocated , & tmp_err );
377
+ if (UNLIKELY (ret < 0 ))
358
378
{
359
- ret = read_pids_cgroup (child_dfd_clone , true, & pids , & n_pids , & allocated , & tmp_err );
360
- if (UNLIKELY (ret < 0 ))
361
- {
362
- crun_error_release (& tmp_err );
363
- continue ;
364
- }
379
+ crun_error_release (& tmp_err );
380
+ continue ;
365
381
}
366
382
367
383
for (i = 0 ; i < n_pids ; i ++ )
394
410
libcrun_cgroup_read_pids_from_path (const char * path , bool recurse , pid_t * * pids , libcrun_error_t * err )
395
411
{
396
412
cleanup_free char * cgroup_path = NULL ;
413
+ cleanup_close int dirfd = -1 ;
397
414
size_t n_pids , allocated ;
398
- int dirfd ;
399
415
int mode ;
400
416
int ret ;
401
417
@@ -928,7 +944,7 @@ enable_controllers (const char *path, libcrun_error_t *err)
928
944
}
929
945
930
946
int
931
- libcrun_move_process_to_cgroup (pid_t pid , pid_t init_pid , char * path , libcrun_error_t * err )
947
+ libcrun_move_process_to_cgroup (pid_t pid , pid_t init_pid , const char * path , bool create_if_missing , libcrun_error_t * err )
932
948
{
933
949
int cgroup_mode = libcrun_get_cgroup_mode (err );
934
950
if (UNLIKELY (cgroup_mode < 0 ))
@@ -937,7 +953,7 @@ libcrun_move_process_to_cgroup (pid_t pid, pid_t init_pid, char *path, libcrun_e
937
953
if (path == NULL || * path == '\0' )
938
954
return 0 ;
939
955
940
- return enter_cgroup (cgroup_mode , pid , init_pid , path , false , err );
956
+ return enter_cgroup (cgroup_mode , pid , init_pid , path , create_if_missing , err );
941
957
}
942
958
943
959
int
@@ -971,3 +987,76 @@ libcrun_get_cgroup_dirfd (struct libcrun_cgroup_status *status, const char *sub_
971
987
972
988
return cgroupdirfd ;
973
989
}
990
+
991
+ int
992
+ libcrun_migrate_all_pids_to_cgroup (pid_t init_pid , char * from , char * to , libcrun_error_t * err )
993
+ {
994
+ cleanup_free pid_t * pids = NULL ;
995
+ cleanup_close int child_dfd = -1 ;
996
+ int cgroup_mode ;
997
+ size_t from_len ;
998
+ size_t i ;
999
+ int ret ;
1000
+
1001
+ cgroup_mode = libcrun_get_cgroup_mode (err );
1002
+ if (cgroup_mode < 0 )
1003
+ return cgroup_mode ;
1004
+
1005
+ ret = libcrun_cgroup_pause_unpause_path (from , true, err );
1006
+ if (UNLIKELY (ret < 0 ))
1007
+ return ret ;
1008
+
1009
+ ret = libcrun_cgroup_read_pids_from_path (from , true, & pids , err );
1010
+ if (UNLIKELY (ret < 0 ))
1011
+ return ret ;
1012
+
1013
+ from_len = strlen (from );
1014
+
1015
+ for (i = 0 ; pids && pids [i ]; i ++ )
1016
+ {
1017
+ cleanup_free char * pid_path = NULL ;
1018
+ cleanup_free char * dest_cgroup = NULL ;
1019
+
1020
+ ret = libcrun_get_cgroup_process (pids [i ], & pid_path , false, err );
1021
+ if (UNLIKELY (ret < 0 ))
1022
+ return ret ;
1023
+
1024
+ /* Make sure the pid is in the cgroup we are migrating from. */
1025
+ if (! has_prefix (pid_path , from ))
1026
+ return crun_make_error (err , 0 , "error migrating pid %d. It is not in the cgroup `%s`" , pids [i ], from );
1027
+
1028
+ /* Build the destination cgroup path, keeping the same hierarchy. */
1029
+ xasprintf (& dest_cgroup , "%s%s" , to , pid_path + from_len );
1030
+
1031
+ ret = enter_cgroup (cgroup_mode , pids [i ], init_pid , dest_cgroup , false, err );
1032
+ if (UNLIKELY (ret < 0 ))
1033
+ return ret ;
1034
+ }
1035
+
1036
+ ret = libcrun_cgroup_pause_unpause_path (from , false, err );
1037
+ if (UNLIKELY (ret < 0 ))
1038
+ return ret ;
1039
+
1040
+ return destroy_cgroup_path (from , cgroup_mode , err );
1041
+ }
1042
+
1043
+ int
1044
+ get_cgroup_dirfd_path (int dirfd , char * * path , libcrun_error_t * err )
1045
+ {
1046
+ cleanup_free char * cgroup_path = NULL ;
1047
+ proc_fd_path_t fd_path ;
1048
+ ssize_t len ;
1049
+
1050
+ get_proc_self_fd_path (fd_path , dirfd );
1051
+
1052
+ len = safe_readlinkat (AT_FDCWD , fd_path , & cgroup_path , 0 , err );
1053
+ if (UNLIKELY (len < 0 ))
1054
+ return len ;
1055
+
1056
+ if (has_prefix (cgroup_path , CGROUP_ROOT ))
1057
+ {
1058
+ * path = xstrdup (cgroup_path + strlen (CGROUP_ROOT ));
1059
+ return 0 ;
1060
+ }
1061
+ return crun_make_error (err , 0 , "invalid cgroup path `%s`" , cgroup_path );
1062
+ }
0 commit comments