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

systemd / systemd / 15263807472

26 May 2025 08:53PM UTC coverage: 72.046% (-0.002%) from 72.048%
15263807472

push

github

yuwata
src/core/manager.c: log preset activity on first boot

This gives us a little more information about what units were enabled
or disabled on that first boot and will be useful for OS developers
tracking down the source of unit state.

An example with this enabled looks like:

```
NET: Registered PF_VSOCK protocol family
systemd[1]: Applying preset policy.
systemd[1]: Unit /etc/systemd/system/dnsmasq.service is masked, ignoring.
systemd[1]: Unit /etc/systemd/system/systemd-repart.service is masked, ignoring.
systemd[1]: Removed '/etc/systemd/system/sockets.target.wants/systemd-resolved-monitor.socket'.
systemd[1]: Removed '/etc/systemd/system/sockets.target.wants/systemd-resolved-varlink.socket'.
systemd[1]: Created symlink '/etc/systemd/system/multi-user.target.wants/var-mnt-workdir.mount' → '/etc/systemd/system/var-mnt-workdir.mount'.
systemd[1]: Created symlink '/etc/systemd/system/multi-user.target.wants/var-mnt-workdir\x2dtmp.mount' → '/etc/systemd/system/var-mnt-workdir\x2dtmp.mount'.
systemd[1]: Created symlink '/etc/systemd/system/afterburn-sshkeys.target.requires/afterburn-sshkeys@core.service' → '/usr/lib/systemd/system/afterburn-sshkeys@.service'.
systemd[1]: Created symlink '/etc/systemd/system/sockets.target.wants/systemd-resolved-varlink.socket' → '/usr/lib/systemd/system/systemd-resolved-varlink.socket'.
systemd[1]: Created symlink '/etc/systemd/system/sockets.target.wants/systemd-resolved-monitor.socket' → '/usr/lib/systemd/system/systemd-resolved-monitor.socket'.
systemd[1]: Populated /etc with preset unit settings.
```

Considering it only happens on first boot and not on every boot I think
the extra information is worth the extra verbosity in the logs just for
that boot.

5 of 6 new or added lines in 1 file covered. (83.33%)

5463 existing lines in 165 files now uncovered.

299151 of 415222 relevant lines covered (72.05%)

702386.45 hits per line

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

92.8
/src/basic/rlimit-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "alloc-util.h"
4
#include "errno-util.h"
5
#include "extract-word.h"
6
#include "fd-util.h"
7
#include "fileio.h"
8
#include "format-util.h"
9
#include "log.h"
10
#include "parse-util.h"
11
#include "process-util.h"
12
#include "rlimit-util.h"
13
#include "string-table.h"
14
#include "strv.h"
15
#include "time-util.h"
16

17
int setrlimit_closest(int resource, const struct rlimit *rlim) {
42,128✔
18
        struct rlimit highest, fixed;
42,128✔
19

20
        assert(rlim);
42,128✔
21

22
        if (setrlimit(resource, rlim) >= 0)
42,128✔
23
                return 0;
42,128✔
24

25
        if (errno != EPERM)
235✔
26
                return -errno;
1✔
27

28
        /* So we failed to set the desired setrlimit, then let's try
29
         * to get as close as we can */
30
        if (getrlimit(resource, &highest) < 0)
234✔
UNCOV
31
                return -errno;
×
32

33
        /* If the hard limit is unbounded anyway, then the EPERM had other reasons, let's propagate the original EPERM
34
         * then */
35
        if (highest.rlim_max == RLIM_INFINITY)
234✔
36
                return -EPERM;
37

38
        fixed = (struct rlimit) {
234✔
39
                .rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max),
234✔
40
                .rlim_max = MIN(rlim->rlim_max, highest.rlim_max),
234✔
41
        };
42

43
        /* Shortcut things if we wouldn't change anything. */
44
        if (fixed.rlim_cur == highest.rlim_cur &&
234✔
45
            fixed.rlim_max == highest.rlim_max)
46
                return 0;
47

48
        log_debug("Failed at setting rlimit " RLIM_FMT " for resource RLIMIT_%s. Will attempt setting value " RLIM_FMT " instead.", rlim->rlim_max, rlimit_to_string(resource), fixed.rlim_max);
118✔
49

50
        return RET_NERRNO(setrlimit(resource, &fixed));
118✔
51
}
52

53
int setrlimit_closest_all(const struct rlimit *const *rlim, int *which_failed) {
9,701✔
54
        int r;
9,701✔
55

56
        assert(rlim);
9,701✔
57

58
        /* On failure returns the limit's index that failed in *which_failed, but only if non-NULL */
59

60
        for (int i = 0; i < _RLIMIT_MAX; i++) {
164,917✔
61
                if (!rlim[i])
155,216✔
62
                        continue;
134,321✔
63

64
                r = setrlimit_closest(i, rlim[i]);
20,895✔
65
                if (r < 0) {
20,895✔
UNCOV
66
                        if (which_failed)
×
UNCOV
67
                                *which_failed = i;
×
68

69
                        return r;
×
70
                }
71
        }
72

73
        if (which_failed)
9,701✔
74
                *which_failed = -1;
9,701✔
75

76
        return 0;
77
}
78

79
static int rlimit_parse_u64(const char *val, rlim_t *ret) {
23,110✔
80
        uint64_t u;
23,110✔
81
        int r;
23,110✔
82

83
        assert(val);
23,110✔
84
        assert(ret);
23,110✔
85

86
        if (streq(val, "infinity")) {
23,110✔
87
                *ret = RLIM_INFINITY;
12✔
88
                return 0;
12✔
89
        }
90

91
        /* setrlimit(2) suggests rlim_t is always 64-bit on Linux. */
92
        assert_cc(sizeof(rlim_t) == sizeof(uint64_t));
23,098✔
93

94
        r = safe_atou64(val, &u);
23,098✔
95
        if (r < 0)
23,098✔
96
                return r;
97
        if (u >= (uint64_t) RLIM_INFINITY)
23,095✔
98
                return -ERANGE;
99

100
        *ret = (rlim_t) u;
23,095✔
101
        return 0;
23,095✔
102
}
103

104
static int rlimit_parse_size(const char *val, rlim_t *ret) {
11,591✔
105
        uint64_t u;
11,591✔
106
        int r;
11,591✔
107

108
        assert(val);
11,591✔
109
        assert(ret);
11,591✔
110

111
        if (streq(val, "infinity")) {
11,591✔
112
                *ret = RLIM_INFINITY;
6✔
113
                return 0;
6✔
114
        }
115

116
        r = parse_size(val, 1024, &u);
11,585✔
117
        if (r < 0)
11,585✔
118
                return r;
119
        if (u >= (uint64_t) RLIM_INFINITY)
11,585✔
120
                return -ERANGE;
121

122
        *ret = (rlim_t) u;
11,585✔
123
        return 0;
11,585✔
124
}
125

126
static int rlimit_parse_sec(const char *val, rlim_t *ret) {
15✔
127
        uint64_t u;
15✔
128
        usec_t t;
15✔
129
        int r;
15✔
130

131
        assert(val);
15✔
132
        assert(ret);
15✔
133

134
        if (streq(val, "infinity")) {
15✔
135
                *ret = RLIM_INFINITY;
1✔
136
                return 0;
1✔
137
        }
138

139
        r = parse_sec(val, &t);
14✔
140
        if (r < 0)
14✔
141
                return r;
142
        if (t == USEC_INFINITY) {
14✔
UNCOV
143
                *ret = RLIM_INFINITY;
×
UNCOV
144
                return 0;
×
145
        }
146

147
        u = (uint64_t) DIV_ROUND_UP(t, USEC_PER_SEC);
14✔
148
        if (u >= (uint64_t) RLIM_INFINITY)
14✔
149
                return -ERANGE;
150

151
        *ret = (rlim_t) u;
14✔
152
        return 0;
14✔
153
}
154

155
static int rlimit_parse_usec(const char *val, rlim_t *ret) {
12✔
156
        usec_t t;
12✔
157
        int r;
12✔
158

159
        assert(val);
12✔
160
        assert(ret);
12✔
161

162
        if (streq(val, "infinity")) {
12✔
163
                *ret = RLIM_INFINITY;
3✔
164
                return 0;
3✔
165
        }
166

167
        r = parse_time(val, &t, 1);
9✔
168
        if (r < 0)
9✔
169
                return r;
170
        if (t == USEC_INFINITY) {
9✔
UNCOV
171
                *ret = RLIM_INFINITY;
×
UNCOV
172
                return 0;
×
173
        }
174

175
        *ret = (rlim_t) t;
9✔
176
        return 0;
9✔
177
}
178

179
static int rlimit_parse_nice(const char *val, rlim_t *ret) {
23✔
180
        uint64_t rl;
23✔
181
        int r;
23✔
182

183
        /* So, Linux is weird. The range for RLIMIT_NICE is 40..1, mapping to the nice levels -20..19. However, the
184
         * RLIMIT_NICE limit defaults to 0 by the kernel, i.e. a value that maps to nice level 20, which of course is
185
         * bogus and does not exist. In order to permit parsing the RLIMIT_NICE of 0 here we hence implement a slight
186
         * asymmetry: when parsing as positive nice level we permit 0..19. When parsing as negative nice level, we
187
         * permit -20..0. But when parsing as raw resource limit value then we also allow the special value 0.
188
         *
189
         * Yeah, Linux is quality engineering sometimes... */
190

191
        if (val[0] == '+') {
23✔
192

193
                /* Prefixed with "+": Parse as positive user-friendly nice value */
194
                r = safe_atou64(val + 1, &rl);
4✔
195
                if (r < 0)
4✔
196
                        return r;
23✔
197

198
                if (rl >= PRIO_MAX)
4✔
199
                        return -ERANGE;
200

201
                rl = 20 - rl;
3✔
202

203
        } else if (val[0] == '-') {
19✔
204

205
                /* Prefixed with "-": Parse as negative user-friendly nice value */
206
                r = safe_atou64(val + 1, &rl);
4✔
207
                if (r < 0)
4✔
208
                        return r;
209

210
                if (rl > (uint64_t) (-PRIO_MIN))
4✔
211
                        return -ERANGE;
212

213
                rl = 20 + rl;
3✔
214
        } else {
215

216
                /* Not prefixed: parse as raw resource limit value */
217
                r = safe_atou64(val, &rl);
15✔
218
                if (r < 0)
15✔
219
                        return r;
220

221
                if (rl > (uint64_t) (20 - PRIO_MIN))
15✔
222
                        return -ERANGE;
223
        }
224

225
        *ret = (rlim_t) rl;
20✔
226
        return 0;
20✔
227
}
228

229
static int (*const rlimit_parse_table[_RLIMIT_MAX])(const char *val, rlim_t *ret) = {
230
        [RLIMIT_CPU] = rlimit_parse_sec,
231
        [RLIMIT_FSIZE] = rlimit_parse_size,
232
        [RLIMIT_DATA] = rlimit_parse_size,
233
        [RLIMIT_STACK] = rlimit_parse_size,
234
        [RLIMIT_CORE] = rlimit_parse_size,
235
        [RLIMIT_RSS] = rlimit_parse_size,
236
        [RLIMIT_NOFILE] = rlimit_parse_u64,
237
        [RLIMIT_AS] = rlimit_parse_size,
238
        [RLIMIT_NPROC] = rlimit_parse_u64,
239
        [RLIMIT_MEMLOCK] = rlimit_parse_size,
240
        [RLIMIT_LOCKS] = rlimit_parse_u64,
241
        [RLIMIT_SIGPENDING] = rlimit_parse_u64,
242
        [RLIMIT_MSGQUEUE] = rlimit_parse_size,
243
        [RLIMIT_NICE] = rlimit_parse_nice,
244
        [RLIMIT_RTPRIO] = rlimit_parse_u64,
245
        [RLIMIT_RTTIME] = rlimit_parse_usec,
246
};
247

248
int rlimit_parse_one(int resource, const char *val, rlim_t *ret) {
34,751✔
249
        assert(val);
34,751✔
250
        assert(ret);
34,751✔
251

252
        if (resource < 0)
34,751✔
253
                return -EINVAL;
254
        if (resource >= _RLIMIT_MAX)
34,751✔
255
                return -EINVAL;
256

257
        return rlimit_parse_table[resource](val, ret);
34,751✔
258
}
259

260
int rlimit_parse(int resource, const char *val, struct rlimit *ret) {
24,004✔
261
        _cleanup_free_ char *hard = NULL, *soft = NULL;
24,004✔
262
        rlim_t hl, sl;
24,004✔
263
        int r;
24,004✔
264

265
        assert(val);
24,004✔
266
        assert(ret);
24,004✔
267

268
        r = extract_first_word(&val, &soft, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
24,004✔
269
        if (r < 0)
24,004✔
270
                return r;
271
        if (r == 0)
24,004✔
272
                return -EINVAL;
273

274
        r = rlimit_parse_one(resource, soft, &sl);
24,004✔
275
        if (r < 0)
24,004✔
276
                return r;
277

278
        r = extract_first_word(&val, &hard, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
23,999✔
279
        if (r < 0)
23,999✔
280
                return r;
281
        if (!isempty(val))
48,003✔
282
                return -EINVAL;
283
        if (r == 0)
23,997✔
284
                hl = sl;
13,250✔
285
        else {
286
                r = rlimit_parse_one(resource, hard, &hl);
10,747✔
287
                if (r < 0)
10,747✔
288
                        return r;
289
                if (sl > hl)
10,746✔
290
                        return -EILSEQ;
291
        }
292

293
        *ret = (struct rlimit) {
23,994✔
294
                .rlim_cur = sl,
295
                .rlim_max = hl,
296
        };
297

298
        return 0;
23,994✔
299
}
300

301
int rlimit_format(const struct rlimit *rl, char **ret) {
11,774✔
302
        _cleanup_free_ char *s = NULL;
11,774✔
303
        int r;
11,774✔
304

305
        assert(rl);
11,774✔
306
        assert(ret);
11,774✔
307

308
        if (rl->rlim_cur >= RLIM_INFINITY && rl->rlim_max >= RLIM_INFINITY)
11,774✔
309
                r = free_and_strdup(&s, "infinity");
3,202✔
310
        else if (rl->rlim_cur >= RLIM_INFINITY)
8,572✔
311
                r = asprintf(&s, "infinity:" RLIM_FMT, rl->rlim_max);
1✔
312
        else if (rl->rlim_max >= RLIM_INFINITY)
8,571✔
313
                r = asprintf(&s, RLIM_FMT ":infinity", rl->rlim_cur);
918✔
314
        else if (rl->rlim_cur == rl->rlim_max)
7,653✔
315
                r = asprintf(&s, RLIM_FMT, rl->rlim_cur);
5,165✔
316
        else
317
                r = asprintf(&s, RLIM_FMT ":" RLIM_FMT, rl->rlim_cur, rl->rlim_max);
2,488✔
318
        if (r < 0)
11,774✔
319
                return -ENOMEM;
320

321
        *ret = TAKE_PTR(s);
11,774✔
322
        return 0;
11,774✔
323
}
324

325
static const char* const rlimit_table[_RLIMIT_MAX] = {
326
        [RLIMIT_AS]         = "AS",
327
        [RLIMIT_CORE]       = "CORE",
328
        [RLIMIT_CPU]        = "CPU",
329
        [RLIMIT_DATA]       = "DATA",
330
        [RLIMIT_FSIZE]      = "FSIZE",
331
        [RLIMIT_LOCKS]      = "LOCKS",
332
        [RLIMIT_MEMLOCK]    = "MEMLOCK",
333
        [RLIMIT_MSGQUEUE]   = "MSGQUEUE",
334
        [RLIMIT_NICE]       = "NICE",
335
        [RLIMIT_NOFILE]     = "NOFILE",
336
        [RLIMIT_NPROC]      = "NPROC",
337
        [RLIMIT_RSS]        = "RSS",
338
        [RLIMIT_RTPRIO]     = "RTPRIO",
339
        [RLIMIT_RTTIME]     = "RTTIME",
340
        [RLIMIT_SIGPENDING] = "SIGPENDING",
341
        [RLIMIT_STACK]      = "STACK",
342
};
343

344
DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
72,242✔
345

346
int rlimit_from_string_harder(const char *s) {
54✔
347
        const char *suffix;
54✔
348

349
        /* The official prefix */
350
        suffix = startswith(s, "RLIMIT_");
54✔
351
        if (suffix)
54✔
352
                return rlimit_from_string(suffix);
17✔
353

354
        /* Our own unit file setting prefix */
355
        suffix = startswith(s, "Limit");
37✔
356
        if (suffix)
37✔
357
                return rlimit_from_string(suffix);
17✔
358

359
        return rlimit_from_string(s);
20✔
360
}
361

362
void rlimit_free_all(struct rlimit **rl) {
61,164✔
363
        free_many((void**) rl, _RLIMIT_MAX);
61,164✔
364
}
61,164✔
365

366
int rlimit_copy_all(struct rlimit* target[static _RLIMIT_MAX], struct rlimit* const source[static _RLIMIT_MAX]) {
260✔
367
        struct rlimit* copy[_RLIMIT_MAX] = {};
260✔
368

369
        assert(target);
260✔
370
        assert(source);
260✔
371

372
        for (int i = 0; i < _RLIMIT_MAX; i++) {
4,420✔
373
                if (!source[i])
4,160✔
374
                        continue;
3,640✔
375

376
                copy[i] = newdup(struct rlimit, source[i], 1);
520✔
377
                if (!copy[i]) {
520✔
UNCOV
378
                        rlimit_free_all(copy);
×
UNCOV
379
                        return -ENOMEM;
×
380
                }
381
        }
382

383
        memcpy(target, copy, sizeof(struct rlimit*) * _RLIMIT_MAX);
260✔
384
        return 0;
260✔
385
}
386

387
int rlimit_nofile_bump(int limit) {
20,756✔
388
        int r;
20,756✔
389

390
        /* Bumps the (soft) RLIMIT_NOFILE resource limit as close as possible to the specified limit. If a negative
391
         * limit is specified, bumps it to the maximum the kernel and the hard resource limit allows. This call should
392
         * be used by all our programs that might need a lot of fds, and that know how to deal with high fd numbers
393
         * (i.e. do not use select() — which chokes on fds >= 1024) */
394

395
        if (limit < 0)
20,756✔
396
                limit = read_nr_open();
61✔
397

398
        if (limit < 3)
20,756✔
UNCOV
399
                limit = 3;
×
400

401
        r = setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(limit));
20,756✔
402
        if (r < 0)
20,756✔
UNCOV
403
                return log_debug_errno(r, "Failed to set RLIMIT_NOFILE: %m");
×
404

405
        return 0;
406
}
407

408
int rlimit_nofile_safe(void) {
18,774✔
409
        struct rlimit rl;
18,774✔
410

411
        /* Resets RLIMIT_NOFILE's soft limit FD_SETSIZE (i.e. 1024), for compatibility with software still using
412
         * select() */
413

414
        if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
18,774✔
UNCOV
415
                return log_debug_errno(errno, "Failed to query RLIMIT_NOFILE: %m");
×
416

417
        if (rl.rlim_cur <= FD_SETSIZE)
18,774✔
418
                return 0;
419

420
        /* So we might have inherited a hard limit that's larger than the kernel's maximum limit as stored in
421
         * /proc/sys/fs/nr_open. If we pass this hard limit unmodified to setrlimit(), we'll get EPERM. To
422
         * make sure that doesn't happen, let's limit our hard limit to the value from nr_open. */
423
        rl.rlim_max = MIN(rl.rlim_max, (rlim_t) read_nr_open());
16,882✔
424
        rl.rlim_cur = MIN((rlim_t) FD_SETSIZE, rl.rlim_max);
16,882✔
425
        if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
16,882✔
UNCOV
426
                return log_debug_errno(errno, "Failed to lower RLIMIT_NOFILE's soft limit to " RLIM_FMT ": %m", rl.rlim_cur);
×
427

428
        return 1;
429
}
430

431
int pid_getrlimit(pid_t pid, int resource, struct rlimit *ret) {
928✔
432

433
        static const char * const prefix_table[_RLIMIT_MAX] = {
928✔
434
                [RLIMIT_CPU]        = "Max cpu time",
435
                [RLIMIT_FSIZE]      = "Max file size",
436
                [RLIMIT_DATA]       = "Max data size",
437
                [RLIMIT_STACK]      = "Max stack size",
438
                [RLIMIT_CORE]       = "Max core file size",
439
                [RLIMIT_RSS]        = "Max resident set",
440
                [RLIMIT_NPROC]      = "Max processes",
441
                [RLIMIT_NOFILE]     = "Max open files",
442
                [RLIMIT_MEMLOCK]    = "Max locked memory",
443
                [RLIMIT_AS]         = "Max address space",
444
                [RLIMIT_LOCKS]      = "Max file locks",
445
                [RLIMIT_SIGPENDING] = "Max pending signals",
446
                [RLIMIT_MSGQUEUE]   = "Max msgqueue size",
447
                [RLIMIT_NICE]       = "Max nice priority",
448
                [RLIMIT_RTPRIO]     = "Max realtime priority",
449
                [RLIMIT_RTTIME]     = "Max realtime timeout",
450
        };
451

452
        int r;
928✔
453

454
        assert(resource >= 0);
928✔
455
        assert(resource < _RLIMIT_MAX);
928✔
456
        assert(pid >= 0);
928✔
457
        assert(ret);
928✔
458

459
        if (pid == 0 || pid == getpid_cached())
928✔
460
                return RET_NERRNO(getrlimit(resource, ret));
928✔
461

462
        r = RET_NERRNO(prlimit(pid, resource, /* new_limit= */ NULL, ret));
928✔
463
        if (!ERRNO_IS_NEG_PRIVILEGE(r))
40✔
464
                return r;
888✔
465

466
        /* We don't have access? Then try to go via /proc/$PID/limits. Weirdly that's world readable in
467
         * contrast to querying the data via prlimit() */
468

469
        const char *p = procfs_file_alloca(pid, "limits");
40✔
470
        _cleanup_free_ char *limits = NULL;
40✔
471

472
        r = read_full_file(p, &limits, /* ret_size = */ NULL);
40✔
473
        if (r < 0)
40✔
474
                return -EPERM; /* propagate original permission error if we can't access the limits file */
475

476
        _cleanup_strv_free_ char **l = NULL;
40✔
477
        l = strv_split_newlines(limits);
40✔
478
        if (!l)
40✔
479
                return -ENOMEM;
480

481
        STRV_FOREACH(i, strv_skip(l, 1)) {
364✔
482
                _cleanup_free_ char *soft = NULL, *hard = NULL;
364✔
483
                uint64_t sv, hv;
364✔
484
                const char *e;
364✔
485

486
                e = startswith(*i, prefix_table[resource]);
364✔
487
                if (!e)
364✔
488
                        continue;
324✔
489

490
                if (*e != ' ')
40✔
UNCOV
491
                        continue;
×
492

493
                e += strspn(e, WHITESPACE);
40✔
494

495
                size_t n;
40✔
496
                n = strcspn(e, WHITESPACE);
40✔
497
                if (n == 0)
40✔
UNCOV
498
                        continue;
×
499

500
                soft = strndup(e, n);
40✔
501
                if (!soft)
40✔
502
                        return -ENOMEM;
503

504
                e += n;
40✔
505
                if (*e != ' ')
40✔
UNCOV
506
                        continue;
×
507

508
                e += strspn(e, WHITESPACE);
40✔
509
                n = strcspn(e, WHITESPACE);
40✔
510
                if (n == 0)
40✔
UNCOV
511
                        continue;
×
512

513
                hard = strndup(e, n);
40✔
514
                if (!hard)
40✔
515
                        return -ENOMEM;
516

517
                if (streq(soft, "unlimited"))
40✔
518
                        sv = RLIM_INFINITY;
8✔
519
                else {
520
                        r = safe_atou64(soft, &sv);
32✔
521
                        if (r < 0)
32✔
522
                                return r;
523
                }
524

525
                if (streq(hard, "unlimited"))
40✔
526
                        hv = RLIM_INFINITY;
9✔
527
                else {
528
                        r = safe_atou64(hard, &hv);
31✔
529
                        if (r < 0)
31✔
530
                                return r;
531
                }
532

533
                *ret = (struct rlimit) {
40✔
534
                        .rlim_cur = sv,
535
                        .rlim_max = hv,
536
                };
537

538
                return 0;
40✔
539
        }
540

541
        return -ENOTRECOVERABLE;
542
}
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