• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

drakenclimber / libcgroup / 14937352646

09 May 2025 08:40PM UTC coverage: 54.044% (-2.1%) from 56.161%
14937352646

push

github

drakenclimber
wip - have it working

sudo ./src/tools/cgset -p -r AllowedCPUs=1-3,6-13,15 foo.scope

Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>

8 of 222 new or added lines in 2 files covered. (3.6%)

170 existing lines in 13 files now uncovered.

5573 of 10312 relevant lines covered (54.04%)

325.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

48.19
/src/tools/cgcreate.c
1
// SPDX-License-Identifier: LGPL-2.1-only
2
/**
3
 * Copyright Red Hat, Inc. 2009
4
 *
5
 * Authors:        Ivana Hutarova Varekova <varekova@redhat.com>
6
 */
7

8
#include "tools-common.h"
9

10
#include <libcgroup.h>
11
#include <libcgroup-internal.h>
12

13
#include <getopt.h>
14
#include <stdlib.h>
15
#include <string.h>
16
#include <unistd.h>
17
#include <stdio.h>
18
#include <errno.h>
19
#include <pwd.h>
20
#include <grp.h>
21

22
#include <sys/types.h>
23

24
/*
25
 * Display the usage
26
 */
27
static void usage(int status, const char *program_name)
×
28
{
29
        if (status != 0) {
×
30
                err("Wrong input parameters, try %s -h for more information.\n", program_name);
×
31
                return;
×
32
        }
33

34
        info("Usage: %s [-h] [-f mode] [-d mode] [-s mode] ", program_name);
×
35
        info("[-t <tuid>:<tgid>] [-a <agid>:<auid>] -g <controllers>:<path> [-g ...]\n");
×
36
        info("Create control group(s)\n");
×
37
        info("  -a <tuid>:<tgid>                Owner of the group and all its files\n");
×
38
        info("  -d, --dperm=mode                Group directory permissions\n");
×
39
        info("  -f, --fperm=mode                Group file permissions\n");
×
40
        info("  -g <controllers>:<path>        Control group which should be added\n");
×
41
        info("  -h, --help                        Display this help\n");
×
42
        info("  -s, --tperm=mode                Tasks file permissions\n");
×
43
        info("  -t <tuid>:<tgid>                Owner of the tasks file\n");
×
44
#ifdef WITH_SYSTEMD
UNCOV
45
        info("  -b                                Ignore default systemd");
×
UNCOV
46
        info("delegate hierarchy\n");
×
UNCOV
47
        info("  -c, --scope                        Create a delegated systemd scope\n");
×
UNCOV
48
        info("  -p, --pid=pid                        Task pid to use to create systemd ");
×
UNCOV
49
        info("scope\n");
×
UNCOV
50
        info("  -S, --setdefault                Set this scope as the default scope ");
×
UNCOV
51
        info("delegate hierarchy\n");
×
52
#endif
53
}
54

55
#ifdef WITH_SYSTEMD
56
static int create_systemd_scope(struct cgroup * const cgrp, const char * const prog_name,
18✔
57
                                int set_default, pid_t pid)
58
{
59
        struct cgroup_systemd_scope_opts opts;
60
        char slice[FILENAME_MAX];
61
        char *scope;
62
        int ret;
63
        int len;
64

65
        ret = cgroup_set_default_scope_opts(&opts);
18✔
66
        if (ret)
18✔
UNCOV
67
                return ret;
×
68

69
        opts.pid = pid;
18✔
70

71
        ret = cgroup_create_scope2(cgrp, 0, &opts);
18✔
72
        if (!ret && set_default) {
18✔
73
                scope = strstr(cgrp->name, "/");
2✔
74
                if (!scope) {
2✔
UNCOV
75
                        err("%s: Invalid scope name %s, expected <slice>/<scope>\n",
×
76
                            prog_name, cgrp->name);
UNCOV
77
                        ret = ECGINVAL;
×
UNCOV
78
                        goto err;
×
79
                }
80
                len = strlen(cgrp->name) - strlen(scope);
2✔
81
                strncpy(slice, cgrp->name, FILENAME_MAX - 1);
2✔
82
                slice[len] = '\0';
2✔
83
                scope++;
2✔
84

85
                ret = cgroup_write_systemd_default_cgroup(slice, scope);
2✔
86
                /*
87
                 * cgroup_write_systemd_default_cgroup() returns 0 on failure
88
                 */
89
                if (ret == 0) {
2✔
UNCOV
90
                        err("%s: failed to write default %s/%s to /var/run/libcgroup/systemd\n",
×
91
                            prog_name, slice, scope);
UNCOV
92
                        ret = ECGINVAL;
×
UNCOV
93
                        goto err;
×
94
                }
95

96
                /*
97
                 * the default was successfully set.  Override the return of "1" back to
98
                 * the usual "0" on success.
99
                 */
100
                ret = 0;
2✔
101
        }
102

103
err:
16✔
104
        return ret;
18✔
105
}
106
#else
107
static int create_systemd_scope(struct cgroup * const cgrp, const char * const prog_name,
108
                                int set_default, pid_t pid)
109
{
110
        return ECGINVAL;
111
}
112
#endif /* WITH_SYSTEMD */
113

114
int main(int argc, char *argv[])
118✔
115
{
116
        static struct option long_opts[] = {
117
                {"help",              no_argument, NULL, 'h'},
118
                {"task",        required_argument, NULL, 't'},
119
                {"admin",        required_argument, NULL, 'a'},
120
                {"",                required_argument, NULL, 'g'},
121
                {"dperm",        required_argument, NULL, 'd'},
122
                {"fperm",        required_argument, NULL, 'f'},
123
                {"tperm",        required_argument, NULL, 's'},
124
#ifdef WITH_SYSTEMD
125
                {"scope",              no_argument, NULL, 'c'},
126
                {"setdefault",              no_argument, NULL, 'S'},
127
                {"pid",                required_argument, NULL, 'p'},
128
#endif /* WITH_SYSTEMD */
129
                {0, 0, 0, 0},
130
        };
131

132
        uid_t tuid = CGRULE_INVALID, auid = CGRULE_INVALID;
118✔
133
        gid_t tgid = CGRULE_INVALID, agid = CGRULE_INVALID;
118✔
134

135
#ifdef WITH_SYSTEMD
136
        int ignore_default_systemd_delegate_slice = 0;
118✔
137
#endif
138
        int set_default_scope = 0;
118✔
139
        int create_scope = 0;
118✔
140
        pid_t scope_pid = -1;
118✔
141

142
        struct cgroup_group_spec **cgrp_list;
143
        struct cgroup_controller *cgc;
144
        struct cgroup *cgrp;
145

146
        /* approximation of max. numbers of groups that will be created */
147
        int capacity = argc;
118✔
148

149
        /* permission variables */
150
        mode_t tasks_mode = NO_PERMS;
118✔
151
        mode_t file_mode = NO_PERMS;
118✔
152
        mode_t dir_mode = NO_PERMS;
118✔
153
        int filem_change = 0;
118✔
154
        int dirm_change = 0;
118✔
155

156
        int ret = 0;
118✔
157
        int i, j;
158
        int c;
159

160
        /* no parameter on input */
161
        if (argc < 2) {
118✔
162
                usage(1, argv[0]);
×
163
                exit(EXIT_BADARGS);
×
164
        }
165

166
        cgrp_list = calloc(capacity, sizeof(struct cgroup_group_spec *));
118✔
167
        if (cgrp_list == NULL) {
118✔
168
                err("%s: out of memory\n", argv[0]);
×
169
                ret = -1;
×
170
                goto err;
×
171
        }
172

173
#ifdef WITH_SYSTEMD
174
        /* parse arguments */
175
        while ((c = getopt_long(argc, argv, "a:t:g:hd:f:s:bcp:S", long_opts, NULL)) > 0) {
266✔
176
                switch (c) {
148✔
177
                case 'b':
5✔
178
                        ignore_default_systemd_delegate_slice = 1;
5✔
179
                        break;
5✔
180
                case 'c':
18✔
181
                        create_scope = 1;
18✔
182
                        break;
18✔
183
                case 'p':
3✔
184
                        scope_pid = atoi(optarg);
3✔
185
                        if (scope_pid <= 1) {
3✔
UNCOV
186
                                err("%s: Invalid pid %s\n", argv[0], optarg);
×
UNCOV
187
                                ret = EXIT_BADARGS;
×
UNCOV
188
                                goto err;
×
189
                        }
190
                        break;
3✔
191
                case 'S':
2✔
192
                        set_default_scope = 1;
2✔
193
                        break;
2✔
194
#else
195
        while ((c = getopt_long(argc, argv, "a:t:g:hd:f:s:", long_opts, NULL)) > 0) {
196
                switch (c) {
197
#endif
198
                case 'h':
×
199
                        usage(0, argv[0]);
×
200
                        ret = 0;
×
201
                        goto err;
×
202
                case 'a':
2✔
203
                        /* set admin uid/gid */
204
                        if (parse_uid_gid(optarg, &auid, &agid, argv[0]))
2✔
205
                                goto err;
×
206
                        break;
2✔
207
                case 't':
×
208
                        /* set task uid/gid */
209
                        if (parse_uid_gid(optarg, &tuid, &tgid, argv[0]))
×
210
                                goto err;
×
211
                        break;
×
212
                case 'g':
118✔
213
                        ret = parse_cgroup_spec(cgrp_list, optarg, capacity);
118✔
214
                        if (ret) {
118✔
215
                                err("%s: cgroup controller and path parsing failed (%s)\n",
×
216
                                    argv[0], argv[optind]);
217
                                ret = EXIT_BADARGS;
×
218
                                goto err;
×
219
                        }
220
                        break;
118✔
221
                case 'd':
×
222
                        dirm_change = 1;
×
223
                        ret = parse_mode(optarg, &dir_mode, argv[0]);
×
224
                        if (ret)
×
225
                                goto err;
×
226
                        break;
×
227
                case 'f':
×
228
                        filem_change = 1;
×
229
                        ret = parse_mode(optarg, &file_mode, argv[0]);
×
230
                        if (ret)
×
231
                                goto err;
×
232
                        break;
×
233
                case 's':
×
234
                        filem_change = 1;
×
235
                        ret = parse_mode(optarg, &tasks_mode, argv[0]);
×
236
                        if (ret)
×
237
                                goto err;
×
238
                        break;
×
239
                default:
×
240
                        usage(1, argv[0]);
×
241
                        ret = EXIT_BADARGS;
×
242
                        goto err;
×
243
                }
244
        }
245

246
#ifdef WITH_SYSTEMD
247
        if (ignore_default_systemd_delegate_slice && create_scope) {
118✔
UNCOV
248
                err("%s: \"-b\" and \"-c\" are mutually exclusive\n", argv[0]);
×
UNCOV
249
                ret = EXIT_BADARGS;
×
UNCOV
250
                goto err;
×
251
        }
252

253
        if (set_default_scope && !create_scope) {
118✔
UNCOV
254
                err("%s: \"-S\" requires \"-c\" to be provided\n", argv[0]);
×
UNCOV
255
                ret = EXIT_BADARGS;
×
UNCOV
256
                goto err;
×
257
        }
258

259
        if (!create_scope && scope_pid != -1) {
118✔
UNCOV
260
                err("%s: \"-p\" requires \"-c\" to be provided\n", argv[0]);
×
UNCOV
261
                ret = EXIT_BADARGS;
×
UNCOV
262
                goto err;
×
263
        }
264
#endif
265

266
        /* no cgroup name */
267
        if (argv[optind]) {
118✔
268
                err("%s: wrong arguments (%s)\n", argv[0], argv[optind]);
×
269
                ret = EXIT_BADARGS;
×
270
                goto err;
×
271
        }
272

273
        /* initialize libcgroup */
274
        ret = cgroup_init();
118✔
275
        if (ret) {
118✔
276
                err("%s: libcgroup initialization failed: %s\n", argv[0], cgroup_strerror(ret));
×
277
                goto err;
×
278
        }
279

280
#ifdef WITH_SYSTEMD
281
        if (!create_scope && !ignore_default_systemd_delegate_slice)
118✔
282
                cgroup_set_default_systemd_cgroup();
95✔
283
#endif
284

285
        /* for each new cgroup */
286
        for (i = 0; i < capacity; i++) {
224✔
287
                if (!cgrp_list[i])
224✔
288
                        break;
106✔
289

290
                /* create the new cgroup structure */
291
                cgrp = cgroup_new_cgroup(cgrp_list[i]->path);
118✔
292
                if (!cgrp) {
118✔
293
                        ret = ECGFAIL;
×
294
                        err("%s: can't add new cgroup: %s\n", argv[0], cgroup_strerror(ret));
×
295
                        goto err;
×
296
                }
297

298
                /* set uid and gid for the new cgroup based on input options */
299
                ret = cgroup_set_uid_gid(cgrp, tuid, tgid, auid, agid);
118✔
300
                if (ret)
118✔
301
                        goto err;
×
302

303
                /* add controllers to the new cgroup */
304
                j = 0;
118✔
305
                while (cgrp_list[i]->controllers[j]) {
256✔
306
                        if (strcmp(cgrp_list[i]->controllers[j], "*") == 0) {
138✔
307
                                /* it is meta character, add all controllers */
308
                                ret = cgroup_add_all_controllers(cgrp);
×
309
                                if (ret != 0) {
×
310
                                        ret = ECGINVAL;
×
311
                                        err("%s: can't add all controllers\n", argv[0]);
×
312
                                        cgroup_free(&cgrp);
×
313
                                        goto err;
×
314
                                }
315
                        } else {
316
                                cgc = cgroup_add_controller(cgrp,
138✔
317
                                        cgrp_list[i]->controllers[j]);
138✔
318
                                if (!cgc) {
138✔
319
                                        ret = ECGINVAL;
×
320
                                        err("%s: controller %s can't be add\n", argv[0],
×
321
                                            cgrp_list[i]->controllers[j]);
322
                                        cgroup_free(&cgrp);
×
323
                                        goto err;
×
324
                                }
325
                        }
326
                        j++;
138✔
327
                }
328

329
                /* all variables set so create cgroup */
330
                if (dirm_change | filem_change)
118✔
331
                        cgroup_set_permissions(cgrp, dir_mode, file_mode, tasks_mode);
×
332

333
                if (create_scope)
118✔
334
                        ret = create_systemd_scope(cgrp, argv[0], set_default_scope, scope_pid);
18✔
335
                else
336
                        ret = cgroup_create_cgroup(cgrp, 0);
100✔
337
                if (ret) {
118✔
338
                        err("%s: can't create cgroup %s: %s\n", argv[0], cgrp->name,
12✔
339
                            cgroup_strerror(ret));
340
                        cgroup_free(&cgrp);
12✔
341
                        goto err;
12✔
342
                }
343
                cgroup_free(&cgrp);
106✔
344
        }
345

346
err:
×
347
        if (cgrp_list) {
118✔
348
                for (i = 0; i < capacity; i++) {
507✔
349
                        if (cgrp_list[i])
389✔
350
                                cgroup_free_group_spec(cgrp_list[i]);
118✔
351
                }
352
                free(cgrp_list);
118✔
353
        }
354

355
        return ret;
118✔
356
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc