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

systemd / systemd / 26546993077

27 May 2026 08:34PM UTC coverage: 72.995% (+0.3%) from 72.667%
26546993077

push

github

bluca
test-pressure: set timeout to make not wait forever

If this runs on a slow or busy machine, then we may not get enough
pressure to trigger the event sources. In such case, the test does not
finish. It is problematic when the test is _not_ run with 'meson test',
e.g. debian/ubuntu CIs.

Let's introduce a timeout for each event loop, and skip test cases
gracefully.

8 of 12 new or added lines in 1 file covered. (66.67%)

19671 existing lines in 226 files now uncovered.

337119 of 461841 relevant lines covered (72.99%)

1326365.62 hits per line

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

84.77
/src/basic/log.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <fcntl.h>
4
#include <sys/signalfd.h>
5
#include <sys/stat.h>
6
#include <sys/uio.h>
7
#include <threads.h>
8
#include <unistd.h>
9

10
#include "sd-messages.h"
11

12
#include "alloc-util.h"
13
#include "ansi-color.h"
14
#include "argv-util.h"
15
#include "env-util.h"
16
#include "errno-util.h"
17
#include "extract-word.h"
18
#include "fd-util.h"
19
#include "format-util.h"
20
#include "iovec-util.h"
21
#include "list.h"
22
#include "log.h"
23
#include "log-context.h"
24
#include "parse-util.h"
25
#include "proc-cmdline.h"
26
#include "process-util.h"
27
#include "ratelimit.h"
28
#include "signal-util.h"
29
#include "socket-util.h"
30
#include "stdio-util.h"
31
#include "string-table.h"
32
#include "string-util.h"
33
#include "strv.h"
34
#include "syslog-util.h"
35
#include "terminal-util.h"
36
#include "time-util.h"
37
#include "utf8.h"
38

39
#define SNDBUF_SIZE (8*1024*1024)
40
#define IOVEC_MAX 256U
41

42
static log_syntax_callback_t log_syntax_callback = NULL;
43
static void *log_syntax_callback_userdata = NULL;
44

45
static LogTarget log_target = LOG_TARGET_CONSOLE;
46
static int log_max_level = LOG_INFO;
47
static int log_target_max_level[_LOG_TARGET_SINGLE_MAX] = {
48
        [LOG_TARGET_CONSOLE] = INT_MAX,
49
        [LOG_TARGET_KMSG]    = INT_MAX,
50
        [LOG_TARGET_SYSLOG]  = INT_MAX,
51
        [LOG_TARGET_JOURNAL] = INT_MAX,
52
};
53
static int log_facility = LOG_DAEMON;
54
static bool ratelimit_kmsg = true;
55

56
static int console_fd = STDERR_FILENO;
57
static int console_fd_is_tty = -1; /* tri-state: -1 means don't know */
58
static int syslog_fd = -EBADF;
59
static int kmsg_fd = -EBADF;
60
static int journal_fd = -EBADF;
61

62
static bool syslog_is_stream = false;
63

64
static int show_color = -1; /* tristate */
65
static bool show_location = false;
66
static bool show_time = false;
67
static bool show_tid = false;
68

69
static bool upgrade_syslog_to_journal = false;
70
static bool always_reopen_console = false;
71
static bool open_when_needed = false;
72
static bool prohibit_ipc = false;
73

74
static thread_local const char *log_prefix = NULL;
75

76
#if LOG_MESSAGE_VERIFICATION || defined(__COVERITY__)
77
bool _log_message_dummy = false; /* Always false */
78
#endif
79

80
/* An assert to use in logging functions that does not call recursively
81
 * into our logging functions (since that might lead to a loop). */
82
#define assert_raw(expr)                                                \
83
        do {                                                            \
84
                if (_unlikely_(!(expr))) {                              \
85
                        fputs(#expr "\n", stderr);                      \
86
                        abort();                                        \
87
                }                                                       \
88
        } while (false)
89

90
void log_prefix_swap(const char **prefix) {
1,128✔
91
        assert(prefix);
1,128✔
92

93
        SWAP_TWO(log_prefix, *prefix);
1,128✔
94
}
1,128✔
95

96
static void log_close_console(void) {
407,068✔
97
        /* See comment in log_close_journal() */
98
        (void) safe_close_above_stdio(TAKE_FD(console_fd));
407,068✔
99
        console_fd_is_tty = -1;
407,068✔
100
}
407,068✔
101

102
static int log_open_console(void) {
78,951✔
103

104
        if (!always_reopen_console) {
78,951✔
105
                console_fd = STDERR_FILENO;
70,889✔
106
                console_fd_is_tty = -1;
70,889✔
107
                return 0;
70,889✔
108
        }
109

110
        if (console_fd < 3) {
8,062✔
111
                int fd;
5,967✔
112

113
                fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
5,967✔
114
                if (fd < 0)
5,967✔
115
                        return fd;
116

117
                console_fd = fd_move_above_stdio(fd);
5,869✔
118
                console_fd_is_tty = true;
5,869✔
119
        }
120

121
        return 0;
122
}
123

124
static void log_close_kmsg(void) {
205,265✔
125
        /* See comment in log_close_journal() */
126
        (void) safe_close(TAKE_FD(kmsg_fd));
205,265✔
127
}
205,265✔
128

129
static int log_open_kmsg(void) {
17,572✔
130

131
        if (kmsg_fd >= 0)
17,572✔
132
                return 0;
133

134
        kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
14,807✔
135
        if (kmsg_fd < 0)
14,807✔
136
                return -errno;
6,565✔
137

138
        kmsg_fd = fd_move_above_stdio(kmsg_fd);
8,242✔
139
        return 0;
8,242✔
140
}
141

142
static void log_close_syslog(void) {
486,017✔
143
        /* See comment in log_close_journal() */
144
        (void) safe_close(TAKE_FD(syslog_fd));
486,017✔
145
}
486,017✔
146

147
static int create_log_socket(int type) {
185,361✔
148
        struct timeval tv;
185,361✔
149
        int fd;
185,361✔
150

151
        fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
185,361✔
152
        if (fd < 0)
185,361✔
UNCOV
153
                return -errno;
×
154

155
        fd = fd_move_above_stdio(fd);
185,361✔
156
        (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
185,361✔
157

158
        /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
159
         * in the unlikely case of a deadlock. */
160
        if (getpid_cached() == 1)
185,361✔
161
                timeval_store(&tv, 10 * USEC_PER_MSEC);
294✔
162
        else
163
                timeval_store(&tv, 10 * USEC_PER_SEC);
185,067✔
164
        (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
185,361✔
165

166
        return fd;
185,361✔
167
}
168

169
static int log_open_syslog(void) {
2✔
170
        int r;
2✔
171

172
        if (syslog_fd >= 0)
2✔
173
                return 0;
174

175
        syslog_fd = create_log_socket(SOCK_DGRAM);
2✔
176
        if (syslog_fd < 0) {
2✔
177
                r = syslog_fd;
×
UNCOV
178
                goto fail;
×
179
        }
180

181
        r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log");
2✔
182
        if (r < 0) {
2✔
183
                safe_close(syslog_fd);
×
184

185
                /* Some legacy syslog systems still use stream sockets. They really shouldn't. But what can
186
                 * we do... */
187
                syslog_fd = create_log_socket(SOCK_STREAM);
×
188
                if (syslog_fd < 0) {
×
189
                        r = syslog_fd;
×
UNCOV
190
                        goto fail;
×
191
                }
192

UNCOV
193
                r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log");
×
UNCOV
194
                if (r < 0)
×
UNCOV
195
                        goto fail;
×
196

197
                syslog_is_stream = true;
×
198
        } else
199
                syslog_is_stream = false;
2✔
200

201
        return 0;
202

UNCOV
203
fail:
×
UNCOV
204
        log_close_syslog();
×
UNCOV
205
        return r;
×
206
}
207

208
static void log_close_journal(void) {
295,062✔
209
        /* If the journal FD is bad, safe_close will fail, and will try to log, which will fail, so we'll
210
         * try to close the journal FD, which is bad, so safe_close will fail... Whether we can close it
211
         * or not, invalidate it immediately so that we don't get in a recursive loop until we run out of
212
         * stack. */
213
        (void) safe_close(TAKE_FD(journal_fd));
295,062✔
214
}
295,062✔
215

216
static int log_open_journal(void) {
201,775✔
217
        int r;
201,775✔
218

219
        if (journal_fd >= 0)
201,775✔
220
                return 0;
221

222
        journal_fd = create_log_socket(SOCK_DGRAM);
185,359✔
223
        if (journal_fd < 0) {
185,359✔
UNCOV
224
                r = journal_fd;
×
UNCOV
225
                goto fail;
×
226
        }
227

228
        r = connect_unix_path(journal_fd, AT_FDCWD, "/run/systemd/journal/socket");
185,359✔
229
        if (r < 0)
185,359✔
230
                goto fail;
95✔
231

232
        return 0;
233

234
fail:
95✔
235
        log_close_journal();
95✔
236
        return r;
95✔
237
}
238

239
bool stderr_is_journal(void) {
268,394✔
240
        _cleanup_free_ char *w = NULL;
268,394✔
241
        const char *e;
268,394✔
242
        uint64_t dev, ino;
268,394✔
243
        struct stat st;
268,394✔
244

245
        e = getenv("JOURNAL_STREAM");
268,394✔
246
        if (!e)
268,394✔
247
                return false;
248

249
        if (extract_first_word(&e, &w, ":", EXTRACT_DONT_COALESCE_SEPARATORS) <= 0)
32,516✔
250
                return false;
251
        if (!e)
32,516✔
252
                return false;
253

254
        if (safe_atou64(w, &dev) < 0)
32,516✔
255
                return false;
256
        if (safe_atou64(e, &ino) < 0)
32,516✔
257
                return false;
258

259
        if (fstat(STDERR_FILENO, &st) < 0)
32,516✔
260
                return false;
261

262
        return st.st_dev == dev && st.st_ino == ino;
36,842✔
263
}
264

265
int log_open(void) {
280,754✔
266
        int r;
280,754✔
267

268
        /* Do not call from library code. */
269

270
        /* This function is often called in preparation for logging. Let's make sure we don't clobber errno,
271
         * so that a call to a logging function immediately following a log_open() call can still easily
272
         * reference an error that happened immediately before the log_open() call. */
273
        PROTECT_ERRNO;
280,754✔
274

275
        /* If we don't use the console, we close it here to not get killed by SAK. If we don't use syslog, we
276
         * close it here too, so that we are not confused by somebody deleting the socket in the fs, and to
277
         * make sure we don't use it if prohibit_ipc is set. If we don't use /dev/kmsg we still keep it open,
278
         * because there is no reason to close it. */
279

280
        if (log_target == LOG_TARGET_NULL) {
280,754✔
281
                log_close_journal();
1✔
282
                log_close_syslog();
1✔
283
                log_close_console();
1✔
284
                return 0;
285
        }
286

287
        if (getpid_cached() == 1 ||
540,049✔
288
            stderr_is_journal() ||
259,296✔
289
            IN_SET(log_target,
239,879✔
290
                   LOG_TARGET_KMSG,
291
                   LOG_TARGET_JOURNAL,
292
                   LOG_TARGET_JOURNAL_OR_KMSG,
293
                   LOG_TARGET_SYSLOG,
294
                   LOG_TARGET_SYSLOG_OR_KMSG)) {
295

296
                if (!prohibit_ipc) {
210,585✔
297
                        if (IN_SET(log_target,
205,013✔
298
                                   LOG_TARGET_AUTO,
299
                                   LOG_TARGET_JOURNAL_OR_KMSG,
300
                                   LOG_TARGET_JOURNAL)) {
301

302
                                r = log_open_journal();
191,143✔
303
                                if (r >= 0) {
191,143✔
304
                                        log_close_syslog();
191,061✔
305
                                        log_close_console();
191,061✔
306
                                        return r;
307
                                }
308
                        }
309

310
                        if (IN_SET(log_target,
13,952✔
311
                                   LOG_TARGET_SYSLOG_OR_KMSG,
312
                                   LOG_TARGET_SYSLOG)) {
313

314
                                r = log_open_syslog();
2✔
315
                                if (r >= 0) {
2✔
316
                                        log_close_journal();
2✔
317
                                        log_close_console();
2✔
318
                                        return r;
319
                                }
320
                        }
321
                }
322

323
                if (IN_SET(log_target, LOG_TARGET_AUTO,
19,522✔
324
                                       LOG_TARGET_JOURNAL_OR_KMSG,
325
                                       LOG_TARGET_SYSLOG_OR_KMSG,
326
                                       LOG_TARGET_KMSG)) {
327
                        r = log_open_kmsg();
17,299✔
328
                        if (r >= 0) {
17,299✔
329
                                log_close_journal();
10,739✔
330
                                log_close_syslog();
10,739✔
331
                                log_close_console();
10,739✔
332
                                return r;
333
                        }
334
                }
335
        }
336

337
        log_close_journal();
78,951✔
338
        log_close_syslog();
78,951✔
339

340
        return log_open_console();
78,951✔
341
}
342

343
void log_set_target(LogTarget target) {
105,303✔
344
        assert(target >= 0);
105,303✔
345
        assert(target < _LOG_TARGET_MAX);
105,303✔
346

347
        if (upgrade_syslog_to_journal) {
105,303✔
348
                if (target == LOG_TARGET_SYSLOG)
355✔
349
                        target = LOG_TARGET_JOURNAL;
350
                else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
355✔
UNCOV
351
                        target = LOG_TARGET_JOURNAL_OR_KMSG;
×
352
        }
353

354
        log_target = target;
105,303✔
355
}
105,303✔
356

357
void log_set_target_and_open(LogTarget target) {
323✔
358
        log_set_target(target);
323✔
359
        log_open();
323✔
360
}
323✔
361

362
void log_close(void) {
205,265✔
363
        /* Do not call from library code. */
364

365
        log_close_journal();
205,265✔
366
        log_close_syslog();
205,265✔
367
        log_close_kmsg();
205,265✔
368
        log_close_console();
205,265✔
369
}
205,265✔
370

371
void log_forget_fds(void) {
12,286✔
372
        /* Do not call from library code. */
373

374
        console_fd = kmsg_fd = syslog_fd = journal_fd = -EBADF;
12,286✔
375
        console_fd_is_tty = -1;
12,286✔
376
}
12,286✔
377

378
int log_set_max_level(int level) {
1,056,700✔
379
        assert(level == LOG_NULL || log_level_is_valid(level));
1,056,700✔
380

381
        int old = log_max_level;
1,056,700✔
382
        log_max_level = level;
1,056,700✔
383

384
        /* Also propagate max log level to libc's syslog(), just in case some other component loaded into our
385
         * process logs directly via syslog(). You might wonder why we maintain our own log level variable if
386
         * libc has the same functionality. This has multiple reasons, first and foremost that we want to
387
         * apply this to all our log targets, not just syslog and console. Moreover, we cannot query the
388
         * current log mask from glibc without changing it, but that's useful for testing the current log
389
         * level before even entering the log functions like we do in our macros. */
390
        setlogmask(LOG_UPTO(level));
1,056,700✔
391

392
        /* Ensure that our own LOG_NULL define maps sanely to the log mask */
393
        assert_cc(LOG_UPTO(LOG_NULL) == 0);
1,056,700✔
394

395
        return old;
1,056,700✔
396
}
397

398
void log_set_facility(int facility) {
196✔
399
        log_facility = facility;
196✔
400
}
196✔
401

402
static bool check_console_fd_is_tty(void) {
215,470✔
403
        if (console_fd < 0)
215,470✔
404
                return false;
405

406
        if (console_fd_is_tty < 0)
215,470✔
407
                console_fd_is_tty = isatty_safe(console_fd);
13,563✔
408

409
        return console_fd_is_tty;
215,470✔
410
}
411

412
static int write_to_console(
338,888✔
413
                int level,
414
                int error,
415
                const char *file,
416
                int line,
417
                const char *func,
418
                const char *buffer) {
419

420
        static int dumb = -1;
338,888✔
421

422
        char location[256],
338,888✔
423
             header_time[FORMAT_TIMESTAMP_MAX],
424
             prefix[1 + DECIMAL_STR_MAX(int) + 2],
425
             tid_string[3 + DECIMAL_STR_MAX(pid_t) + 1];
426
        struct iovec iovec[11];
338,888✔
427
        const char *on = NULL, *off = NULL;
338,888✔
428
        size_t n = 0;
338,888✔
429

430
        if (console_fd < 0)
338,888✔
431
                return 0;
338,888✔
432

433
        if (dumb < 0)
338,125✔
434
                dumb = getenv_terminal_is_dumb();
14,349✔
435

436
        if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_CONSOLE])
338,125✔
437
                return 0;
438

439
        if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
215,470✔
440
                xsprintf(prefix, "<%i>", level);
381✔
441
                iovec[n++] = IOVEC_MAKE_STRING(prefix);
381✔
442
        }
443

444
        if (show_time &&
215,470✔
445
            format_timestamp(header_time, sizeof(header_time), now(CLOCK_REALTIME))) {
×
446
                iovec[n++] = IOVEC_MAKE_STRING(header_time);
×
UNCOV
447
                iovec[n++] = IOVEC_MAKE_STRING(" ");
×
448
        }
449

450
        if (show_tid) {
215,470✔
UNCOV
451
                xsprintf(tid_string, "(" PID_FMT ") ", gettid());
×
UNCOV
452
                iovec[n++] = IOVEC_MAKE_STRING(tid_string);
×
453
        }
454

455
        if (log_get_show_color())
215,470✔
456
                get_log_colors(LOG_PRI(level), &on, &off, NULL);
207,415✔
457

458
        if (show_location) {
215,470✔
459
                const char *lon = "", *loff = "";
×
460
                if (log_get_show_color()) {
×
UNCOV
461
                        lon = ansi_highlight_yellow4();
×
UNCOV
462
                        loff = ansi_normal();
×
463
                }
464

UNCOV
465
                (void) snprintf(location, sizeof location, "%s%s:%i%s: ", lon, file, line, loff);
×
UNCOV
466
                iovec[n++] = IOVEC_MAKE_STRING(location);
×
467
        }
468

469
        if (on)
215,470✔
470
                iovec[n++] = IOVEC_MAKE_STRING(on);
191,188✔
471
        if (log_prefix) {
215,470✔
472
                iovec[n++] = IOVEC_MAKE_STRING(log_prefix);
8,957✔
473
                iovec[n++] = IOVEC_MAKE_STRING(": ");
8,957✔
474
        }
475
        iovec[n++] = IOVEC_MAKE_STRING(buffer);
215,470✔
476
        if (off)
215,470✔
477
                iovec[n++] = IOVEC_MAKE_STRING(off);
191,188✔
478

479
        /* When writing to a TTY we output an extra '\r' (i.e. CR) first, to generate CRNL rather than just
480
         * NL. This is a robustness thing in case the TTY is currently in raw mode (specifically: has the
481
         * ONLCR flag off). We want that subsequent output definitely starts at the beginning of the line
482
         * again, after all. If the TTY is not in raw mode the extra CR should not hurt. If we're writing to
483
         * a dumb terminal, only write NL as CRNL might be interpreted as a double newline. */
484
        iovec[n++] = IOVEC_MAKE_STRING(check_console_fd_is_tty() && !dumb ? "\r\n" : "\n");
430,940✔
485

486
        if (writev(console_fd, iovec, n) < 0) {
215,470✔
487

488
                if (errno == EIO && getpid_cached() == 1) {
×
489

490
                        /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try
491
                         * to reconnect. */
492

493
                        log_close_console();
×
UNCOV
494
                        (void) log_open_console();
×
495
                        if (console_fd < 0)
×
496
                                return 0;
497

UNCOV
498
                        if (writev(console_fd, iovec, n) < 0)
×
UNCOV
499
                                return -errno;
×
500
                } else
UNCOV
501
                        return -errno;
×
502
        }
503

504
        return 1;
505
}
506

507
static int write_to_syslog(
180✔
508
                int level,
509
                int error,
510
                const char *file,
511
                int line,
512
                const char *func,
513
                const char *buffer) {
514

515
        char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
180✔
516
             header_time[64],
517
             header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
518
        struct tm tm;
180✔
519
        int r;
180✔
520

521
        if (syslog_fd < 0)
180✔
522
                return 0;
180✔
523

524
        if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_SYSLOG])
180✔
525
                return 0;
526

527
        xsprintf(header_priority, "<%i>", level);
180✔
528

529
        r = localtime_or_gmtime_usec(now(CLOCK_REALTIME), /* utc= */ false, &tm);
180✔
530
        if (r < 0)
180✔
531
                return r;
532

533
        if (strftime(header_time, sizeof(header_time), "%h %e %T ", &tm) <= 0)
180✔
534
                return -EINVAL;
535

536
        xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
180✔
537

538
        struct iovec iovec[] = {
1,440✔
539
                IOVEC_MAKE_STRING(header_priority),
180✔
540
                IOVEC_MAKE_STRING(header_time),
180✔
541
                IOVEC_MAKE_STRING(program_invocation_short_name),
180✔
542
                IOVEC_MAKE_STRING(header_pid),
180✔
543
                IOVEC_MAKE_STRING(strempty(log_prefix)),
292✔
544
                IOVEC_MAKE_STRING(log_prefix ? ": " : ""),
292✔
545
                IOVEC_MAKE_STRING(buffer),
180✔
546
        };
547
        const struct msghdr msghdr = {
180✔
548
                .msg_iov = iovec,
549
                .msg_iovlen = ELEMENTSOF(iovec),
550
        };
551

552
        /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
553
        if (syslog_is_stream)
180✔
UNCOV
554
                iovec[ELEMENTSOF(iovec) - 1].iov_len++;
×
555

556
        for (;;) {
180✔
557
                ssize_t n;
180✔
558

559
                n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
180✔
560
                if (n < 0)
180✔
UNCOV
561
                        return -errno;
×
562

563
                if (!syslog_is_stream)
180✔
564
                        break;
565

UNCOV
566
                if (iovec_inc_many(iovec, ELEMENTSOF(iovec), n))
×
567
                        break;
568
        }
569

570
        return 1;
571
}
572

573
static int write_to_kmsg(
294,554✔
574
                int level,
575
                int error,
576
                const char *file,
577
                int line,
578
                const char *func,
579
                const char *buffer) {
580

581
        /* Set a ratelimit on the amount of messages logged to /dev/kmsg. This is mostly supposed to be a
582
         * safety catch for the case where start indiscriminately logging in a loop. It will not catch cases
583
         * where we log excessively, but not in a tight loop.
584
         *
585
         * Note that this ratelimit is per-emitter, so we might still overwhelm /dev/kmsg with multiple
586
         * loggers.
587
         */
588
        static thread_local RateLimit ratelimit = { 5 * USEC_PER_SEC, 200 };
294,554✔
589

590
        char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
294,554✔
591
             header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
592

593
        if (kmsg_fd < 0)
294,554✔
594
                return 0;
294,554✔
595

596
        if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_KMSG])
60,914✔
597
                return 0;
598

599
        if (ratelimit_kmsg && !ratelimit_below(&ratelimit)) {
60,914✔
UNCOV
600
                if (ratelimit_num_dropped(&ratelimit) > 1)
×
601
                        return 0;
602

603
                buffer = "Too many messages being logged to kmsg, ignoring";
604
        }
605

606
        xsprintf(header_priority, "<%i>", level);
60,914✔
607
        xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
60,914✔
608

609
        const struct iovec iovec[] = {
487,312✔
610
                IOVEC_MAKE_STRING(header_priority),
60,914✔
611
                IOVEC_MAKE_STRING(program_invocation_short_name),
60,914✔
612
                IOVEC_MAKE_STRING(header_pid),
60,914✔
613
                IOVEC_MAKE_STRING(strempty(log_prefix)),
94,500✔
614
                IOVEC_MAKE_STRING(log_prefix ? ": " : ""),
94,500✔
615
                IOVEC_MAKE_STRING(buffer),
60,914✔
616
                IOVEC_MAKE_STRING("\n"),
60,914✔
617
        };
618

619
        if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
60,914✔
UNCOV
620
                return -errno;
×
621

622
        return 1;
623
}
624

625
static int log_do_header(
6,459,610✔
626
                char *header,
627
                size_t size,
628
                int level,
629
                int error,
630
                const char *file, int line, const char *func,
631
                const char *object_field, const char *object,
632
                const char *extra_field, const char *extra) {
633
        int r;
6,459,610✔
634

635
        error = IS_SYNTHETIC_ERRNO(error) ? 0 : ERRNO_VALUE(error);
6,459,610✔
636

637
        r = snprintf(header, size,
6,459,610✔
638
                     "PRIORITY=%i\n"
639
                     "SYSLOG_FACILITY=%i\n"
640
                     "TID=" PID_FMT "\n"
641
                     "%s%.256s%s"        /* CODE_FILE */
642
                     "%s%.*i%s"          /* CODE_LINE */
643
                     "%s%.256s%s"        /* CODE_FUNC */
644
                     "%s%.*i%s"          /* ERRNO */
645
                     "%s%.256s%s"        /* object */
646
                     "%s%.256s%s"        /* extra */
647
                     "SYSLOG_IDENTIFIER=%.256s\n",
648
                     LOG_PRI(level),
649
                     LOG_FAC(level),
6,459,610✔
650
                     gettid(),
651
                     isempty(file) ? "" : "CODE_FILE=",
6,459,610✔
652
                     isempty(file) ? "" : file,
6,459,610✔
653
                     isempty(file) ? "" : "\n",
6,459,610✔
654
                     line ? "CODE_LINE=" : "",
655
                     line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
656
                     line ? "\n" : "",
657
                     isempty(func) ? "" : "CODE_FUNC=",
6,459,610✔
658
                     isempty(func) ? "" : func,
6,459,610✔
659
                     isempty(func) ? "" : "\n",
6,459,610✔
660
                     error ? "ERRNO=" : "",
661
                     error ? 1 : 0, error,
662
                     error ? "\n" : "",
663
                     isempty(object) ? "" : ASSERT_PTR(object_field),
6,459,610✔
664
                     isempty(object) ? "" : object,
6,459,610✔
665
                     isempty(object) ? "" : "\n",
6,459,610✔
666
                     isempty(extra) ? "" : ASSERT_PTR(extra_field),
6,459,610✔
667
                     isempty(extra) ? "" : extra,
6,459,610✔
668
                     isempty(extra) ? "" : "\n",
6,459,610✔
669
                     program_invocation_short_name);
670
        assert_raw((size_t) r < size);
6,459,610✔
671

672
        return 0;
6,459,610✔
673
}
674

675
static void log_do_context(struct iovec *iovec, size_t iovec_len, size_t *n) {
6,459,610✔
676
        assert(iovec);
6,459,610✔
677
        assert(n);
6,459,610✔
678

679
        LIST_FOREACH(ll, c, log_context_head()) {
9,038,929✔
680
                STRV_FOREACH(s, c->fields) {
22,962,427✔
681
                        if (*n + 2 >= iovec_len)
20,231,898✔
UNCOV
682
                                return;
×
683

684
                        iovec[(*n)++] = IOVEC_MAKE_STRING(*s);
20,231,898✔
685
                        iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
20,231,898✔
686
                }
687

688
                for (size_t i = 0; i < c->n_input_iovec; i++) {
2,755,395✔
689
                        if (*n + 2 >= iovec_len)
24,939✔
690
                                return;
73✔
691

692
                        iovec[(*n)++] = c->input_iovec[i];
24,866✔
693
                        iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
24,866✔
694
                }
695

696
                if (c->key && c->value) {
2,730,456✔
697
                        if (*n + 3 >= iovec_len)
341,633✔
698
                                return;
151,137✔
699

700
                        iovec[(*n)++] = IOVEC_MAKE_STRING(c->key);
190,496✔
701
                        iovec[(*n)++] = IOVEC_MAKE_STRING(c->value);
190,496✔
702
                        iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
190,496✔
703
                }
704
        }
705
}
706

707
static int write_to_journal(
6,724,295✔
708
                int level,
709
                int error,
710
                const char *file,
711
                int line,
712
                const char *func,
713
                const char *object_field,
714
                const char *object,
715
                const char *extra_field,
716
                const char *extra,
717
                const char *buffer) {
718

719
        char header[LINE_MAX];
6,724,295✔
720
        size_t n = 0, iovec_len;
6,724,295✔
721
        struct iovec *iovec;
6,724,295✔
722

723
        if (journal_fd < 0)
6,724,295✔
724
                return 0;
6,724,295✔
725

726
        if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_JOURNAL])
6,377,846✔
727
                return 0;
728

729
        iovec_len = MIN(6 + log_context_num_fields() * 3, IOVEC_MAX);
6,377,846✔
730
        iovec = newa(struct iovec, iovec_len);
6,377,846✔
731

732
        log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
6,377,846✔
733

734
        iovec[n++] = IOVEC_MAKE_STRING(header);
6,377,846✔
735
        iovec[n++] = IOVEC_MAKE_STRING("MESSAGE=");
6,377,846✔
736
        if (log_prefix) {
6,377,846✔
737
                iovec[n++] = IOVEC_MAKE_STRING(log_prefix);
1,853,186✔
738
                iovec[n++] = IOVEC_MAKE_STRING(": ");
1,853,186✔
739
        }
740
        iovec[n++] = IOVEC_MAKE_STRING(buffer);
6,377,846✔
741
        iovec[n++] = IOVEC_MAKE_STRING("\n");
6,377,846✔
742

743
        log_do_context(iovec, iovec_len, &n);
6,377,846✔
744

745
        const struct msghdr msghdr = {
6,377,846✔
746
                .msg_iov = iovec,
747
                .msg_iovlen = n,
748
        };
749

750
        if (sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL) < 0)
6,377,846✔
751
                return -errno;
804✔
752

753
        return 1;
754
}
755

756
int log_dispatch_internal(
6,763,354✔
757
                int level,
758
                int error,
759
                const char *file,
760
                int line,
761
                const char *func,
762
                const char *object_field,
763
                const char *object,
764
                const char *extra_field,
765
                const char *extra,
766
                char *buffer) {
767

768
        assert_raw(buffer);
6,763,354✔
769

770
        if (log_target == LOG_TARGET_NULL)
6,763,354✔
771
                return -ERRNO_VALUE(error);
37✔
772

773
        /* Patch in LOG_DAEMON facility if necessary */
774
        if (LOG_FAC(level) == 0)
6,763,317✔
775
                level |= log_facility;
6,751,219✔
776

777
        if (open_when_needed)
6,763,317✔
778
                (void) log_open();
157,926✔
779

780
        do {
6,815,498✔
781
                char *e;
6,815,498✔
782
                int k = 0;
6,815,498✔
783

784
                buffer += strspn(buffer, NEWLINE);
6,815,498✔
785

786
                if (buffer[0] == 0)
6,815,498✔
787
                        break;
788

789
                if ((e = strpbrk(buffer, NEWLINE)))
6,777,024✔
790
                        *(e++) = 0;
52,181✔
791

792
                if (IN_SET(log_target, LOG_TARGET_AUTO,
6,777,024✔
793
                                       LOG_TARGET_JOURNAL_OR_KMSG,
794
                                       LOG_TARGET_JOURNAL)) {
795

796
                        k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
6,724,295✔
797
                        if (k < 0 && k != -EAGAIN)
6,724,295✔
798
                                log_close_journal();
9✔
799
                }
800

801
                if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
6,777,024✔
802
                                       LOG_TARGET_SYSLOG)) {
803

804
                        k = write_to_syslog(level, error, file, line, func, buffer);
180✔
805
                        if (k < 0 && k != -EAGAIN)
180✔
UNCOV
806
                                log_close_syslog();
×
807
                }
808

809
                if (k <= 0 &&
6,777,024✔
810
                    IN_SET(log_target, LOG_TARGET_AUTO,
399,802✔
811
                                       LOG_TARGET_SYSLOG_OR_KMSG,
812
                                       LOG_TARGET_JOURNAL_OR_KMSG,
813
                                       LOG_TARGET_KMSG)) {
814

815
                        if (k < 0)
294,554✔
816
                                log_open_kmsg();
273✔
817

818
                        k = write_to_kmsg(level, error, file, line, func, buffer);
294,554✔
819
                        if (k < 0) {
294,554✔
UNCOV
820
                                log_close_kmsg();
×
UNCOV
821
                                (void) log_open_console();
×
822
                        }
823
                }
824

825
                if (k <= 0)
399,802✔
826
                        (void) write_to_console(level, error, file, line, func, buffer);
338,888✔
827

828
                buffer = e;
6,777,024✔
829
        } while (buffer);
6,777,024✔
830

831
        if (open_when_needed)
6,763,317✔
832
                log_close();
157,926✔
833

834
        return -ERRNO_VALUE(error);
6,763,317✔
835
}
836

837
int log_dump_internal(
9✔
838
                int level,
839
                int error,
840
                const char *file,
841
                int line,
842
                const char *func,
843
                char *buffer) {
844

845
        PROTECT_ERRNO;
9✔
846

847
        /* This modifies the buffer... */
848

849
        if (_likely_(LOG_PRI(level) > log_max_level))
9✔
UNCOV
850
                return -ERRNO_VALUE(error);
×
851

852
        return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
9✔
853
}
854

855
int log_internalv(
4,991,077✔
856
                int level,
857
                int error,
858
                const char *file,
859
                int line,
860
                const char *func,
861
                const char *format,
862
                va_list ap) {
863

864
        if (_likely_(LOG_PRI(level) > log_max_level))
4,991,077✔
865
                return -ERRNO_VALUE(error);
4,991,077✔
866

867
        /* Make sure that %m maps to the specified error (or "Success"). */
868
        char buffer[LINE_MAX];
4,991,077✔
869
        LOCAL_ERRNO(ERRNO_VALUE(error));
4,991,077✔
870

871
        (void) vsnprintf(buffer, sizeof buffer, format, ap);
4,991,077✔
872

873
        return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
4,991,077✔
874
}
875

876
int log_internal(
4,989,262✔
877
                int level,
878
                int error,
879
                const char *file,
880
                int line,
881
                const char *func,
882
                const char *format, ...) {
883

884
        va_list ap;
4,989,262✔
885
        int r;
4,989,262✔
886

887
        va_start(ap, format);
4,989,262✔
888
        r = log_internalv(level, error, file, line, func, format, ap);
4,989,262✔
889
        va_end(ap);
4,989,262✔
890

891
        return r;
4,989,262✔
892
}
893

894
int log_object_internalv(
1,806,478✔
895
                int level,
896
                int error,
897
                const char *file,
898
                int line,
899
                const char *func,
900
                const char *object_field,
901
                const char *object,
902
                const char *extra_field,
903
                const char *extra,
904
                const char *format,
905
                va_list ap) {
906

907
        char *buffer, *b;
1,806,478✔
908

909
        if (_likely_(LOG_PRI(level) > log_max_level))
1,806,478✔
910
                return -ERRNO_VALUE(error);
1,806,478✔
911

912
        /* Make sure that %m maps to the specified error (or "Success"). */
UNCOV
913
        LOCAL_ERRNO(ERRNO_VALUE(error));
×
914

915
        LOG_SET_PREFIX(object);
3,520,752✔
916

917
        b = buffer = newa(char, LINE_MAX);
1,760,376✔
918
        (void) vsnprintf(b, LINE_MAX, format, ap);
1,760,376✔
919

920
        return log_dispatch_internal(level, error, file, line, func,
1,760,376✔
921
                                     object_field, object, extra_field, extra, buffer);
922
}
923

924
int log_object_internal(
1,800,122✔
925
                int level,
926
                int error,
927
                const char *file,
928
                int line,
929
                const char *func,
930
                const char *object_field,
931
                const char *object,
932
                const char *extra_field,
933
                const char *extra,
934
                const char *format, ...) {
935

936
        va_list ap;
1,800,122✔
937
        int r;
1,800,122✔
938

939
        va_start(ap, format);
1,800,122✔
940
        r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
1,800,122✔
941
        va_end(ap);
1,800,122✔
942

943
        return r;
1,800,122✔
944
}
945

UNCOV
946
int log_oom_internal(int level, const char *file, int line, const char *func) {
×
UNCOV
947
        return log_internal(level, ENOMEM, file, line, func, "Out of memory.");
×
948
}
949

950
int log_format_iovec(
78,618✔
951
                struct iovec *iovec,
952
                size_t iovec_len,
953
                size_t *n,
954
                bool newline_separator,
955
                int error,
956
                const char *format,
957
                va_list ap) {
958

959
        assert(iovec);
78,618✔
960
        assert(n);
78,618✔
961

962
        while (format && *n + 1 < iovec_len) {
468,328✔
963
                va_list aq;
389,710✔
964
                char *m;
389,710✔
965
                int r;
389,710✔
966

967
                /* We need to copy the va_list structure,
968
                 * since vasprintf() leaves it afterwards at
969
                 * an undefined location */
970

971
                errno = ERRNO_VALUE(error);
389,710✔
972

973
                va_copy(aq, ap);
389,710✔
974
                r = vasprintf(&m, format, aq);
389,710✔
975
                va_end(aq);
389,710✔
976
                if (r < 0)
389,710✔
UNCOV
977
                        return -EINVAL;
×
978

979
                /* Now, jump enough ahead, so that we point to
980
                 * the next format string */
981
                VA_FORMAT_ADVANCE(format, ap);
1,245,562✔
982

983
                iovec[(*n)++] = IOVEC_MAKE_STRING(m);
389,710✔
984
                if (newline_separator)
389,710✔
985
                        iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
387,622✔
986

987
                format = va_arg(ap, char *);
389,710✔
988
        }
989
        return 0;
990
}
991

992
int log_struct_internal(
89,893✔
993
                int level,
994
                int error,
995
                const char *file,
996
                int line,
997
                const char *func,
998
                const char *format, ...) {
999

1000
        char buf[LINE_MAX];
89,893✔
1001
        bool found = false;
89,893✔
1002
        PROTECT_ERRNO;
89,893✔
1003
        va_list ap;
89,893✔
1004

1005
        if (_likely_(LOG_PRI(level) > log_max_level) ||
89,893✔
1006
            log_target == LOG_TARGET_NULL)
89,893✔
1007
                return -ERRNO_VALUE(error);
50✔
1008

1009
        if (LOG_FAC(level) == 0)
89,843✔
1010
                level |= log_facility;
89,843✔
1011

1012
        if (IN_SET(log_target,
89,843✔
1013
                   LOG_TARGET_AUTO,
1014
                   LOG_TARGET_JOURNAL_OR_KMSG,
1015
                   LOG_TARGET_JOURNAL)) {
1016

1017
                if (open_when_needed)
87,943✔
1018
                        log_open_journal();
10,632✔
1019

1020
                if (journal_fd >= 0) {
87,943✔
1021
                        char header[LINE_MAX];
78,357✔
1022
                        struct iovec *iovec;
78,357✔
1023
                        size_t n = 0, m, iovec_len;
78,357✔
1024
                        int r;
78,357✔
1025
                        bool fallback = false;
78,357✔
1026

1027
                        iovec_len = MIN(17 + log_context_num_fields() * 3, IOVEC_MAX);
78,357✔
1028
                        iovec = newa(struct iovec, iovec_len);
78,357✔
1029

1030
                        /* If the journal is available do structured logging.
1031
                         * Do not report the errno if it is synthetic. */
1032
                        log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
78,357✔
1033
                        iovec[n++] = IOVEC_MAKE_STRING(header);
78,357✔
1034

1035
                        va_start(ap, format);
78,357✔
1036
                        DISABLE_WARNING_FORMAT_NONLITERAL;
78,357✔
1037
                        r = log_format_iovec(iovec, iovec_len, &n, true, error, format, ap);
78,357✔
1038
                        REENABLE_WARNING;
78,357✔
1039
                        m = n;
78,357✔
1040
                        if (r < 0)
78,357✔
1041
                                fallback = true;
1042
                        else {
1043
                                log_do_context(iovec, iovec_len, &n);
78,357✔
1044

1045
                                const struct msghdr msghdr = {
78,357✔
1046
                                        .msg_iov = iovec,
1047
                                        .msg_iovlen = n,
1048
                                };
1049

1050
                                (void) sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL);
78,357✔
1051
                        }
1052

1053
                        va_end(ap);
78,357✔
1054
                        for (size_t i = 1; i < m; i += 2)
465,974✔
1055
                                free(iovec[i].iov_base);
387,617✔
1056

1057
                        if (!fallback) {
78,357✔
1058
                                if (open_when_needed)
78,357✔
1059
                                        log_close();
10,619✔
1060

1061
                                return -ERRNO_VALUE(error);
78,357✔
1062
                        }
1063
                }
1064
        }
1065

1066
        /* Fallback if journal logging is not available or didn't work. */
1067

1068
        va_start(ap, format);
11,486✔
1069
        while (format) {
34,733✔
1070
                va_list aq;
34,733✔
1071

1072
                errno = ERRNO_VALUE(error);
34,733✔
1073

1074
                va_copy(aq, ap);
34,733✔
1075
                DISABLE_WARNING_FORMAT_NONLITERAL;
34,733✔
1076
                (void) vsnprintf(buf, sizeof buf, format, aq);
34,733✔
1077
                REENABLE_WARNING;
34,733✔
1078
                va_end(aq);
34,733✔
1079

1080
                if (startswith(buf, "MESSAGE=")) {
34,733✔
1081
                        found = true;
11,486✔
1082
                        break;
11,486✔
1083
                }
1084

1085
                VA_FORMAT_ADVANCE(format, ap);
62,547✔
1086

1087
                format = va_arg(ap, char *);
23,247✔
1088
        }
1089
        va_end(ap);
11,486✔
1090

1091
        if (!found) {
11,486✔
UNCOV
1092
                if (open_when_needed)
×
UNCOV
1093
                        log_close();
×
1094

UNCOV
1095
                return -ERRNO_VALUE(error);
×
1096
        }
1097

1098
        return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
11,486✔
1099
}
1100

1101
int log_struct_iovec_internal(
3,443✔
1102
                int level,
1103
                int error,
1104
                const char *file,
1105
                int line,
1106
                const char *func,
1107
                const struct iovec input_iovec[],
1108
                size_t n_input_iovec) {
1109

1110
        PROTECT_ERRNO;
3,443✔
1111

1112
        if (_likely_(LOG_PRI(level) > log_max_level) ||
3,443✔
1113
            log_target == LOG_TARGET_NULL)
3,443✔
UNCOV
1114
                return -ERRNO_VALUE(error);
×
1115

1116
        if (LOG_FAC(level) == 0)
3,443✔
1117
                level |= log_facility;
3,443✔
1118

1119
        if (IN_SET(log_target, LOG_TARGET_AUTO,
3,443✔
1120
                               LOG_TARGET_JOURNAL_OR_KMSG,
1121
                               LOG_TARGET_JOURNAL) &&
3,443✔
1122
            journal_fd >= 0) {
3,443✔
1123

1124
                char header[LINE_MAX];
3,407✔
1125
                struct iovec *iovec;
3,407✔
1126
                size_t n = 0, iovec_len;
3,407✔
1127

1128
                iovec_len = MIN(1 + n_input_iovec * 2 + log_context_num_fields() * 3, IOVEC_MAX);
3,407✔
1129
                iovec = newa(struct iovec, iovec_len);
3,407✔
1130

1131
                log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
3,407✔
1132

1133
                iovec[n++] = IOVEC_MAKE_STRING(header);
3,407✔
1134
                for (size_t i = 0; i < n_input_iovec; i++) {
27,204✔
1135
                        iovec[n++] = input_iovec[i];
23,797✔
1136
                        iovec[n++] = IOVEC_MAKE_STRING("\n");
23,797✔
1137
                }
1138

1139
                log_do_context(iovec, iovec_len, &n);
3,407✔
1140

1141
                const struct msghdr msghdr = {
3,407✔
1142
                        .msg_iov = iovec,
1143
                        .msg_iovlen = n,
1144
                };
1145

1146
                if (sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL) >= 0)
3,407✔
1147
                        return -ERRNO_VALUE(error);
3,404✔
1148
        }
1149

1150
        for (size_t i = 0; i < n_input_iovec; i++)
156✔
1151
                if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) {
156✔
1152
                        char *m;
39✔
1153

1154
                        m = strndupa_safe((char*) input_iovec[i].iov_base + STRLEN("MESSAGE="),
39✔
1155
                                          input_iovec[i].iov_len - STRLEN("MESSAGE="));
1156

1157
                        return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
39✔
1158
                }
1159

1160
        /* Couldn't find MESSAGE=. */
UNCOV
1161
        return -ERRNO_VALUE(error);
×
1162
}
1163

1164
int log_set_target_from_string(const char *e) {
12,943✔
1165
        LogTarget t;
12,943✔
1166

1167
        t = log_target_from_string(e);
12,943✔
1168
        if (t < 0)
12,943✔
1169
                return t;
1170

1171
        log_set_target(t);
12,941✔
1172
        return 0;
12,941✔
1173
}
1174

1175
int log_set_max_level_from_string(const char *e) {
30,195✔
1176
        int r;
80,810✔
1177

1178
        for (;;) {
80,810✔
1179
                _cleanup_free_ char *word = NULL, *prefix = NULL;
80,810✔
1180
                LogTarget target;
80,810✔
1181
                const char *colon;
80,810✔
1182

1183
                r = extract_first_word(&e, &word, ",", 0);
80,810✔
1184
                if (r < 0)
80,810✔
1185
                        return r;
1186
                if (r == 0)
80,810✔
1187
                        break;
1188

1189
                colon = strchr(word, ':');
50,615✔
1190
                if (!colon) {
50,615✔
1191
                        r = log_level_from_string(word);
30,193✔
1192
                        if (r < 0)
30,193✔
1193
                                return r;
1194

1195
                        log_set_max_level(r);
30,193✔
1196
                        continue;
30,193✔
1197
                }
1198

1199
                prefix = strndup(word, colon - word);
20,422✔
1200
                if (!prefix)
20,422✔
1201
                        return -ENOMEM;
1202

1203
                target = log_target_from_string(prefix);
20,422✔
1204
                if (target < 0)
20,422✔
1205
                        return target;
1206

1207
                if (target >= _LOG_TARGET_SINGLE_MAX)
20,422✔
1208
                        return -EINVAL;
1209

1210
                r = log_level_from_string(colon + 1);
20,422✔
1211
                if (r < 0)
20,422✔
1212
                        return r;
1213

1214
                log_target_max_level[target] = r;
20,422✔
1215
        }
1216

1217
        return 0;
30,195✔
1218
}
1219

1220
int log_max_levels_to_string(int level, char **ret) {
4,458✔
1221
        _cleanup_free_ char *s = NULL;
4,458✔
1222
        int r;
4,458✔
1223

1224
        assert(ret);
4,458✔
1225

1226
        r = log_level_to_string_alloc(level, &s);
4,458✔
1227
        if (r < 0)
4,458✔
1228
                return r;
1229

1230
        for (LogTarget target = 0; target < _LOG_TARGET_SINGLE_MAX; target++) {
22,290✔
1231
                _cleanup_free_ char *l = NULL;
4,458✔
1232

1233
                if (log_target_max_level[target] == INT_MAX)
17,832✔
1234
                        continue;
13,374✔
1235

1236
                r = log_level_to_string_alloc(log_target_max_level[target], &l);
4,458✔
1237
                if (r < 0)
4,458✔
1238
                        return r;
1239

1240
                r = strextendf_with_separator(&s, ",", "%s:%s", log_target_to_string(target), l);
4,458✔
1241
                if (r < 0)
4,458✔
1242
                        return r;
1243
        }
1244

1245
        *ret = TAKE_PTR(s);
4,458✔
1246
        return 0;
4,458✔
1247
}
1248

1249
static int log_set_ratelimit_kmsg_from_string(const char *e) {
8,233✔
1250
        int r;
8,233✔
1251

1252
        r = parse_boolean(e);
8,233✔
1253
        if (r < 0)
8,233✔
1254
                return r;
1255

1256
        ratelimit_kmsg = r;
8,233✔
1257
        return 0;
8,233✔
1258
}
1259

1260
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
279,125✔
1261

1262
        /*
1263
         * The systemd.log_xyz= settings are parsed by all tools, and
1264
         * so is "debug".
1265
         *
1266
         * However, "quiet" is only parsed by PID 1, and only turns of
1267
         * status output to /dev/console, but does not alter the log
1268
         * level.
1269
         */
1270

1271
        if (streq(key, "debug") && !value)
279,125✔
UNCOV
1272
                log_set_max_level(LOG_DEBUG);
×
1273

1274
        else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
279,125✔
1275

UNCOV
1276
                if (proc_cmdline_value_missing(key, value))
×
1277
                        return 0;
1278

UNCOV
1279
                if (log_set_target_from_string(value) < 0)
×
UNCOV
1280
                        log_warning("Failed to parse log target '%s', ignoring.", value);
×
1281

1282
        } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
279,125✔
1283

1284
                if (proc_cmdline_value_missing(key, value))
8,233✔
1285
                        return 0;
1286

1287
                if (log_set_max_level_from_string(value) < 0)
8,233✔
UNCOV
1288
                        log_warning("Failed to parse log level setting '%s', ignoring.", value);
×
1289

1290
        } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
270,892✔
1291

1292
                if (log_show_color_from_string(value ?: "1") < 0)
×
UNCOV
1293
                        log_warning("Failed to parse log color setting '%s', ignoring.", value);
×
1294

1295
        } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
270,892✔
1296

1297
                if (log_show_location_from_string(value ?: "1") < 0)
×
UNCOV
1298
                        log_warning("Failed to parse log location setting '%s', ignoring.", value);
×
1299

1300
        } else if (proc_cmdline_key_streq(key, "systemd.log_tid")) {
270,892✔
1301

1302
                if (log_show_tid_from_string(value ?: "1") < 0)
×
UNCOV
1303
                        log_warning("Failed to parse log tid setting '%s', ignoring.", value);
×
1304

1305
        } else if (proc_cmdline_key_streq(key, "systemd.log_time")) {
270,892✔
1306

1307
                if (log_show_time_from_string(value ?: "1") < 0)
×
UNCOV
1308
                        log_warning("Failed to parse log time setting '%s', ignoring.", value);
×
1309

1310
        } else if (proc_cmdline_key_streq(key, "systemd.log_ratelimit_kmsg")) {
270,892✔
1311

1312
                if (log_set_ratelimit_kmsg_from_string(value ?: "1") < 0)
8,233✔
UNCOV
1313
                        log_warning("Failed to parse log ratelimit kmsg boolean '%s', ignoring.", value);
×
1314
        }
1315

1316
        return 0;
1317
}
1318

1319
static bool should_parse_proc_cmdline(void) {
80,879✔
1320
        /* PID1 always reads the kernel command line. */
1321
        if (getpid_cached() == 1)
80,879✔
1322
                return true;
1323

1324
        /* Otherwise, parse the command line if invoked directly by systemd. */
1325
        return invoked_by_systemd();
80,651✔
1326
}
1327

1328
void log_parse_environment_variables(void) {
83,654✔
1329
        const char *e;
83,654✔
1330
        int r;
83,654✔
1331

1332
        e = getenv("SYSTEMD_LOG_TARGET");
83,654✔
1333
        if (e && log_set_target_from_string(e) < 0)
83,654✔
1334
                log_warning("Failed to parse log target '%s', ignoring.", e);
2✔
1335

1336
        e = getenv("SYSTEMD_LOG_LEVEL");
83,654✔
1337
        if (e) {
83,654✔
1338
                r = log_set_max_level_from_string(e);
8,751✔
1339
                if (r < 0)
8,751✔
UNCOV
1340
                        log_warning_errno(r, "Failed to parse log level '%s', ignoring: %m", e);
×
1341
        } else {
1342
                /* If no explicit log level is specified then let's see if this is a debug invocation, and if
1343
                 * so raise the log level to debug too. Note that this is not symmetric: just because
1344
                 * DEBUG_INVOCATION is explicitly set to 0 we won't lower the log level below debug. This
1345
                 * follows the logic that debug logging is an opt-in thing anyway, and if there's any reason
1346
                 * to enable it we should not disable it here automatically. */
1347
                r = getenv_bool("DEBUG_INVOCATION");
74,903✔
1348
                if (r < 0 && r != -ENXIO)
74,903✔
UNCOV
1349
                        log_warning_errno(r, "Failed to parse $DEBUG_INVOCATION value, ignoring: %m");
×
1350
                else if (r > 0)
74,903✔
UNCOV
1351
                        log_set_max_level(LOG_DEBUG);
×
1352
        }
1353

1354
        e = getenv("SYSTEMD_LOG_COLOR");
83,654✔
1355
        if (e && log_show_color_from_string(e) < 0)
83,654✔
UNCOV
1356
                log_warning("Failed to parse log color '%s', ignoring.", e);
×
1357

1358
        e = getenv("SYSTEMD_LOG_LOCATION");
83,654✔
1359
        if (e && log_show_location_from_string(e) < 0)
83,654✔
UNCOV
1360
                log_warning("Failed to parse log location '%s', ignoring.", e);
×
1361

1362
        e = getenv("SYSTEMD_LOG_TIME");
83,654✔
1363
        if (e && log_show_time_from_string(e) < 0)
83,654✔
UNCOV
1364
                log_warning("Failed to parse log time '%s', ignoring.", e);
×
1365

1366
        e = getenv("SYSTEMD_LOG_TID");
83,654✔
1367
        if (e && log_show_tid_from_string(e) < 0)
83,654✔
UNCOV
1368
                log_warning("Failed to parse log tid '%s', ignoring.", e);
×
1369

1370
        e = getenv("SYSTEMD_LOG_RATELIMIT_KMSG");
83,654✔
1371
        if (e && log_set_ratelimit_kmsg_from_string(e) < 0)
83,654✔
UNCOV
1372
                log_warning("Failed to parse log ratelimit kmsg boolean '%s', ignoring.", e);
×
1373
}
83,654✔
1374

1375
void log_parse_environment(void) {
80,879✔
1376
        /* Do not call from library code. */
1377

1378
        if (should_parse_proc_cmdline())
80,879✔
1379
                (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
8,245✔
1380

1381
        log_parse_environment_variables();
80,879✔
1382
}
80,879✔
1383

1384
LogTarget log_get_target(void) {
24,915✔
1385
        return log_target;
24,915✔
1386
}
1387

1388
void log_settle_target(void) {
20,856✔
1389

1390
        /* If we're using LOG_TARGET_AUTO and opening the log again on every single log call, we'll check if
1391
         * stderr is attached to the journal every single log call. However, if we then close all file
1392
         * descriptors later, that will stop working because stderr will be closed as well. To avoid that
1393
         * problem, this function is used to permanently change the log target depending on whether stderr is
1394
         * connected to the journal or not. */
1395

1396
        LogTarget t = log_get_target();
20,856✔
1397

1398
        if (t != LOG_TARGET_AUTO)
20,856✔
1399
                return;
1400

1401
        t = getpid_cached() == 1 || stderr_is_journal() ? (prohibit_ipc ? LOG_TARGET_KMSG : LOG_TARGET_JOURNAL_OR_KMSG)
26,785✔
1402
                                                        : LOG_TARGET_CONSOLE;
17,774✔
1403
        log_set_target(t);
9,011✔
1404
}
1405

1406
int log_get_max_level(void) {
20,338,259✔
1407
        return log_max_level;
20,338,259✔
1408
}
1409

1410
int log_get_target_max_level(LogTarget target) {
16✔
1411
        assert(target >= 0);
16✔
1412
        assert(target < _LOG_TARGET_SINGLE_MAX);
16✔
1413
        return log_target_max_level[target];
16✔
1414
}
1415

1416
void log_show_color(bool b) {
70,519✔
1417
        show_color = b;
70,519✔
1418
}
70,519✔
1419

1420
bool log_get_show_color(void) {
260,955✔
1421
        return show_color > 0; /* Defaults to false. */
260,955✔
1422
}
1423

UNCOV
1424
void log_show_location(bool b) {
×
UNCOV
1425
        show_location = b;
×
UNCOV
1426
}
×
1427

1428
bool log_get_show_location(void) {
15✔
1429
        return show_location;
15✔
1430
}
1431

1432
void log_show_time(bool b) {
1✔
1433
        show_time = b;
1✔
1434
}
1✔
1435

1436
bool log_get_show_time(void) {
15✔
1437
        return show_time;
15✔
1438
}
1439

1440
void log_show_tid(bool b) {
1✔
1441
        show_tid = b;
1✔
1442
}
1✔
1443

UNCOV
1444
bool log_get_show_tid(void) {
×
1445
        return show_tid;
×
1446
}
1447

UNCOV
1448
int log_show_color_from_string(const char *e) {
×
1449
        int r;
×
1450

UNCOV
1451
        r = parse_boolean(e);
×
UNCOV
1452
        if (r < 0)
×
1453
                return r;
1454

UNCOV
1455
        log_show_color(r);
×
1456
        return 0;
×
1457
}
1458

UNCOV
1459
int log_show_location_from_string(const char *e) {
×
1460
        int r;
×
1461

UNCOV
1462
        r = parse_boolean(e);
×
UNCOV
1463
        if (r < 0)
×
1464
                return r;
1465

UNCOV
1466
        log_show_location(r);
×
1467
        return 0;
×
1468
}
1469

UNCOV
1470
int log_show_time_from_string(const char *e) {
×
1471
        int r;
×
1472

UNCOV
1473
        r = parse_boolean(e);
×
UNCOV
1474
        if (r < 0)
×
1475
                return r;
1476

UNCOV
1477
        log_show_time(r);
×
1478
        return 0;
×
1479
}
1480

UNCOV
1481
int log_show_tid_from_string(const char *e) {
×
1482
        int r;
×
1483

UNCOV
1484
        r = parse_boolean(e);
×
UNCOV
1485
        if (r < 0)
×
1486
                return r;
1487

UNCOV
1488
        log_show_tid(r);
×
UNCOV
1489
        return 0;
×
1490
}
1491

1492
bool log_on_console(void) {
105,146✔
1493
        if (IN_SET(log_target, LOG_TARGET_CONSOLE,
105,146✔
1494
                               LOG_TARGET_CONSOLE_PREFIXED))
1495
                return true;
1496

1497
        return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
138,145✔
1498
}
1499

1500
static const char *const log_target_table[_LOG_TARGET_MAX] = {
1501
        [LOG_TARGET_CONSOLE]          = "console",
1502
        [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1503
        [LOG_TARGET_KMSG]             = "kmsg",
1504
        [LOG_TARGET_JOURNAL]          = "journal",
1505
        [LOG_TARGET_JOURNAL_OR_KMSG]  = "journal-or-kmsg",
1506
        [LOG_TARGET_SYSLOG]           = "syslog",
1507
        [LOG_TARGET_SYSLOG_OR_KMSG]   = "syslog-or-kmsg",
1508
        [LOG_TARGET_AUTO]             = "auto",
1509
        [LOG_TARGET_NULL]             = "null",
1510
};
1511

1512
DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
42,404✔
1513

1514
void log_received_signal(int level, const struct signalfd_siginfo *si) {
7,625✔
1515
        assert(si);
7,625✔
1516

1517
        if (si_code_from_process(si->ssi_code) && pid_is_valid(si->ssi_pid)) {
7,872✔
1518
                _cleanup_free_ char *p = NULL;
247✔
1519

1520
                (void) pid_get_comm(si->ssi_pid, &p);
247✔
1521

1522
                log_full(level,
247✔
1523
                         "Received SIG%s from PID %"PRIu32" (%s).",
1524
                         signal_to_string(si->ssi_signo),
1525
                         si->ssi_pid, strna(p));
1526
        } else
1527
                log_full(level,
7,378✔
1528
                         "Received SIG%s.",
1529
                         signal_to_string(si->ssi_signo));
1530
}
7,625✔
1531

1532
void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata) {
988✔
1533
        assert(!log_syntax_callback || !cb);
988✔
1534
        assert(!log_syntax_callback_userdata || !userdata);
988✔
1535

1536
        log_syntax_callback = cb;
988✔
1537
        log_syntax_callback_userdata = userdata;
988✔
1538
}
988✔
1539

1540
int log_syntax_internal(
30,402✔
1541
                const char *unit,
1542
                int level,
1543
                const char *config_file,
1544
                unsigned config_line,
1545
                int error,
1546
                const char *file,
1547
                int line,
1548
                const char *func,
1549
                const char *format, ...) {
1550

1551
        PROTECT_ERRNO;
30,402✔
1552

1553
        if (log_syntax_callback)
30,402✔
1554
                log_syntax_callback(unit, level, log_syntax_callback_userdata);
1,518✔
1555

1556
        if (_likely_(LOG_PRI(level) > log_max_level) ||
30,402✔
1557
            log_target == LOG_TARGET_NULL)
30,402✔
1558
                return -ERRNO_VALUE(error);
30✔
1559

1560
        char buffer[LINE_MAX];
30,372✔
1561
        va_list ap;
30,372✔
1562
        const char *unit_fmt = NULL;
30,372✔
1563

1564
        errno = ERRNO_VALUE(error);
30,372✔
1565

1566
        va_start(ap, format);
30,372✔
1567
        (void) vsnprintf(buffer, sizeof buffer, format, ap);
30,372✔
1568
        va_end(ap);
30,372✔
1569

1570
        if (unit)
30,372✔
1571
                unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
22,389✔
1572

1573
        if (config_file) {
30,372✔
1574
                if (config_line > 0)
30,362✔
1575
                        return log_struct_internal(
23,618✔
1576
                                        level,
1577
                                        error,
1578
                                        file, line, func,
1579
                                        LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION_STR),
23,618✔
1580
                                        LOG_ITEM("CONFIG_FILE=%s", config_file),
23,618✔
1581
                                        LOG_ITEM("CONFIG_LINE=%u", config_line),
23,618✔
1582
                                        LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
23,618✔
1583
                                        unit_fmt, unit,
1584
                                        NULL);
1585
                else
1586
                        return log_struct_internal(
6,744✔
1587
                                        level,
1588
                                        error,
1589
                                        file, line, func,
1590
                                        LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION_STR),
6,744✔
1591
                                        LOG_ITEM("CONFIG_FILE=%s", config_file),
6,744✔
1592
                                        LOG_MESSAGE("%s: %s", config_file, buffer),
6,744✔
1593
                                        unit_fmt, unit,
1594
                                        NULL);
1595
        } else if (unit)
10✔
UNCOV
1596
                return log_struct_internal(
×
1597
                                level,
1598
                                error,
1599
                                file, line, func,
UNCOV
1600
                                LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION_STR),
×
UNCOV
1601
                                LOG_MESSAGE("%s: %s", unit, buffer),
×
1602
                                unit_fmt, unit,
1603
                                NULL);
1604
        else
1605
                return log_struct_internal(
10✔
1606
                                level,
1607
                                error,
1608
                                file, line, func,
1609
                                LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION_STR),
10✔
1610
                                LOG_MESSAGE("%s", buffer),
10✔
1611
                                NULL);
1612
}
1613

1614
int log_syntax_invalid_utf8_internal(
9✔
1615
                const char *unit,
1616
                int level,
1617
                const char *config_file,
1618
                unsigned config_line,
1619
                const char *file,
1620
                int line,
1621
                const char *func,
1622
                const char *rvalue) {
1623

UNCOV
1624
        PROTECT_ERRNO;
×
1625
        _cleanup_free_ char *p = NULL;
9✔
1626

1627
        if (rvalue)
9✔
1628
                p = utf8_escape_invalid(rvalue);
9✔
1629

1630
        return log_syntax_internal(unit, level, config_file, config_line,
9✔
1631
                                   SYNTHETIC_ERRNO(EINVAL), file, line, func,
1632
                                   "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
1633
}
1634

1635
int log_syntax_parse_error_internal(
135✔
1636
                const char *unit,
1637
                const char *config_file,
1638
                unsigned config_line,
1639
                int error,
1640
                bool critical,
1641
                const char *file,
1642
                int line,
1643
                const char *func,
1644
                const char *lvalue,
1645
                const char *rvalue) {
1646

UNCOV
1647
        PROTECT_ERRNO;
×
1648
        _cleanup_free_ char *escaped = NULL;
135✔
1649

1650
        /* OOM is always handled as critical. */
1651
        if (ERRNO_VALUE(error) == ENOMEM)
135✔
UNCOV
1652
                return log_oom_internal(LOG_ERR, file, line, func);
×
1653

1654
        if (rvalue && !utf8_is_valid(rvalue)) {
270✔
UNCOV
1655
                escaped = utf8_escape_invalid(rvalue);
×
UNCOV
1656
                if (!escaped)
×
1657
                        rvalue = "(oom)";
1658
                else
UNCOV
1659
                        rvalue = " (escaped)";
×
1660
        }
1661

1662
        log_syntax_internal(unit, critical ? LOG_ERR : LOG_WARNING, config_file, config_line, error,
675✔
1663
                            file, line, func,
1664
                            "Failed to parse %s=%s%s%s%s%s",
1665
                            strna(lvalue), strempty(escaped), strempty(rvalue),
1666
                            critical ? "" : ", ignoring",
1667
                            error == 0 ? "." : ": ",
1668
                            error == 0 ? "" : STRERROR(error));
135✔
1669

1670
        return critical ? -ERRNO_VALUE(error) : 0;
135✔
1671
}
1672

1673
void log_set_upgrade_syslog_to_journal(bool b) {
277✔
1674
        upgrade_syslog_to_journal = b;
277✔
1675

1676
        /* Make the change effective immediately */
1677
        if (b) {
277✔
1678
                if (log_target == LOG_TARGET_SYSLOG)
277✔
UNCOV
1679
                        log_target = LOG_TARGET_JOURNAL;
×
1680
                else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
277✔
UNCOV
1681
                        log_target = LOG_TARGET_JOURNAL_OR_KMSG;
×
1682
        }
1683
}
277✔
1684

1685
void log_set_always_reopen_console(bool b) {
12,466✔
1686
        always_reopen_console = b;
12,466✔
1687
}
12,466✔
1688

1689
void log_set_open_when_needed(bool b) {
32,069✔
1690
        open_when_needed = b;
32,069✔
1691
}
32,069✔
1692

1693
void log_set_prohibit_ipc(bool b) {
45,564✔
1694
        prohibit_ipc = b;
45,564✔
1695
}
45,564✔
1696

UNCOV
1697
int log_emergency_level(void) {
×
1698
        /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1699
         * then the system of the whole system is obviously affected. */
1700

UNCOV
1701
        return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;
×
1702
}
1703

1704
int log_dup_console(void) {
116✔
1705
        int copy;
116✔
1706

1707
        /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
1708
         * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
1709

1710
        if (console_fd < 0 || console_fd >= 3)
116✔
1711
                return 0;
1712

1713
        copy = fcntl(console_fd, F_DUPFD_CLOEXEC, 3);
1✔
1714
        if (copy < 0)
1✔
UNCOV
1715
                return -errno;
×
1716

1717
        console_fd = copy;
1✔
1718
        return 0;
1✔
1719
}
1720

1721
void log_setup(void) {
80,030✔
1722
        log_set_target(LOG_TARGET_AUTO);
80,030✔
1723
        log_parse_environment();
80,030✔
1724
        (void) log_open();
80,030✔
1725
        if (log_on_console() && show_color < 0)
80,030✔
1726
                log_show_color(true);
70,403✔
1727
}
80,030✔
1728

1729
const char* _log_set_prefix(const char *prefix, bool force) {
3,547,346✔
1730
        const char *old = log_prefix;
3,547,346✔
1731

1732
        if (prefix || force)
3,547,346✔
1733
                log_prefix = prefix;
3,545,467✔
1734

1735
        return old;
3,547,346✔
1736
}
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