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

drakenclimber / libcgroup / 20928401962

12 Jan 2026 05:15PM UTC coverage: 52.932% (-3.3%) from 56.221%
20928401962

push

github

drakenclimber
bootstrap: Update to googletest v1.16.0

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

5280 of 9975 relevant lines covered (52.93%)

563.81 hits per line

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

52.63
/src/wrapper.c
1
// SPDX-License-Identifier: LGPL-2.1-only
2
/**
3
 * Copyright IBM Corporation. 2008
4
 *
5
 * Author:        Dhaval Giani <dhaval@linux.vnet.ibm.com>
6
 *
7
 * Code initiated and designed by Dhaval Giani. All faults are most likely
8
 * his mistake.
9
 */
10

11
#define _GNU_SOURCE
12

13
#include <libcgroup.h>
14
#include <libcgroup-internal.h>
15

16
#include <inttypes.h>
17
#include <stdlib.h>
18
#include <string.h>
19
#include <unistd.h>
20
#include <stdio.h>
21
#include <errno.h>
22

23
static void init_cgroup(struct cgroup *cgroup)
6,229✔
24
{
25
        cgroup->task_fperm = NO_PERMS;
6,229✔
26
        cgroup->control_fperm = NO_PERMS;
6,229✔
27
        cgroup->control_dperm = NO_PERMS;
6,229✔
28

29
        cgroup->control_gid = NO_UID_GID;
6,229✔
30
        cgroup->control_uid = NO_UID_GID;
6,229✔
31
        cgroup->tasks_gid = NO_UID_GID;
6,229✔
32
        cgroup->tasks_uid = NO_UID_GID;
6,229✔
33
}
6,229✔
34

35
void init_cgroup_table(struct cgroup *cgroups, size_t count)
96✔
36
{
37
        size_t i;
38

39
        for (i = 0; i < count; ++i)
4,224✔
40
                init_cgroup(&cgroups[i]);
4,128✔
41
}
96✔
42

43
struct cgroup *cgroup_new_cgroup(const char *name)
2,101✔
44
{
45
        struct cgroup *cgroup;
46

47
        if (!name)
2,101✔
48
                return NULL;
×
49

50
        cgroup = calloc(1, sizeof(struct cgroup));
2,101✔
51
        if (!cgroup)
2,101✔
52
                return NULL;
×
53

54
        init_cgroup(cgroup);
2,101✔
55
        strncpy(cgroup->name, name, FILENAME_MAX - 1);
2,101✔
56
        cgroup->name[FILENAME_MAX - 1] = '\0';
2,101✔
57

58
        return cgroup;
2,101✔
59
}
60

61
struct cgroup_controller *cgroup_add_controller(struct cgroup *cgroup, const char *name)
2,006✔
62
{
63
        struct cgroup_controller *controller;
64
        int i, ret;
65

66
        if (!cgroup || !name)
2,006✔
67
                return NULL;
×
68

69
        /* Still not sure how to handle the failure here. */
70
        if (cgroup->index >= CG_CONTROLLER_MAX)
2,006✔
71
                return NULL;
×
72

73
        /* Still not sure how to handle the failure here. */
74
        for (i = 0; i < cgroup->index; i++) {
2,899✔
75
                if (strncmp(name, cgroup->controller[i]->name, CONTROL_NAMELEN_MAX) == 0)
893✔
76
                        return NULL;
×
77
        }
78

79
        controller = calloc(1, sizeof(struct cgroup_controller));
2,006✔
80
        if (!controller)
2,006✔
81
                return NULL;
×
82

83
        strncpy(controller->name, name, CONTROL_NAMELEN_MAX - 1);
2,006✔
84
        controller->name[CONTROL_NAMELEN_MAX - 1] = '\0';
2,006✔
85

86
        controller->cgroup = cgroup;
2,006✔
87
        controller->index = 0;
2,006✔
88

89
        if (strcmp(controller->name, CGRP_FILE_PREFIX) == 0) {
2,006✔
90
                /*
91
                 * Operating on the "cgroup" controller is only allowed
92
                 * on cgroup v2 systems
93
                 */
94
                controller->version = CGROUP_V2;
90✔
95
        } else {
96
                ret = cgroup_get_controller_version(controller->name, &controller->version);
1,916✔
97
                if (ret) {
1,916✔
98
                        cgroup_dbg("failed to get cgroup version for controller %s\n",
2✔
99
                                   controller->name);
100
                        free(controller);
2✔
101
                        return NULL;
2✔
102
                }
103
        }
104

105
        cgroup->controller[cgroup->index] = controller;
2,004✔
106
        cgroup->index++;
2,004✔
107

108
        return controller;
2,004✔
109
}
110

111
int cgroup_add_all_controllers(struct cgroup *cgroup)
13✔
112
{
113
        struct cgroup_controller *cgc;
114
        struct controller_data info;
115
        enum cg_setup_mode_t mode;
116
        void *handle;
117
        int ret = 0;
13✔
118

119
        if (!cgroup)
13✔
120
                return ECGINVAL;
×
121

122
        mode = cgroup_setup_mode();
13✔
123

124
        /*
125
         * Per kernel documentation, cgroup-v2.rst, /proc/cgroups is "meaningless" for cgroup v2.
126
         * Use the cgroup's cgroup.controllers file instead
127
         */
128
        if (mode == CGROUP_MODE_UNIFIED) {
13✔
129
                char *ret_c, *controller, *stok_buff = NULL, line[CGV2_CONTROLLERS_LL_MAX];
13✔
130
                /*
131
                 * cg_cgroup_v2_mount_path (FILENAME_MAX) + cgroup->name (FILENAME_MAX) +
132
                 * strlen("cgroup.controllers") (18) + 2 forward slashes + 1 NULL terminator
133
                 */
134
                char cgroup_controllers_path[FILENAME_MAX * 2 + 18 + 2 + 1];
135
                FILE *fp;
136

137
                pthread_rwlock_rdlock(&cg_mount_table_lock);
13✔
138
                if (strlen(cg_cgroup_v2_mount_path) == 0) {
13✔
139
                        pthread_rwlock_unlock(&cg_mount_table_lock);
×
140
                        ret = ECGOTHER;
×
141
                        goto out;
×
142
                }
143

144
                snprintf(cgroup_controllers_path, sizeof(cgroup_controllers_path), "%s/%s/%s",
13✔
145
                         cg_cgroup_v2_mount_path, cgroup->name, CGV2_CONTROLLERS_FILE);
13✔
146
                pthread_rwlock_unlock(&cg_mount_table_lock);
13✔
147

148
                fp = fopen(cgroup_controllers_path, "re");
13✔
149
                if (!fp) {
13✔
150
                        ret = ECGOTHER;
×
151
                        goto out;
×
152
                }
153

154
                ret_c = fgets(line, CGV2_CONTROLLERS_LL_MAX, fp);
13✔
155
                fclose(fp);
13✔
156
                if (ret_c == NULL) {
13✔
157
                        /* no controllers are enabled */
158
                        goto out;
×
159
                }
160

161
                /* Remove the trailing newline */
162
                ret_c[strlen(ret_c) - 1] = '\0';
13✔
163

164
                /*
165
                 * cgroup.controllers returns a list of available controllers in
166
                 * the following format:
167
                 *        cpuset cpu io memory pids rdma
168
                 */
169
                controller = strtok_r(ret_c, " ", &stok_buff);
13✔
170
                do {
171
                        cgc = cgroup_add_controller(cgroup, controller);
51✔
172
                        if (!cgc) {
51✔
173
                                ret = ECGINVAL;
×
174
                                fprintf(stderr, "controller %s can't be added\n", controller);
×
175
                                goto end;
×
176
                        }
177
                } while ((controller = strtok_r(NULL, " ", &stok_buff)));
51✔
178
        } else {
179
                /* go through the controller list */
180
                ret = cgroup_get_all_controller_begin(&handle, &info);
×
181
                if ((ret != 0) && (ret != ECGEOF)) {
×
182
                        fprintf(stderr, "cannot read controller data: %s\n", cgroup_strerror(ret));
×
183
                        return ret;
×
184
                }
185

186
                while (ret == 0) {
×
187
                        if (info.hierarchy == 0) {
×
188
                                /*
189
                                 * the controller is not attached to any
190
                                 * hierarchy skip it.
191
                                 */
192
                                goto next;
×
193
                        }
194

195
                        /* add mounted controller to cgroup structure */
196
                        cgc = cgroup_add_controller(cgroup, info.name);
×
197
                        if (!cgc) {
×
198
                                ret = ECGINVAL;
×
199
                                fprintf(stderr, "controller %s can't be added\n", info.name);
×
200
                                goto end;
×
201
                        }
202

203
next:
×
204
                        ret = cgroup_get_all_controller_next(&handle, &info);
×
205
                        if (ret && ret != ECGEOF)
×
206
                                goto end;
×
207
                }
208

209
end:
×
210
                cgroup_get_all_controller_end(&handle);
×
211
                if (ret == ECGEOF)
×
212
                        ret = 0;
×
213
                if (ret)
×
214
                        fprintf(stderr,        "cgroup_get_controller_begin/next failed (%s)\n",
×
215
                                cgroup_strerror(ret));
216
        }
217

218
out:
×
219
        return ret;
13✔
220
}
221

222
static void cgroup_free_value(struct control_value *value)
4,939✔
223
{
224
        if (value->multiline_value)
4,939✔
225
                free(value->multiline_value);
54✔
226
        if (value->prev_name)
4,939✔
227
                free(value->prev_name);
58✔
228

229
        free(value);
4,939✔
230
}
4,939✔
231

232
void cgroup_free_controller(struct cgroup_controller *ctrl)
2,396✔
233
{
234
        int i;
235

236
        for (i = 0; i < ctrl->index; i++)
7,327✔
237
                cgroup_free_value(ctrl->values[i]);
4,931✔
238
        ctrl->index = 0;
2,396✔
239

240
        free(ctrl);
2,396✔
241
}
2,396✔
242

243
void cgroup_free_controllers(struct cgroup *cgroup)
2,578✔
244
{
245
        int i;
246

247
        if (!cgroup)
2,578✔
248
                return;
×
249

250
        for (i = 0; i < cgroup->index; i++)
4,968✔
251
                cgroup_free_controller(cgroup->controller[i]);
2,390✔
252

253
        cgroup->index = 0;
2,578✔
254
}
255

256
void cgroup_free(struct cgroup **cgroup)
2,460✔
257
{
258
        struct cgroup *cg = *cgroup;
2,460✔
259

260
        /* Passing NULL pointers is OK. We just return. */
261
        if (!cg)
2,460✔
262
                return;
363✔
263

264
        cgroup_free_controllers(cg);
2,097✔
265
        free(cg);
2,097✔
266
        *cgroup = NULL;
2,097✔
267
}
268

269
int cgroup_add_value_string(struct cgroup_controller *controller, const char *name,
4,281✔
270
                            const char *value)
271
{
272
        int i;
273
        struct control_value *cntl_value;
274

275
        if (!controller || !name)
4,281✔
276
                return ECGINVAL;
×
277

278
        if (controller->index >= CG_NV_MAX)
4,281✔
279
                return ECGMAXVALUESEXCEEDED;
×
280

281
        for (i = 0; i < controller->index && i < CG_NV_MAX; i++) {
25,187✔
282
                if (!strcmp(controller->values[i]->name, name))
20,906✔
283
                        return ECGVALUEEXISTS;
×
284
        }
285

286
        cntl_value = calloc(1, sizeof(struct control_value));
4,281✔
287
        if (!cntl_value)
4,281✔
288
                return ECGCONTROLLERCREATEFAILED;
×
289

290
        strncpy(cntl_value->name, name, sizeof(cntl_value->name));
4,281✔
291
        cntl_value->name[sizeof(cntl_value->name)-1] = '\0';
4,281✔
292

293
        if (value) {
4,281✔
294
                if (strlen(value) >= sizeof(cntl_value->value)) {
4,009✔
295
                        fprintf(stderr, "value exceeds the maximum of %ld characters\n",
×
296
                                sizeof(cntl_value->value) - 1);
297
                        free(cntl_value);
×
298
                        return ECGCONFIGPARSEFAIL;
×
299
                }
300

301
                strncpy(cntl_value->value, value, sizeof(cntl_value->value));
4,009✔
302
                cntl_value->value[sizeof(cntl_value->value)-1] = '\0';
4,009✔
303
                cntl_value->dirty = true;
4,009✔
304
        }
305

306
        controller->values[controller->index] = cntl_value;
4,281✔
307
        controller->index++;
4,281✔
308

309
        return 0;
4,281✔
310
}
311

312
int cgroup_add_value_int64(struct cgroup_controller *controller, const char *name, int64_t value)
×
313
{
314
        char *val;
315
        int ret;
316

317
        ret = asprintf(&val, "%"PRId64, value);
×
318
        if (ret < 0) {
×
319
                last_errno = errno;
×
320
                return ECGOTHER;
×
321
        }
322

323
        ret = cgroup_add_value_string(controller, name, val);
×
324
        free(val);
×
325

326
        return ret;
×
327
}
328

329
int cgroup_add_value_uint64(struct cgroup_controller *controller, const char *name,
×
330
                            u_int64_t value)
331
{
332
        char *val;
333
        int ret;
334

335
        ret = asprintf(&val, "%" PRIu64, value);
×
336
        if (ret < 0) {
×
337
                last_errno = errno;
×
338
                return ECGOTHER;
×
339
        }
340

341
        ret = cgroup_add_value_string(controller, name, val);
×
342
        free(val);
×
343

344
        return ret;
×
345
}
346

347
int cgroup_add_value_bool(struct cgroup_controller *controller, const char *name, bool value)
×
348
{
349
        char *val;
350
        int ret;
351

352
        if (value)
×
353
                val = strdup("1");
×
354
        else
355
                val = strdup("0");
×
356
        if (!val) {
×
357
                last_errno = errno;
×
358
                return ECGOTHER;
×
359
        }
360

361
        ret = cgroup_add_value_string(controller, name, val);
×
362
        free(val);
×
363

364
        return ret;
×
365
}
366

367
int cgroup_remove_value(struct cgroup_controller * const controller, const char * const name)
8✔
368
{
369
        int i;
370

371
        for (i = 0; i < controller->index; i++) {
12✔
372
                if (strcmp(controller->values[i]->name, name) == 0) {
12✔
373
                        cgroup_free_value(controller->values[i]);
8✔
374

375
                        if (i == (controller->index - 1)) {
8✔
376
                                /* This is the last entry in the table. There's nothing to move */
377
                                controller->index--;
×
378
                        } else {
379
                                memmove(&controller->values[i],        &controller->values[i + 1],
8✔
380
                                sizeof(struct control_value *) * (controller->index - i - 1));
8✔
381
                                controller->index--;
8✔
382
                        }
383
                        return 0;
8✔
384
                }
385
        }
386

387
        return ECGROUPNOTEXIST;
×
388
}
389

390
int cgroup_compare_controllers(struct cgroup_controller *cgca, struct cgroup_controller *cgcb)
60✔
391
{
392
        int i;
393

394
        if (!cgca || !cgcb)
60✔
395
                return ECGINVAL;
×
396

397
        if (strcmp(cgca->name, cgcb->name))
60✔
398
                return ECGCONTROLLERNOTEQUAL;
36✔
399

400
        if (cgca->index != cgcb->index)
24✔
401
                return ECGCONTROLLERNOTEQUAL;
×
402

403
        for (i = 0; i < cgca->index; i++) {
103✔
404
                struct control_value *cva = cgca->values[i];
79✔
405
                struct control_value *cvb = cgcb->values[i];
79✔
406

407
                if (strcmp(cva->name, cvb->name))
79✔
408
                        return ECGCONTROLLERNOTEQUAL;
×
409

410
                if (strcmp(cva->value, cvb->value))
79✔
411
                        return ECGCONTROLLERNOTEQUAL;
×
412
        }
413

414
        return 0;
24✔
415
}
416

417
int cgroup_compare_cgroup(struct cgroup *cgroup_a, struct cgroup *cgroup_b)
16✔
418
{
419
        int i, j;
420

421
        if (!cgroup_a || !cgroup_b)
16✔
422
                return ECGINVAL;
×
423

424
        if (strcmp(cgroup_a->name, cgroup_b->name))
16✔
425
                return ECGROUPNOTEQUAL;
×
426

427
        if (cgroup_a->tasks_uid != cgroup_b->tasks_uid)
16✔
428
                return ECGROUPNOTEQUAL;
2✔
429

430
        if (cgroup_a->tasks_gid != cgroup_b->tasks_gid)
14✔
431
                return ECGROUPNOTEQUAL;
2✔
432

433
        if (cgroup_a->control_uid != cgroup_b->control_uid)
12✔
434
                return ECGROUPNOTEQUAL;
2✔
435

436
        if (cgroup_a->control_gid != cgroup_b->control_gid)
10✔
437
                return ECGROUPNOTEQUAL;
2✔
438

439
        if (cgroup_a->index != cgroup_b->index)
8✔
440
                return ECGROUPNOTEQUAL;
×
441

442
        for (i = 0; i < cgroup_a->index; i++) {
32✔
443
                struct cgroup_controller *cgca = cgroup_a->controller[i];
24✔
444
                bool found_match = false;
24✔
445

446
                /*
447
                 * Don't penalize the user if the controllers are in different order
448
                 * from cgroup_a to cgroup_b
449
                 */
450
                for (j = 0; j < cgroup_b->index; j++) {
60✔
451
                        struct cgroup_controller *cgcb = cgroup_b->controller[j];
60✔
452

453
                        if (cgroup_compare_controllers(cgca, cgcb) == 0) {
60✔
454
                                found_match = true;
24✔
455
                                break;
24✔
456
                        }
457
                }
458

459
                if (!found_match)
24✔
460
                        return ECGCONTROLLERNOTEQUAL;
×
461
        }
462

463
        return 0;
8✔
464
}
465

466
int cgroup_set_uid_gid(struct cgroup *cgroup, uid_t tasks_uid, gid_t tasks_gid, uid_t control_uid,
236✔
467
                       gid_t control_gid)
468
{
469
        if (!cgroup)
236✔
470
                return ECGINVAL;
×
471

472
        cgroup->tasks_uid = tasks_uid;
236✔
473
        cgroup->tasks_gid = tasks_gid;
236✔
474
        cgroup->control_uid = control_uid;
236✔
475
        cgroup->control_gid = control_gid;
236✔
476

477
        return 0;
236✔
478
}
479

480
int cgroup_get_uid_gid(struct cgroup *cgroup, uid_t *tasks_uid, gid_t *tasks_gid,
×
481
                       uid_t *control_uid, gid_t *control_gid)
482
{
483
        if (!cgroup || !tasks_uid || !tasks_gid || !control_uid || !control_gid)
×
484
                return ECGINVAL;
×
485

486
        *tasks_uid = cgroup->tasks_uid;
×
487
        *tasks_gid = cgroup->tasks_gid;
×
488
        *control_uid = cgroup->control_uid;
×
489
        *control_gid = cgroup->control_gid;
×
490

491
        return 0;
×
492
}
493

494
struct cgroup_controller *cgroup_get_controller(struct cgroup *cgroup, const char *name)
744✔
495
{
496
        int i;
497
        struct cgroup_controller *cgc;
498

499
        if (!cgroup)
744✔
500
                return NULL;
×
501

502
        for (i = 0; i < cgroup->index; i++) {
990✔
503
                cgc = cgroup->controller[i];
424✔
504

505
                if (!strcmp(cgc->name, name))
424✔
506
                        return cgc;
178✔
507
        }
508

509
        return NULL;
566✔
510
}
511

512
int cgroup_get_value_string(struct cgroup_controller *controller, const char *name, char **value)
562✔
513
{
514
        int i;
515

516
        if (!controller || !name || !value)
562✔
517
                return ECGINVAL;
×
518

519
        for (i = 0; i < controller->index; i++) {
3,431✔
520
                struct control_value *val = controller->values[i];
3,431✔
521

522
                if (!strcmp(val->name, name)) {
3,431✔
523
                        *value = strdup(val->value);
562✔
524

525
                        if (!*value)
562✔
526
                                return ECGOTHER;
×
527

528
                        return 0;
562✔
529
                }
530
        }
531

532
        return ECGROUPVALUENOTEXIST;
×
533

534
}
535

536
int cgroup_set_value_string(struct cgroup_controller *controller, const char *name,
12✔
537
                            const char *value)
538
{
539
        int i;
540

541
        if (!controller || !name || !value)
12✔
542
                return ECGINVAL;
×
543

544
        for (i = 0; i < controller->index; i++) {
12✔
545
                struct control_value *val = controller->values[i];
12✔
546

547
                if (!strcmp(val->name, name)) {
12✔
548
                        strncpy(val->value, value, CG_CONTROL_VALUE_MAX);
12✔
549
                        val->value[sizeof(val->value)-1] = '\0';
12✔
550
                        val->dirty = true;
12✔
551
                        return 0;
12✔
552
                }
553
        }
554

555
        return cgroup_add_value_string(controller, name, value);
×
556
}
557

558
int cgroup_get_value_int64(struct cgroup_controller *controller, const char *name, int64_t *value)
×
559
{
560
        int i;
561

562
        if (!controller || !name || !value)
×
563
                return ECGINVAL;
×
564

565
        for (i = 0; i < controller->index; i++) {
×
566
                struct control_value *val = controller->values[i];
×
567

568
                if (!strcmp(val->name, name)) {
×
569
                        if (sscanf(val->value, "%" SCNd64, value) != 1)
×
570
                                return ECGINVAL;
×
571

572
                        return 0;
×
573
                }
574
        }
575

576
        return ECGROUPVALUENOTEXIST;
×
577
}
578

579
int cgroup_set_value_int64(struct cgroup_controller *controller, const char *name, int64_t value)
×
580
{
581
        int ret;
582
        int i;
583

584
        if (!controller || !name)
×
585
                return ECGINVAL;
×
586

587
        for (i = 0; i < controller->index; i++) {
×
588
                struct control_value *val = controller->values[i];
×
589

590
                if (!strcmp(val->name, name)) {
×
591
                        ret = snprintf(val->value, sizeof(val->value), "%" PRId64, value);
×
592
                        if (ret >= sizeof(val->value))
×
593
                                return ECGINVAL;
×
594

595
                        val->dirty = true;
×
596
                        return 0;
×
597
                }
598
        }
599

600
        return cgroup_add_value_int64(controller, name, value);
×
601
}
602

603
int cgroup_get_value_uint64(struct cgroup_controller *controller, const char *name,
×
604
                            u_int64_t *value)
605
{
606
        int i;
607

608
        if (!controller || !name || !value)
×
609
                return ECGINVAL;
×
610

611
        for (i = 0; i < controller->index; i++) {
×
612
                struct control_value *val = controller->values[i];
×
613

614
                if (!strcmp(val->name, name)) {
×
615
                        if (sscanf(val->value, "%" SCNu64, value) != 1)
×
616
                                return ECGINVAL;
×
617

618
                        return 0;
×
619
                }
620
        }
621

622
        return ECGROUPVALUENOTEXIST;
×
623
}
624

625
int cgroup_set_value_uint64(struct cgroup_controller *controller, const char *name,
×
626
                            u_int64_t value)
627
{
628
        int ret;
629
        int i;
630

631
        if (!controller || !name)
×
632
                return ECGINVAL;
×
633

634
        for (i = 0; i < controller->index; i++) {
×
635
                struct control_value *val = controller->values[i];
×
636

637
                if (!strcmp(val->name, name)) {
×
638
                        ret = snprintf(val->value, sizeof(val->value), "%" PRIu64, value);
×
639
                        if (ret >= sizeof(val->value))
×
640
                                return ECGINVAL;
×
641

642
                        val->dirty = true;
×
643
                        return 0;
×
644
                }
645
        }
646

647
        return cgroup_add_value_uint64(controller, name, value);
×
648
}
649

650
int cgroup_get_value_bool(struct cgroup_controller *controller, const char *name, bool *value)
×
651
{
652
        int i;
653

654
        if (!controller || !name || !value)
×
655
                return ECGINVAL;
×
656

657
        for (i = 0; i < controller->index; i++) {
×
658
                struct control_value *val = controller->values[i];
×
659

660
                if (!strcmp(val->name, name)) {
×
661
                        int cgc_val;
662

663
                        if (sscanf(val->value, "%d", &cgc_val) != 1)
×
664
                                return ECGINVAL;
×
665

666
                        if (cgc_val)
×
667
                                *value = true;
×
668
                        else
669
                                *value = false;
×
670

671
                        return 0;
×
672
                }
673
        }
674

675
        return ECGROUPVALUENOTEXIST;
×
676
}
677

678
int cgroup_set_value_bool(struct cgroup_controller *controller, const char *name, bool value)
×
679
{
680
        int ret;
681
        int i;
682

683
        if (!controller || !name)
×
684
                return ECGINVAL;
×
685

686
        for (i = 0; i < controller->index; i++) {
×
687
                struct control_value *val = controller->values[i];
×
688

689
                if (!strcmp(val->name, name)) {
×
690
                        if (value)
×
691
                                ret = snprintf(val->value, sizeof(val->value), "1");
×
692
                        else
693
                                ret = snprintf(val->value, sizeof(val->value), "0");
×
694

695
                        if (ret >= sizeof(val->value))
×
696
                                return ECGINVAL;
×
697

698
                        val->dirty = true;
×
699
                        return 0;
×
700

701
                }
702
        }
703

704
        return cgroup_add_value_bool(controller, name, value);
×
705
}
706

707
struct cgroup *create_cgroup_from_name_value_pairs(const char *name,
365✔
708
                                                   struct control_value *name_value, int nv_number)
709
{
710
        struct cgroup_controller *cgc;
711
        struct cgroup *src_cgroup;
712
        char con[FILENAME_MAX];
713

714
        int ret;
715
        int i;
716

717
        /* create source cgroup */
718
        src_cgroup = cgroup_new_cgroup(name);
365✔
719
        if (!src_cgroup) {
365✔
720
                fprintf(stderr, "can't create cgroup: %s\n", cgroup_strerror(ECGFAIL));
×
721
                goto scgroup_err;
×
722
        }
723

724
        /* Add pairs name-value to relevant controllers of this cgroup. */
725
        for (i = 0; i < nv_number; i++) {
701✔
726

727
                if ((strchr(name_value[i].name, '.')) == NULL) {
336✔
728
                        fprintf(stderr, "wrong -r  parameter (%s=%s)\n", name_value[i].name,
×
729
                                name_value[i].value);
×
730
                        goto scgroup_err;
×
731
                }
732

733
                strncpy(con, name_value[i].name, FILENAME_MAX - 1);
336✔
734
                con[FILENAME_MAX - 1] = '\0';
336✔
735

736
                strtok(con, ".");
336✔
737

738
                /*
739
                 * find out whether we have to add the controller or
740
                 * cgroup already contains it.
741
                 */
742
                cgc = cgroup_get_controller(src_cgroup, con);
336✔
743
                if (!cgc) {
336✔
744
                        /* add relevant controller */
745
                        cgc = cgroup_add_controller(src_cgroup, con);
336✔
746
                        if (!cgc) {
336✔
747
                                fprintf(stderr, "controller %s can't be add\n",        con);
×
748
                                goto scgroup_err;
×
749
                        }
750
                }
751

752
                /* add name-value pair to this controller */
753
                ret = cgroup_add_value_string(cgc, name_value[i].name, name_value[i].value);
336✔
754
                if (ret) {
336✔
755
                        fprintf(stderr, "name-value pair %s=%s can't be set\n",        name_value[i].name,
×
756
                                name_value[i].value);
×
757
                        goto scgroup_err;
×
758
                }
759
        }
760

761
        return src_cgroup;
365✔
762

763
scgroup_err:
×
764
        cgroup_free(&src_cgroup);
×
765

766
        return NULL;
×
767
}
768

769
int cgroup_get_value_name_count(struct cgroup_controller *controller)
148✔
770
{
771
        if (!controller)
148✔
772
                return -1;
×
773

774
        return controller->index;
148✔
775
}
776

777

778
char *cgroup_get_value_name(struct cgroup_controller *controller, int index)
739✔
779
{
780

781
        if (!controller)
739✔
782
                return NULL;
×
783

784
        if (index < controller->index)
739✔
785
                return (controller->values[index])->name;
739✔
786
        else
787
                return NULL;
×
788
}
789

790
char *cgroup_get_cgroup_name(struct cgroup *cgroup)
×
791
{
792
        if (!cgroup)
×
793
                return NULL;
×
794

795
        return cgroup->name;
×
796
}
797

798

799
/*
800
 * Return true if cgroup setup mode is cgroup v1 (legacy), else
801
 * returns false.
802
 */
803
bool is_cgroup_mode_legacy(void)
2✔
804
{
805
        enum cg_setup_mode_t setup_mode;
806

807
        setup_mode = cgroup_setup_mode();
2✔
808
        return (setup_mode == CGROUP_MODE_LEGACY);
2✔
809
}
810

811
/*
812
 * Return true if cgroup setup mode is cgroup v1/v2 (hybrid), else
813
 * returns false.
814
 */
815
bool is_cgroup_mode_hybrid(void)
2✔
816
{
817
        enum cg_setup_mode_t setup_mode;
818

819
        setup_mode = cgroup_setup_mode();
2✔
820
        return (setup_mode == CGROUP_MODE_HYBRID);
2✔
821
}
822

823
/*
824
 * Return true if cgroup setup mode is cgroup v2 (unified), else
825
 * returns false.
826
 */
827
bool is_cgroup_mode_unified(void)
79✔
828
{
829
        enum cg_setup_mode_t setup_mode;
830

831
        setup_mode = cgroup_setup_mode();
79✔
832
        return (setup_mode == CGROUP_MODE_UNIFIED);
79✔
833
}
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