• 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

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

3
#include <stdlib.h>
4

5
#include "alloc-util.h"
6
#include "env-file.h"
7
#include "hostname-util.h"
8
#include "log.h"
9
#include "os-util.h"
10
#include "string-util.h"
11
#include "strv.h"
12

13
char* get_default_hostname_raw(void) {
44✔
14
        int r;
44✔
15

16
        /* Returns the default hostname, and leaves any ??? in place. */
17

18
        const char *e = secure_getenv("SYSTEMD_DEFAULT_HOSTNAME");
44✔
19
        if (e) {
44✔
UNCOV
20
                if (hostname_is_valid(e, VALID_HOSTNAME_QUESTION_MARK))
×
21
                        return strdup(e);
44✔
22

UNCOV
23
                log_debug("Invalid hostname in $SYSTEMD_DEFAULT_HOSTNAME, ignoring: %s", e);
×
24
        }
25

26
        _cleanup_free_ char *f = NULL;
44✔
27
        r = parse_os_release(NULL, "DEFAULT_HOSTNAME", &f);
44✔
28
        if (r < 0)
44✔
UNCOV
29
                log_debug_errno(r, "Failed to parse os-release, ignoring: %m");
×
30
        else if (f) {
44✔
UNCOV
31
                if (hostname_is_valid(f, VALID_HOSTNAME_QUESTION_MARK))
×
UNCOV
32
                        return TAKE_PTR(f);
×
33

34
                log_debug("Invalid hostname in os-release, ignoring: %s", f);
×
35
        }
36

37
        return strdup(FALLBACK_HOSTNAME);
44✔
38
}
39

40
bool valid_ldh_char(char c) {
68,784✔
41
        /* "LDH" → "Letters, digits, hyphens", as per RFC 5890, Section 2.3.1 */
42

43
        return ascii_isalpha(c) ||
68,784✔
44
                ascii_isdigit(c) ||
68,784✔
45
                c == '-';
46
}
47

48
bool hostname_is_valid(const char *s, ValidHostnameFlags flags) {
3,632✔
49
        unsigned n_dots = 0;
3,632✔
50
        const char *p;
3,632✔
51
        bool dot, hyphen;
3,632✔
52

53
        /* Check if s looks like a valid hostname or FQDN. This does not do full DNS validation, but only
54
         * checks if the name is composed of allowed characters and the length is not above the maximum
55
         * allowed by Linux (c.f. dns_name_is_valid()). A trailing dot is allowed if
56
         * VALID_HOSTNAME_TRAILING_DOT flag is set and at least two components are present in the name. Note
57
         * that due to the restricted charset and length this call is substantially more conservative than
58
         * dns_name_is_valid(). Doesn't accept empty hostnames, hostnames with leading dots, and hostnames
59
         * with multiple dots in a sequence. Doesn't allow hyphens at the beginning or end of label. */
60

61
        if (isempty(s))
3,632✔
62
                return false;
63

64
        if (streq(s, ".host")) /* Used by the container logic to denote the "root container" */
3,623✔
65
                return FLAGS_SET(flags, VALID_HOSTNAME_DOT_HOST);
61✔
66

67
        for (p = s, dot = hyphen = true; *p; p++)
69,846✔
68
                if (*p == '.') {
66,324✔
69
                        if (dot || hyphen)
9,752✔
70
                                return false;
71

72
                        dot = true;
9,740✔
73
                        hyphen = false;
9,740✔
74
                        n_dots++;
9,740✔
75

76
                } else if (*p == '-') {
56,572✔
77
                        if (dot)
2,210✔
78
                                return false;
79

80
                        dot = false;
81
                        hyphen = true;
82

83
                } else {
84
                        if (!valid_ldh_char(*p) && (*p != '?' || !FLAGS_SET(flags, VALID_HOSTNAME_QUESTION_MARK)))
54,362✔
85
                                return false;
86

87
                        dot = false;
88
                        hyphen = false;
89
                }
90

91
        if (dot && (n_dots < 2 || !FLAGS_SET(flags, VALID_HOSTNAME_TRAILING_DOT)))
3,522✔
92
                return false;
93
        if (hyphen)
3,516✔
94
                return false;
95

96
        if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on Linux, but DNS allows domain names up to
3,516✔
97
                                  * 255 characters */
98
                return false;
5✔
99

100
        return true;
101
}
102

103
char* hostname_cleanup(char *s) {
409✔
104
        char *p, *d;
409✔
105
        bool dot, hyphen;
409✔
106

107
        assert(s);
409✔
108

109
        for (p = s, d = s, dot = hyphen = true; *p && d - s < HOST_NAME_MAX; p++)
13,337✔
110
                if (*p == '.') {
12,928✔
111
                        if (dot || hyphen)
741✔
112
                                continue;
16✔
113

114
                        *(d++) = '.';
725✔
115
                        dot = true;
725✔
116
                        hyphen = false;
725✔
117

118
                } else if (*p == '-') {
12,187✔
119
                        if (dot)
1,459✔
120
                                continue;
4✔
121

122
                        *(d++) = '-';
1,455✔
123
                        dot = false;
1,455✔
124
                        hyphen = true;
1,455✔
125

126
                } else if (valid_ldh_char(*p) || *p == '?') {
10,728✔
127
                        *(d++) = *p;
10,704✔
128
                        dot = false;
10,704✔
129
                        hyphen = false;
10,704✔
130
                }
131

132
        if (d > s && IN_SET(d[-1], '-', '.'))
409✔
133
                /* The dot can occur at most once, but we might have multiple
134
                 * hyphens, hence the loop */
135
                d--;
7✔
136
        *d = 0;
409✔
137

138
        return s;
409✔
139
}
140

141
bool is_localhost(const char *hostname) {
141,213✔
142
        assert(hostname);
141,213✔
143

144
        /* This tries to identify local host and domain names
145
         * described in RFC6761 plus the redhatism of localdomain */
146

147
        return STRCASE_IN_SET(
141,213✔
148
                        hostname,
149
                        "localhost",
150
                        "localhost.",
151
                        "localhost.localdomain",
152
                        "localhost.localdomain.") ||
140,923✔
153
                endswith_no_case(hostname, ".localhost") ||
281,816✔
154
                endswith_no_case(hostname, ".localhost.") ||
281,756✔
155
                endswith_no_case(hostname, ".localhost.localdomain") ||
422,909✔
156
                endswith_no_case(hostname, ".localhost.localdomain.");
140,833✔
157
}
158

159
int get_pretty_hostname(char **ret) {
11✔
160
        _cleanup_free_ char *n = NULL;
11✔
161
        int r;
11✔
162

163
        assert(ret);
11✔
164

165
        r = parse_env_file(NULL, "/etc/machine-info", "PRETTY_HOSTNAME", &n);
11✔
166
        if (r < 0)
11✔
167
                return r;
168

169
        if (isempty(n))
11✔
170
                return -ENXIO;
171

UNCOV
172
        *ret = TAKE_PTR(n);
×
UNCOV
173
        return 0;
×
174
}
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