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

systemd / systemd / 25026908423

27 Apr 2026 07:14PM UTC coverage: 71.865% (-0.3%) from 72.175%
25026908423

push

github

daandemeyer
udev: don't assert on worker cap after killing a broken idle worker

manager_can_process_event() considers an event processable if either
there is room below children_max to spawn, or an idle worker exists.
When only the latter holds, event_run() picks the idle worker and
tries device_monitor_send(). If that send fails, event_run() SIGKILLs
the worker, marks it WORKER_KILLED and continues the loop. With no
other idle worker available, it falls through to worker_spawn(),
guarded by:

    assert(hashmap_size(manager->workers) < manager->config.children_max);

The just-killed worker is still in manager->workers until its SIGCHLD
is reaped by on_worker_exit(), so at the cap this assertion trips and
udevd aborts:

    Assertion 'hashmap_size(manager->workers) < manager->config.children_max'
    failed at src/udev/udev-manager.c:635, function event_run(). Aborting.

Instead of asserting, bail out when we are already at the worker
limit. The event remains in EVENT_QUEUED; once the killed worker's
SIGCHLD arrives and frees it from the hashmap, on_post() re-runs
event_queue_start() and the event is retried.

1 of 1 new or added line in 1 file covered. (100.0%)

7309 existing lines in 125 files now uncovered.

322519 of 448782 relevant lines covered (71.87%)

1173939.78 hits per line

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

77.78
/src/firstboot/firstboot.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <fcntl.h>
4
#include <unistd.h>
5

6
#include "sd-bus.h"
7
#include "sd-id128.h"
8
#include "sd-varlink.h"
9

10
#include "alloc-util.h"
11
#include "ask-password-api.h"
12
#include "build.h"
13
#include "bus-error.h"
14
#include "bus-locator.h"
15
#include "bus-unit-util.h"
16
#include "bus-util.h"
17
#include "bus-wait-for-jobs.h"
18
#include "chase.h"
19
#include "copy.h"
20
#include "creds-util.h"
21
#include "dissect-image.h"
22
#include "env-file.h"
23
#include "errno-util.h"
24
#include "fd-util.h"
25
#include "fileio.h"
26
#include "format-table.h"
27
#include "fs-util.h"
28
#include "glyph-util.h"
29
#include "hostname-util.h"
30
#include "image-policy.h"
31
#include "kbd-util.h"
32
#include "label-util.h"
33
#include "libcrypt-util.h"
34
#include "locale-setup.h"
35
#include "locale-util.h"
36
#include "lock-util.h"
37
#include "loop-util.h"
38
#include "main-func.h"
39
#include "memory-util.h"
40
#include "mount-util.h"
41
#include "options.h"
42
#include "os-util.h"
43
#include "parse-argument.h"
44
#include "password-quality-util.h"
45
#include "path-util.h"
46
#include "plymouth-util.h"
47
#include "pretty-print.h"
48
#include "proc-cmdline.h"
49
#include "prompt-util.h"
50
#include "runtime-scope.h"
51
#include "smack-util.h"
52
#include "stat-util.h"
53
#include "string-util.h"
54
#include "strv.h"
55
#include "terminal-util.h"
56
#include "time-util.h"
57
#include "tmpfile-util-label.h"
58
#include "user-util.h"
59
#include "vconsole-util.h"
60

61
static char *arg_root = NULL;
62
static char *arg_image = NULL;
63
static char *arg_locale = NULL;  /* $LANG */
64
static char *arg_locale_messages = NULL; /* $LC_MESSAGES */
65
static char *arg_keymap = NULL;
66
static char *arg_timezone = NULL;
67
static char *arg_hostname = NULL;
68
static sd_id128_t arg_machine_id = {};
69
static char *arg_root_password = NULL;
70
static char *arg_root_shell = NULL;
71
static char *arg_kernel_cmdline = NULL;
72
static bool arg_prompt_locale = false;
73
static bool arg_prompt_keymap = false;
74
static bool arg_prompt_keymap_auto = false;
75
static bool arg_prompt_timezone = false;
76
static bool arg_prompt_hostname = false;
77
static bool arg_prompt_root_password = false;
78
static bool arg_prompt_root_shell = false;
79
static bool arg_copy_locale = false;
80
static bool arg_copy_keymap = false;
81
static bool arg_copy_timezone = false;
82
static bool arg_copy_root_password = false;
83
static bool arg_copy_root_shell = false;
84
static bool arg_force = false;
85
static bool arg_delete_root_password = false;
86
static bool arg_root_password_is_hashed = false;
87
static bool arg_welcome = true;
88
static bool arg_reset = false;
89
static ImagePolicy *arg_image_policy = NULL;
90
static bool arg_chrome = true;
91
static bool arg_mute_console = false;
92

93
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
143✔
94
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
143✔
95
STATIC_DESTRUCTOR_REGISTER(arg_locale, freep);
143✔
96
STATIC_DESTRUCTOR_REGISTER(arg_locale_messages, freep);
143✔
97
STATIC_DESTRUCTOR_REGISTER(arg_keymap, freep);
143✔
98
STATIC_DESTRUCTOR_REGISTER(arg_timezone, freep);
143✔
99
STATIC_DESTRUCTOR_REGISTER(arg_hostname, freep);
143✔
100
STATIC_DESTRUCTOR_REGISTER(arg_root_password, erase_and_freep);
143✔
101
STATIC_DESTRUCTOR_REGISTER(arg_root_shell, freep);
143✔
102
STATIC_DESTRUCTOR_REGISTER(arg_kernel_cmdline, freep);
143✔
103
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
143✔
104

105
static void print_welcome(int rfd, sd_varlink **mute_console_link) {
7✔
106
        _cleanup_free_ char *pretty_name = NULL, *os_name = NULL, *ansi_color = NULL;
7✔
107
        static bool done = false;
7✔
108
        const char *pn, *ac;
7✔
109
        int r;
7✔
110

111
        assert(rfd >= 0);
7✔
112
        assert(mute_console_link);
7✔
113

114
        /* Needs to be called before mute_console or it will garble the screen */
115
        if (arg_welcome)
7✔
116
                (void) plymouth_hide_splash();
6✔
117

118
        if (!*mute_console_link && arg_mute_console)
7✔
119
                (void) mute_console(mute_console_link);
×
120

121
        if (!arg_welcome)
7✔
122
                return;
123

124
        if (done) {
6✔
125
                putchar('\n'); /* Add some breathing room between multiple prompts */
1✔
126
                return;
127
        }
128

129
        (void) terminal_reset_defensive_locked(STDOUT_FILENO, /* flags= */ 0);
6✔
130

131
        if (arg_chrome)
6✔
132
                chrome_show("Initial Setup", /* bottom= */ NULL);
6✔
133

134
        r = parse_os_release_at(rfd,
6✔
135
                                "PRETTY_NAME", &pretty_name,
136
                                "NAME", &os_name,
137
                                "ANSI_COLOR", &ansi_color);
138
        if (r < 0)
6✔
139
                log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
6✔
140
                               "Failed to read os-release file, ignoring: %m");
141

142
        pn = os_release_pretty_name(pretty_name, os_name);
6✔
143
        ac = isempty(ansi_color) ? "0" : ansi_color;
6✔
144

145
        if (colors_enabled())
6✔
146
                printf(ANSI_HIGHLIGHT "Welcome to " ANSI_NORMAL "\x1B[%sm%s" ANSI_HIGHLIGHT "!" ANSI_NORMAL "\n", ac, pn);
×
147
        else
148
                printf("Welcome to %s!\n", pn);
6✔
149

150
        putchar('\n');
6✔
151
        if (emoji_enabled()) {
6✔
152
                fputs(glyph(GLYPH_SPARKLES), stdout);
×
153
                putchar(' ');
×
154
        }
155
        printf("Please configure the system!\n\n");
6✔
156

157
        done = true;
6✔
158
}
159

160
static int should_configure(int dir_fd, const char *filename) {
1,120✔
161
        _cleanup_fclose_ FILE *passwd = NULL, *shadow = NULL;
1,120✔
162
        int r;
1,120✔
163

164
        assert(dir_fd >= 0);
1,120✔
165
        assert(filename);
1,120✔
166

167
        if (streq(filename, "passwd") && !arg_force)
1,120✔
168
                /* We may need to do additional checks, so open the file. */
169
                r = xfopenat(dir_fd, filename, "re", O_NOFOLLOW, &passwd);
137✔
170
        else
171
                r = RET_NERRNO(faccessat(dir_fd, filename, F_OK, AT_SYMLINK_NOFOLLOW));
983✔
172

173
        if (r == -ENOENT)
601✔
174
                return true; /* missing */
175
        if (r < 0)
631✔
176
                return log_error_errno(r, "Failed to access %s: %m", filename);
×
177
        if (arg_force)
631✔
178
                return true; /* exists, but if --force was given we should still configure the file. */
179

180
        if (!passwd)
614✔
181
                return false;
182

183
        /* In case of /etc/passwd, do an additional check for the root password field.
184
         * We first check that passwd redirects to shadow, and then we check shadow.
185
         */
186
        struct passwd *i;
187
        while ((r = fgetpwent_sane(passwd, &i)) > 0) {
112✔
188
                if (!streq(i->pw_name, "root"))
111✔
189
                        continue;
×
190

191
                if (streq_ptr(i->pw_passwd, PASSWORD_SEE_SHADOW))
111✔
192
                        break;
193
                log_debug("passwd: root account with non-shadow password found, treating root as configured");
×
194
                return false;
195
        }
196
        if (r < 0)
112✔
197
                return log_error_errno(r, "Failed to read %s: %m", filename);
×
198
        if (r == 0) {
112✔
199
                log_debug("No root account found in %s, assuming root is not configured.", filename);
1✔
200
                return true;
1✔
201
        }
202

203
        r = xfopenat(dir_fd, "shadow", "re", O_NOFOLLOW, &shadow);
111✔
204
        if (r == -ENOENT) {
111✔
205
                log_debug("No shadow file found, assuming root is not configured.");
×
206
                return true; /* missing */
×
207
        }
208
        if (r < 0)
111✔
209
                return log_error_errno(r, "Failed to access shadow: %m");
×
210

211
        struct spwd *j;
212
        while ((r = fgetspent_sane(shadow, &j)) > 0) {
111✔
213
                if (!streq(j->sp_namp, "root"))
111✔
214
                        continue;
×
215

216
                bool unprovisioned = streq_ptr(j->sp_pwdp, PASSWORD_UNPROVISIONED);
111✔
217
                log_debug("Root account found, %s.",
216✔
218
                          unprovisioned ? "with unprovisioned password, treating root as not configured" :
219
                                          "treating root as configured");
220
                return unprovisioned;
111✔
221
        }
222
        if (r < 0)
×
223
                return log_error_errno(r, "Failed to read shadow: %m");
×
224
        assert(r == 0);
×
225
        log_debug("No root account found in shadow, assuming root is not configured.");
×
226
        return true;
227
}
228

229
static int locale_is_ok(const char *name, void *userdata) {
11✔
230
        int rfd = ASSERT_FD(PTR_TO_FD(userdata)), r;
11✔
231

232
        r = dir_fd_is_root(rfd);
11✔
233
        if (r < 0)
11✔
234
                log_debug_errno(r, "Unable to determine if operating on host root directory, assuming we are: %m");
×
235

236
        return r != 0 ? locale_is_installed(name) > 0 : locale_is_valid(name);
11✔
237
}
238

239
static int prompt_locale(int rfd, sd_varlink **mute_console_link) {
11✔
240
        _cleanup_strv_free_ char **locales = NULL;
×
241
        bool acquired_from_creds = false;
11✔
242
        int r;
11✔
243

244
        assert(rfd >= 0);
11✔
245

246
        if (arg_locale || arg_locale_messages)
11✔
247
                return 0;
248

249
        r = read_credential("firstboot.locale", (void**) &arg_locale, NULL);
6✔
250
        if (r < 0)
6✔
251
                log_debug_errno(r, "Failed to read credential firstboot.locale, ignoring: %m");
5✔
252
        else
253
                acquired_from_creds = true;
254

255
        r = read_credential("firstboot.locale-messages", (void**) &arg_locale_messages, NULL);
6✔
256
        if (r < 0)
6✔
257
                log_debug_errno(r, "Failed to read credential firstboot.locale-messages, ignoring: %m");
5✔
258
        else
259
                acquired_from_creds = true;
260

261
        if (acquired_from_creds) {
5✔
262
                log_debug("Acquired locale from credentials.");
1✔
263
                return 0;
1✔
264
        }
265

266
        if (!arg_prompt_locale) {
5✔
267
                log_debug("Prompting for locale was not requested.");
4✔
268
                return 0;
4✔
269
        }
270

271
        r = get_locales(&locales);
1✔
272
        if (r < 0)
1✔
273
                return log_error_errno(r, "Cannot query locales list: %m");
×
274

275
        if (strv_isempty(locales))
1✔
276
                log_debug("No locales found, skipping locale selection.");
×
277
        else if (strv_length(locales) == 1) {
1✔
278

279
                if (streq(locales[0], SYSTEMD_DEFAULT_LOCALE))
×
280
                        log_debug("Only installed locale is default locale anyway, not setting locale explicitly.");
×
281
                else {
282
                        log_debug("Only a single locale available (%s), selecting it as default.", locales[0]);
×
283

284
                        arg_locale = strdup(locales[0]);
×
285
                        if (!arg_locale)
×
286
                                return log_oom();
×
287

288
                        /* Not setting arg_locale_message here, since it defaults to LANG anyway */
289
                }
290
        } else {
291
                print_welcome(rfd, mute_console_link);
1✔
292

293
                r = prompt_loop("Please enter the new system locale name or number",
2✔
294
                                GLYPH_WORLD,
295
                                locales,
296
                                /* accepted= */ NULL,
297
                                /* ellipsize_percentage= */ 60,
298
                                /* n_columns= */ 3,
299
                                /* column_width= */ 20,
300
                                locale_is_ok,
301
                                /* refresh= */ NULL,
302
                                FD_TO_PTR(rfd),
1✔
303
                                PROMPT_MAY_SKIP|PROMPT_SHOW_MENU,
304
                                &arg_locale);
305
                if (r < 0)
1✔
306
                        return r;
307
                if (isempty(arg_locale))
12✔
308
                        return 0;
309

310
                r = prompt_loop("Please enter the new system message locale name or number",
1✔
311
                                GLYPH_WORLD,
312
                                locales,
313
                                /* accepted= */ NULL,
314
                                /* ellipsize_percentage= */ 60,
315
                                /* n_columns= */ 3,
316
                                /* column_width= */ 20,
317
                                locale_is_ok,
318
                                /* refresh= */ NULL,
319
                                FD_TO_PTR(rfd),
320
                                PROMPT_MAY_SKIP|PROMPT_SHOW_MENU,
321
                                &arg_locale_messages);
322
                if (r < 0)
1✔
323
                        return r;
324

325
                /* Suppress the messages setting if it's the same as the main locale anyway */
326
                if (streq_ptr(arg_locale, arg_locale_messages))
1✔
327
                        arg_locale_messages = mfree(arg_locale_messages);
×
328
        }
329

330
        return 0;
331
}
332

333
static int process_locale(int rfd, sd_varlink **mute_console_link) {
140✔
334
        _cleanup_close_ int pfd = -EBADF;
140✔
335
        _cleanup_free_ char *f = NULL;
140✔
336
        char* locales[3];
140✔
337
        unsigned i = 0;
140✔
338
        int r;
140✔
339

340
        assert(rfd >= 0);
140✔
341

342
        pfd = chase_and_open_parent_at(rfd, rfd, etc_locale_conf(),
140✔
343
                                       CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
344
                                       &f);
345
        if (pfd < 0)
140✔
346
                return log_error_errno(pfd, "Failed to chase /etc/locale.conf: %m");
×
347

348
        r = should_configure(pfd, f);
140✔
349
        if (r == 0)
140✔
350
                log_debug("Found /etc/locale.conf, assuming locale information has been configured.");
126✔
351
        if (r <= 0)
140✔
352
                return r;
353

354
        r = dir_fd_is_root(rfd);
14✔
355
        if (r < 0)
14✔
356
                return log_error_errno(r, "Failed to check if directory file descriptor is root: %m");
×
357

358
        if (arg_copy_locale && r == 0) {
14✔
359
                r = copy_file_atomic_at(AT_FDCWD, etc_locale_conf(), pfd, f, 0644, COPY_REFLINK);
3✔
360
                if (r != -ENOENT) {
3✔
361
                        if (r < 0)
3✔
362
                                return log_error_errno(r, "Failed to copy host's /etc/locale.conf: %m");
×
363

364
                        log_info("Copied host's /etc/locale.conf.");
3✔
365
                        return 0;
3✔
366
                }
367
        }
368

369
        r = prompt_locale(rfd, mute_console_link);
11✔
370
        if (r < 0)
11✔
371
                return r;
372

373
        if (!isempty(arg_locale))
11✔
374
                locales[i++] = strjoina("LANG=", arg_locale);
30✔
375
        if (!isempty(arg_locale_messages) && !streq_ptr(arg_locale_messages, arg_locale))
16✔
376
                locales[i++] = strjoina("LC_MESSAGES=", arg_locale_messages);
25✔
377

378
        if (i == 0)
11✔
379
                return 0;
380

381
        locales[i] = NULL;
7✔
382

383
        r = write_env_file(
7✔
384
                        pfd,
385
                        f,
386
                        /* headers= */ NULL,
387
                        locales,
388
                        WRITE_ENV_FILE_LABEL);
389
        if (r < 0)
7✔
390
                return log_error_errno(r, "Failed to write /etc/locale.conf: %m");
×
391

392
        log_info("/etc/locale.conf written.");
7✔
393
        return 1;
394
}
395

396
static int keymap_is_ok(const char* name, void *userdata) {
5✔
397
        int rfd = ASSERT_FD(PTR_TO_FD(userdata)), r;
5✔
398

399
        r = dir_fd_is_root(rfd);
5✔
400
        if (r < 0)
5✔
401
                log_debug_errno(r, "Unable to determine if operating on host root directory, assuming we are: %m");
×
402

403
        return r != 0 ? keymap_exists(name) > 0 : keymap_is_valid(name);
5✔
404
}
405

406
static int prompt_keymap(int rfd, sd_varlink **mute_console_link) {
19✔
407
        _cleanup_strv_free_ char **kmaps = NULL;
19✔
408
        int r;
19✔
409

410
        assert(rfd >= 0);
19✔
411

412
        if (arg_keymap)
19✔
413
                return 0;
414

415
        _cleanup_free_ char *km = NULL;
16✔
416
        r = read_credential("firstboot.keymap", (void**) &km, NULL);
16✔
417
        if (r < 0)
16✔
418
                log_debug_errno(r, "Failed to read credential firstboot.keymap, ignoring: %m");
15✔
419
        else if (!keymap_is_valid(km))
1✔
420
                log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Keymap '%s' supplied via credential is not valid, ignoring.", km);
×
421
        else {
422
                log_debug("Acquired keymap from credential.");
1✔
423
                arg_keymap = TAKE_PTR(km);
1✔
424
                return 0;
1✔
425
        }
426

427
        bool b;
15✔
428
        if (arg_prompt_keymap_auto) {
15✔
429
                _cleanup_free_ char *ttyname = NULL;
1✔
430

431
                r = getttyname_harder(STDOUT_FILENO, &ttyname);
1✔
432
                if (r < 0) {
1✔
433
                        log_debug_errno(r, "Cannot determine TTY we are connected, ignoring: %m");
1✔
434
                        b = false; /* if we can't resolve this, it's probably not a VT */
435
                } else {
436
                        b = tty_is_vc_resolve(ttyname);
×
437
                        log_debug("Detected connection to local console: %s", yes_no(b));
×
438
                }
439
        } else
440
                b = arg_prompt_keymap;
14✔
441
        if (!b) {
15✔
442
                log_debug("Prompting for keymap was not requested.");
14✔
443
                return 0;
14✔
444
        }
445

446
        r = get_keymaps(&kmaps);
1✔
447
        if (r == -ENOENT) /* no keymaps installed */
1✔
448
                return log_debug_errno(r, "No keymaps are installed.");
×
449
        if (r < 0)
1✔
450
                return log_error_errno(r, "Failed to read keymaps: %m");
×
451

452
        print_welcome(rfd, mute_console_link);
1✔
453

454
        return prompt_loop(
1✔
455
                        "Please enter the new keymap name or number",
456
                        GLYPH_KEYBOARD,
457
                        kmaps,
458
                        /* accepted= */ NULL,
459
                        /* ellipsize_percentage= */ 60,
460
                        /* n_columns= */ 3,
461
                        /* column_width= */ 20,
462
                        keymap_is_ok,
463
                        /* refresh= */ NULL,
464
                        FD_TO_PTR(rfd),
1✔
465
                        PROMPT_MAY_SKIP|PROMPT_SHOW_MENU,
466
                        &arg_keymap);
467
}
468

469
static int process_keymap(int rfd, sd_varlink **mute_console_link) {
140✔
470
        _cleanup_close_ int pfd = -EBADF;
140✔
471
        _cleanup_free_ char *f = NULL;
140✔
472
        _cleanup_strv_free_ char **keymap = NULL;
×
473
        int r;
140✔
474

475
        assert(rfd >= 0);
140✔
476

477
        pfd = chase_and_open_parent_at(rfd, rfd, etc_vconsole_conf(),
140✔
478
                                       CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
479
                                       &f);
480
        if (pfd < 0)
140✔
481
                return log_error_errno(pfd, "Failed to chase /etc/vconsole.conf: %m");
×
482

483
        r = should_configure(pfd, f);
140✔
484
        if (r == 0)
140✔
485
                log_debug("Found /etc/vconsole.conf, assuming console has been configured.");
118✔
486
        if (r <= 0)
140✔
487
                return r;
488

489
        r = dir_fd_is_root(rfd);
22✔
490
        if (r < 0)
22✔
491
                return log_error_errno(r, "Failed to check if directory file descriptor is root: %m");
×
492

493
        if (arg_copy_keymap && r == 0) {
22✔
494
                r = copy_file_atomic_at(AT_FDCWD, etc_vconsole_conf(), pfd, f, 0644, COPY_REFLINK);
3✔
495
                if (r != -ENOENT) {
3✔
496
                        if (r < 0)
3✔
497
                                return log_error_errno(r, "Failed to copy host's /etc/vconsole.conf: %m");
×
498

499
                        log_info("Copied host's /etc/vconsole.conf.");
3✔
500
                        return 0;
3✔
501
                }
502
        }
503

504
        r = prompt_keymap(rfd, mute_console_link);
19✔
505
        if (r == -ENOENT)
19✔
506
                return 0; /* don't fail if no keymaps are installed */
507
        if (r < 0)
19✔
508
                return r;
509

510
        if (isempty(arg_keymap))
145✔
511
                return 0;
512

513
        VCContext vc = {
5✔
514
                .keymap = arg_keymap,
515
        };
516
        _cleanup_(x11_context_clear) X11Context xc = {};
5✔
517

518
        r = vconsole_convert_to_x11(&vc, /* verify= */ NULL, &xc);
5✔
519
        if (r < 0)
5✔
520
                return log_error_errno(r, "Failed to convert keymap data: %m");
×
521

522
        r = vconsole_serialize(&vc, &xc, &keymap);
5✔
523
        if (r < 0)
5✔
524
                return log_error_errno(r, "Failed to serialize keymap data: %m");
×
525

526
        r = write_vconsole_conf(pfd, f, keymap);
5✔
527
        if (r < 0)
5✔
528
                return log_error_errno(r, "Failed to write /etc/vconsole.conf: %m");
×
529

530
        log_info("/etc/vconsole.conf written.");
5✔
531
        return 1;
532
}
533

534
static int timezone_is_ok(const char *name, void *userdata) {
1✔
535
        return timezone_is_valid(name, LOG_DEBUG);
1✔
536
}
537

538
static int prompt_timezone(int rfd, sd_varlink **mute_console_link) {
121✔
539
        _cleanup_strv_free_ char **zones = NULL;
121✔
540
        int r;
121✔
541

542
        assert(rfd >= 0);
121✔
543

544
        if (arg_timezone)
121✔
545
                return 0;
546

547
        _cleanup_free_ char *tz = NULL;
118✔
548
        r = read_credential("firstboot.timezone", (void**) &tz, NULL);
118✔
549
        if (r < 0)
118✔
550
                log_debug_errno(r, "Failed to read credential firstboot.timezone, ignoring: %m");
12✔
551
        else if (!timezone_is_valid(tz, LOG_DEBUG))
106✔
552
                log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Timezone '%s' supplied via credential is not valid, ignoring.", tz);
×
553
        else {
554
                log_debug("Acquired timezone from credential.");
106✔
555
                arg_timezone = TAKE_PTR(tz);
106✔
556
                return 0;
106✔
557
        }
558

559
        if (!arg_prompt_timezone) {
12✔
560
                log_debug("Prompting for timezone was not requested.");
11✔
561
                return 0;
11✔
562
        }
563

564
        r = get_timezones(&zones);
1✔
565
        if (r < 0)
1✔
566
                return log_error_errno(r, "Cannot query timezone list: %m");
×
567

568
        print_welcome(rfd, mute_console_link);
1✔
569

570
        return prompt_loop(
1✔
571
                        "Please enter the new timezone name or number",
572
                        GLYPH_CLOCK,
573
                        zones,
574
                        /* accepted= */ NULL,
575
                        /* ellipsize_percentage= */ 30,
576
                        /* n_columns= */ 3,
577
                        /* column_width= */ 20,
578
                        timezone_is_ok,
579
                        /* refresh= */ NULL,
580
                        FD_TO_PTR(rfd),
1✔
581
                        PROMPT_MAY_SKIP|PROMPT_SHOW_MENU,
582
                        &arg_timezone);
583
}
584

585
static int process_timezone(int rfd, sd_varlink **mute_console_link) {
140✔
586
        _cleanup_close_ int pfd = -EBADF;
140✔
587
        _cleanup_free_ char *f = NULL, *relpath = NULL;
140✔
588
        const char *e;
140✔
589
        int r;
140✔
590

591
        assert(rfd >= 0);
140✔
592

593
        pfd = chase_and_open_parent_at(rfd, rfd, etc_localtime(),
140✔
594
                                       CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
595
                                       &f);
596
        if (pfd < 0)
140✔
597
                return log_error_errno(pfd, "Failed to chase /etc/localtime: %m");
×
598

599
        r = should_configure(pfd, f);
140✔
600
        if (r == 0)
140✔
601
                log_debug("Found /etc/localtime, assuming timezone has been configured.");
16✔
602
        if (r <= 0)
140✔
603
                return r;
604

605
        r = dir_fd_is_root(rfd);
124✔
606
        if (r < 0)
124✔
607
                return log_error_errno(r, "Failed to check if directory file descriptor is root: %m");
×
608

609
        if (arg_copy_timezone && r == 0) {
124✔
610
                _cleanup_free_ char *s = NULL;
3✔
611

612
                r = readlink_malloc(etc_localtime(), &s);
3✔
613
                if (r != -ENOENT) {
3✔
614
                        if (r < 0)
3✔
615
                                return log_error_errno(r, "Failed to read host's /etc/localtime: %m");
×
616

617
                        r = symlinkat_atomic_full(s, pfd, f, SYMLINK_LABEL);
3✔
618
                        if (r < 0)
3✔
619
                                return log_error_errno(r, "Failed to create /etc/localtime symlink: %m");
×
620

621
                        log_info("Copied host's /etc/localtime.");
3✔
622
                        return 0;
3✔
623
                }
624
        }
625

626
        r = prompt_timezone(rfd, mute_console_link);
121✔
627
        if (r < 0)
121✔
628
                return r;
629

630
        if (isempty(arg_timezone))
250✔
631
                return 0;
632

633
        e = strjoina("/usr/share/zoneinfo/", arg_timezone);
550✔
634
        r = path_make_relative_parent(etc_localtime(), e, &relpath);
110✔
635
        if (r < 0)
110✔
636
                return r;
637

638
        r = symlinkat_atomic_full(relpath, pfd, f, SYMLINK_LABEL);
110✔
639
        if (r < 0)
110✔
640
                return log_error_errno(r, "Failed to create /etc/localtime symlink: %m");
×
641

642
        log_info("/etc/localtime written");
110✔
643
        return 0;
644
}
645

646
static int hostname_is_ok(const char *name, void *userdata) {
1✔
647
        return hostname_is_valid(name, VALID_HOSTNAME_TRAILING_DOT);
1✔
648
}
649

650
static int prompt_hostname(int rfd, sd_varlink **mute_console_link) {
126✔
651
        int r;
126✔
652

653
        assert(rfd >= 0);
126✔
654

655
        if (arg_hostname)
126✔
656
                return 0;
126✔
657

658
        _cleanup_free_ char *hn = NULL;
122✔
659
        r = read_credential("firstboot.hostname", (void**) &hn, NULL);
122✔
660
        if (r < 0)
122✔
661
                log_debug_errno(r, "Failed to read credential firstboot.hostname, ignoring: %m");
122✔
662
        else if (!hostname_is_valid(hn, VALID_HOSTNAME_TRAILING_DOT|VALID_HOSTNAME_QUESTION_MARK))
×
663
                log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Hostname '%s' supplied via credential is not valid, ignoring.", hn);
×
664
        else {
665
                log_debug("Acquired hostname from credentials.");
×
666
                arg_hostname = TAKE_PTR(hn);
×
667
                hostname_cleanup(arg_hostname);
×
668
                return 0;
669
        }
670

671
        if (!arg_prompt_hostname) {
122✔
672
                log_debug("Prompting for hostname was not requested.");
121✔
673
                return 0;
121✔
674
        }
675

676
        print_welcome(rfd, mute_console_link);
1✔
677

678
        r = prompt_loop("Please enter the new hostname",
2✔
679
                        GLYPH_LABEL,
680
                        /* menu= */ NULL,
681
                        /* accepted= */ NULL,
682
                        /* ellipsize_percentage= */ 100,
683
                        /* n_columns= */ 3,
684
                        /* column_width= */ 20,
685
                        hostname_is_ok,
686
                        /* refresh= */ NULL,
687
                        FD_TO_PTR(rfd),
1✔
688
                        PROMPT_MAY_SKIP,
689
                        &arg_hostname);
690
        if (r < 0)
1✔
691
                return r;
692

693
        if (arg_hostname)
1✔
694
                hostname_cleanup(arg_hostname);
1✔
695

696
        return 0;
697
}
698

699
static int process_hostname(int rfd, sd_varlink **mute_console_link) {
140✔
700
        _cleanup_close_ int pfd = -EBADF;
140✔
701
        _cleanup_free_ char *f = NULL;
140✔
702
        int r;
140✔
703

704
        assert(rfd >= 0);
140✔
705

706
        pfd = chase_and_open_parent_at(rfd, rfd, etc_hostname(), CHASE_MKDIR_0755|CHASE_WARN, &f);
140✔
707
        if (pfd < 0)
140✔
708
                return log_error_errno(pfd, "Failed to chase /etc/hostname: %m");
×
709

710
        r = should_configure(pfd, f);
140✔
711
        if (r == 0)
140✔
712
                log_debug("Found /etc/hostname, assuming hostname has been configured.");
14✔
713
        if (r <= 0)
140✔
714
                return r;
715

716
        r = prompt_hostname(rfd, mute_console_link);
126✔
717
        if (r < 0)
126✔
718
                return r;
719

720
        if (isempty(arg_hostname))
145✔
721
                return 0;
722

723
        r = write_string_file_at(pfd, f, arg_hostname,
5✔
724
                                 WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_SYNC|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
725
        if (r < 0)
5✔
726
                return log_error_errno(r, "Failed to write /etc/hostname: %m");
×
727

728
        log_info("/etc/hostname written.");
5✔
729
        return 0;
730
}
731

732
static int process_machine_id(int rfd) {
140✔
733
        _cleanup_close_ int pfd = -EBADF;
140✔
734
        _cleanup_free_ char *f = NULL;
140✔
735
        int r;
140✔
736

737
        assert(rfd >= 0);
140✔
738

739
        pfd = chase_and_open_parent_at(rfd, rfd, "/etc/machine-id",
140✔
740
                                       CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
741
                                       &f);
742
        if (pfd < 0)
140✔
743
                return log_error_errno(pfd, "Failed to chase /etc/machine-id: %m");
×
744

745
        r = should_configure(pfd, f);
140✔
746
        if (r == 0)
140✔
747
                log_debug("Found /etc/machine-id, assuming machine-id has been configured.");
115✔
748
        if (r <= 0)
140✔
749
                return r;
750

751
        if (sd_id128_is_null(arg_machine_id)) {
25✔
752
                log_debug("Initialization of machine-id was not requested, skipping.");
22✔
753
                return 0;
22✔
754
        }
755

756
        r = write_string_file_at(pfd, "machine-id", SD_ID128_TO_STRING(arg_machine_id),
3✔
757
                                 WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_SYNC|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
758
        if (r < 0)
3✔
759
                return log_error_errno(r, "Failed to write /etc/machine-id: %m");
×
760

761
        log_info("/etc/machine-id written.");
3✔
762
        return 0;
763
}
764

765
static int prompt_root_password(int rfd, sd_varlink **mute_console_link) {
30✔
766
        const char *msg1, *msg2;
30✔
767
        int r;
30✔
768

769
        assert(rfd >= 0);
30✔
770

771
        if (arg_root_password)
30✔
772
                return 0;
773

774
        if (get_credential_user_password("root", &arg_root_password, &arg_root_password_is_hashed) >= 0)
21✔
775
                return 0;
776

777
        if (!arg_prompt_root_password) {
20✔
778
                log_debug("Prompting for root password was not requested.");
19✔
779
                return 0;
19✔
780
        }
781

782
        print_welcome(rfd, mute_console_link);
1✔
783

784
        msg1 = "Please enter the new root password (empty to skip):";
1✔
785
        msg2 = "Please enter the new root password again:";
1✔
786

787
        suggest_passwords();
1✔
788

789
        for (;;) {
×
790
                _cleanup_strv_free_erase_ char **a = NULL, **b = NULL;
1✔
791
                _cleanup_free_ char *error = NULL;
1✔
792

793
                AskPasswordRequest req = {
1✔
794
                        .tty_fd = -EBADF,
795
                        .message = msg1,
796
                        .until = USEC_INFINITY,
797
                        .hup_fd = -EBADF,
798
                };
799

800
                r = ask_password_tty(&req, /* flags= */ 0, &a);
1✔
801
                if (r < 0)
1✔
802
                        return log_error_errno(r, "Failed to query root password: %m");
×
803
                if (strv_length(a) != 1)
1✔
804
                        return log_error_errno(SYNTHETIC_ERRNO(EIO),
×
805
                                               "Received multiple passwords, where we expected one.");
806

807
                if (isempty(*a)) {
1✔
808
                        log_info("No password entered, skipping.");
1✔
809
                        break;
810
                }
811

812
                r = check_password_quality(*a, /* old= */ NULL, "root", &error);
×
813
                if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
×
814
                        log_warning("Password quality check is not supported, proceeding anyway.");
×
815
                else if (r < 0)
×
816
                        return log_error_errno(r, "Failed to check password quality: %m");
×
817
                else if (r == 0)
×
818
                        log_warning("Password is weak, accepting anyway: %s", error);
×
819

820
                req.message = msg2;
×
821

822
                r = ask_password_tty(&req, /* flags= */ 0, &b);
×
823
                if (r < 0)
×
824
                        return log_error_errno(r, "Failed to query root password: %m");
×
825
                if (strv_length(b) != 1)
×
826
                        return log_error_errno(SYNTHETIC_ERRNO(EIO),
×
827
                                               "Received multiple passwords, where we expected one.");
828

829
                if (!streq(*a, *b)) {
×
830
                        log_error("Entered passwords did not match, please try again.");
×
831
                        continue;
×
832
                }
833

834
                arg_root_password = TAKE_PTR(*a);
×
835
                break;
×
836
        }
837

838
        return 0;
1✔
839
}
840

841
static int find_shell(int rfd, const char *path) {
7✔
842
        int r;
7✔
843

844
        assert(path);
7✔
845

846
        if (!valid_shell(path))
7✔
847
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "%s is not a valid shell", path);
×
848

849
        r = chaseat(rfd, rfd, path, /* flags= */ 0, /* ret_path= */ NULL, /* ret_fd= */ NULL);
7✔
850
        if (r < 0)
7✔
851
                return log_error_errno(r, "Failed to resolve shell %s: %m", path);
1✔
852

853
        return 0;
854
}
855

856
static int shell_is_ok(const char *path, void *userdata) {
2✔
857
        int rfd = ASSERT_FD(PTR_TO_FD(userdata));
2✔
858

859
        return find_shell(rfd, path) >= 0;
2✔
860
}
861

862
static int prompt_root_shell(int rfd, sd_varlink **mute_console_link) {
30✔
863
        int r;
30✔
864

865
        assert(rfd >= 0);
30✔
866

867
        if (arg_root_shell)
30✔
868
                return 0;
869

870
        r = read_credential("passwd.shell.root", (void**) &arg_root_shell, NULL);
25✔
871
        if (r < 0)
25✔
872
                log_debug_errno(r, "Failed to read credential passwd.shell.root, ignoring: %m");
24✔
873
        else {
874
                log_debug("Acquired root shell from credential.");
1✔
875
                return 0;
1✔
876
        }
877

878
        if (!arg_prompt_root_shell) {
24✔
879
                log_debug("Prompting for root shell was not requested.");
22✔
880
                return 0;
22✔
881
        }
882

883
        print_welcome(rfd, mute_console_link);
2✔
884

885
        return prompt_loop(
2✔
886
                        "Please enter the new root shell",
887
                        GLYPH_SHELL,
888
                        /* menu= */ NULL,
889
                        /* accepted= */ NULL,
890
                        /* ellipsize_percentage= */ 0,
891
                        /* n_columns= */ 3,
892
                        /* column_width= */ 20,
893
                        shell_is_ok,
894
                        /* refresh= */ NULL,
895
                        FD_TO_PTR(rfd),
2✔
896
                        PROMPT_MAY_SKIP,
897
                        &arg_root_shell);
898
}
899

900
static int write_root_passwd(int rfd, int etc_fd, const char *password, const char *shell) {
15✔
901
        _cleanup_fclose_ FILE *original = NULL, *passwd = NULL;
15✔
902
        _cleanup_(unlink_and_freep) char *passwd_tmp = NULL;
15✔
903
        int r;
15✔
904
        bool found = false;
15✔
905

906
        r = fopen_temporary_at_label(etc_fd, "passwd", "passwd", &passwd, &passwd_tmp);
15✔
907
        if (r < 0)
15✔
908
                return r;
909

910
        r = xfopenat(etc_fd, "passwd", "re", O_NOFOLLOW, &original);
15✔
911
        if (r < 0 && r != -ENOENT)
15✔
912
                return r;
913

914
        if (original) {
15✔
915
                struct passwd *i;
4✔
916

917
                r = copy_rights(fileno(original), fileno(passwd));
4✔
918
                if (r < 0)
4✔
919
                        return r;
×
920

921
                while ((r = fgetpwent_sane(original, &i)) > 0) {
7✔
922

923
                        if (streq(i->pw_name, "root")) {
3✔
924
                                if (password)
3✔
925
                                        i->pw_passwd = (char *) password;
2✔
926
                                if (shell)
3✔
927
                                        i->pw_shell = (char *) shell;
2✔
928
                                found = true;
929
                        }
930

931
                        r = putpwent_sane(i, passwd);
3✔
932
                        if (r < 0)
3✔
933
                                return r;
934
                }
935
                if (r < 0)
4✔
936
                        return r;
937

938
        } else {
939
                r = fchmod(fileno(passwd), 0644);
11✔
940
                if (r < 0)
11✔
941
                        return -errno;
×
942
        }
943

944
        if (!found) {
4✔
945
                struct passwd root = {
12✔
946
                        .pw_name = (char *) "root",
947
                        .pw_passwd = (char *) (password ?: PASSWORD_SEE_SHADOW),
12✔
948
                        .pw_uid = 0,
949
                        .pw_gid = 0,
950
                        .pw_gecos = (char *) "Super User",
951
                        .pw_dir = (char *) "/root",
952
                        .pw_shell = (char *) (shell ?: default_root_shell_at(rfd)),
6✔
953
                };
954

955
                r = putpwent_sane(&root, passwd);
12✔
956
                if (r < 0)
12✔
957
                        return r;
×
958
        }
959

960
        r = fflush_sync_and_check(passwd);
15✔
961
        if (r < 0)
15✔
962
                return r;
963

964
        r = renameat_and_apply_smack_floor_label(etc_fd, passwd_tmp, etc_fd, "passwd");
15✔
965
        if (r < 0)
15✔
966
                return r;
×
967

968
        return 0;
969
}
970

971
static int write_root_shadow(int etc_fd, const char *hashed_password) {
15✔
972
        _cleanup_fclose_ FILE *original = NULL, *shadow = NULL;
15✔
973
        _cleanup_(unlink_and_freep) char *shadow_tmp = NULL;
15✔
974
        int r;
15✔
975
        bool found = false;
15✔
976

977
        r = fopen_temporary_at_label(etc_fd, "shadow", "shadow", &shadow, &shadow_tmp);
15✔
978
        if (r < 0)
15✔
979
                return r;
980

981
        r = xfopenat(etc_fd, "shadow", "re", O_NOFOLLOW, &original);
15✔
982
        if (r < 0 && r != -ENOENT)
15✔
983
                return r;
984

985
        if (original) {
15✔
986
                struct spwd *i;
4✔
987

988
                r = copy_rights(fileno(original), fileno(shadow));
4✔
989
                if (r < 0)
4✔
990
                        return r;
×
991

992
                while ((r = fgetspent_sane(original, &i)) > 0) {
7✔
993

994
                        if (streq(i->sp_namp, "root")) {
3✔
995
                                if (hashed_password) {
3✔
996
                                        i->sp_pwdp = (char *) hashed_password;
2✔
997
                                        i->sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
2✔
998
                                }
999
                                found = true;
1000
                        }
1001

1002
                        r = putspent_sane(i, shadow);
3✔
1003
                        if (r < 0)
3✔
1004
                                return r;
1005
                }
1006
                if (r < 0)
4✔
1007
                        return r;
1008

1009
        } else {
1010
                r = fchmod(fileno(shadow), 0000);
11✔
1011
                if (r < 0)
11✔
1012
                        return -errno;
×
1013
        }
1014

1015
        if (!found) {
4✔
1016
                struct spwd root = {
36✔
1017
                        .sp_namp = (char*) "root",
1018
                        .sp_pwdp = (char *) (hashed_password ?: PASSWORD_LOCKED_AND_INVALID),
12✔
1019
                        .sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY),
12✔
1020
                        .sp_min = -1,
1021
                        .sp_max = -1,
1022
                        .sp_warn = -1,
1023
                        .sp_inact = -1,
1024
                        .sp_expire = -1,
1025
                        .sp_flag = ULONG_MAX, /* this appears to be what everybody does ... */
1026
                };
1027

1028
                r = putspent_sane(&root, shadow);
12✔
1029
                if (r < 0)
12✔
1030
                        return r;
×
1031
        }
1032

1033
        r = fflush_sync_and_check(shadow);
15✔
1034
        if (r < 0)
15✔
1035
                return r;
1036

1037
        r = renameat_and_apply_smack_floor_label(etc_fd, shadow_tmp, etc_fd, "shadow");
15✔
1038
        if (r < 0)
15✔
1039
                return r;
×
1040

1041
        return 0;
1042
}
1043

1044
static int process_root_account(int rfd, sd_varlink **mute_console_link) {
140✔
1045
        _cleanup_close_ int pfd = -EBADF;
140✔
1046
        _cleanup_(release_lock_file) LockFile lock = LOCK_FILE_INIT;
×
1047
        _cleanup_(erase_and_freep) char *_hashed_password = NULL;
140✔
1048
        const char *password, *hashed_password;
140✔
1049
        int k = 0, r;
140✔
1050

1051
        assert(rfd >= 0);
140✔
1052

1053
        pfd = chase_and_open_parent_at(rfd, rfd, "/etc/passwd",
140✔
1054
                                       CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
1055
                                       NULL);
1056
        if (pfd < 0)
140✔
1057
                return log_error_errno(pfd, "Failed to chase /etc/passwd: %m");
×
1058

1059
        /* Ensure that passwd and shadow are in the same directory and are not symlinks. */
1060

1061
        FOREACH_STRING(s, "passwd", "shadow") {
420✔
1062
                r = verify_regular_at(pfd, s, /* follow= */ false);
280✔
1063
                if (r < 0 && r != -ENOENT)
280✔
1064
                        return log_error_errno(r, "Verification of /etc/%s being regular file failed: %m", s);
×
1065

1066
                r = should_configure(pfd, s);
280✔
1067
                if (r < 0)
280✔
1068
                        return r;
1069

1070
                k += r;
280✔
1071
        }
1072

1073
        if (k == 0) {
140✔
1074
                log_debug("Found /etc/passwd and /etc/shadow, assuming root account has been initialized.");
110✔
1075
                return 0;
110✔
1076
        }
1077

1078
        r = make_lock_file_at(pfd, ETC_PASSWD_LOCK_FILENAME, LOCK_EX, &lock);
30✔
1079
        if (r < 0)
30✔
1080
                return log_error_errno(r, "Failed to take a lock on /etc/passwd: %m");
×
1081

1082
        k = dir_fd_is_root(rfd);
30✔
1083
        if (k < 0)
30✔
1084
                return log_error_errno(k, "Failed to check if directory file descriptor is root: %m");
×
1085

1086
        if (arg_copy_root_shell && k == 0) {
30✔
1087
                _cleanup_free_ struct passwd *p = NULL;
2✔
1088

1089
                r = getpwnam_malloc("root", &p);
2✔
1090
                if (r < 0)
2✔
1091
                        return log_error_errno(r, "Failed to find passwd entry for root: %m");
×
1092

1093
                r = free_and_strdup(&arg_root_shell, p->pw_shell);
2✔
1094
                if (r < 0)
2✔
1095
                        return log_oom();
×
1096
        }
1097

1098
        r = prompt_root_shell(rfd, mute_console_link);
30✔
1099
        if (r < 0)
30✔
1100
                return r;
1101

1102
        if (arg_copy_root_password && k == 0) {
30✔
1103
                struct spwd *p;
2✔
1104

1105
                errno = 0;
2✔
1106
                p = getspnam("root");
2✔
1107
                if (!p)
2✔
1108
                        return log_error_errno(errno_or_else(EIO), "Failed to find shadow entry for root: %m");
×
1109

1110
                r = free_and_strdup(&arg_root_password, p->sp_pwdp);
2✔
1111
                if (r < 0)
2✔
1112
                        return log_oom();
×
1113

1114
                arg_root_password_is_hashed = true;
2✔
1115
        }
1116

1117
        r = prompt_root_password(rfd, mute_console_link);
30✔
1118
        if (r < 0)
30✔
1119
                return r;
1120

1121
        if (arg_root_password && arg_root_password_is_hashed) {
30✔
1122
                password = PASSWORD_SEE_SHADOW;
1123
                hashed_password = arg_root_password;
1124
        } else if (arg_root_password) {
24✔
1125
                r = hash_password(arg_root_password, &_hashed_password);
4✔
1126
                if (r < 0)
4✔
1127
                        return log_error_errno(r, "Failed to hash password: %m");
×
1128

1129
                password = PASSWORD_SEE_SHADOW;
4✔
1130
                hashed_password = _hashed_password;
4✔
1131

1132
        } else if (arg_delete_root_password) {
20✔
1133
                password = PASSWORD_SEE_SHADOW;
1134
                hashed_password = PASSWORD_NONE;
1135
        } else if (!arg_root_password && arg_prompt_root_password) {
19✔
1136
                /* If the user was prompted, but no password was supplied, lock the account. */
1137
                password = PASSWORD_SEE_SHADOW;
1138
                hashed_password = PASSWORD_LOCKED_AND_INVALID;
1139
        } else
1140
                /* Leave the password as is. */
1141
                password = hashed_password = NULL;
18✔
1142

1143
        /* Don't create/modify passwd and shadow if there's nothing to do. */
1144
        if (!(password || hashed_password || arg_root_shell)) {
30✔
1145
                log_debug("Initialization of root account was not requested, skipping.");
15✔
1146
                return 0;
15✔
1147
        }
1148

1149
        r = write_root_passwd(rfd, pfd, password, arg_root_shell);
15✔
1150
        if (r < 0)
15✔
1151
                return log_error_errno(r, "Failed to write /etc/passwd: %m");
×
1152

1153
        log_info("/etc/passwd written.");
15✔
1154

1155
        r = write_root_shadow(pfd, hashed_password);
15✔
1156
        if (r < 0)
15✔
1157
                return log_error_errno(r, "Failed to write /etc/shadow: %m");
×
1158

1159
        log_info("/etc/shadow written.");
15✔
1160
        return 0;
1161
}
1162

1163
static int process_kernel_cmdline(int rfd) {
140✔
1164
        _cleanup_close_ int pfd = -EBADF;
140✔
1165
        _cleanup_free_ char *f = NULL;
140✔
1166
        int r;
140✔
1167

1168
        assert(rfd >= 0);
140✔
1169

1170
        pfd = chase_and_open_parent_at(rfd, rfd, "/etc/kernel/cmdline",
140✔
1171
                                       CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
1172
                                       &f);
1173
        if (pfd < 0)
140✔
1174
                return log_error_errno(pfd, "Failed to chase /etc/kernel/cmdline: %m");
×
1175

1176
        r = should_configure(pfd, f);
140✔
1177
        if (r == 0)
140✔
1178
                log_debug("Found /etc/kernel/cmdline, assuming kernel command line has been configured.");
1✔
1179
        if (r <= 0)
140✔
1180
                return r;
1181

1182
        if (!arg_kernel_cmdline) {
139✔
1183
                log_debug("Creation of /etc/kernel/cmdline was not requested, skipping.");
137✔
1184
                return 0;
137✔
1185
        }
1186

1187
        r = write_string_file_at(pfd, "cmdline", arg_kernel_cmdline,
2✔
1188
                                 WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_SYNC|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
1189
        if (r < 0)
2✔
1190
                return log_error_errno(r, "Failed to write /etc/kernel/cmdline: %m");
×
1191

1192
        log_info("/etc/kernel/cmdline written.");
2✔
1193
        return 0;
1194
}
1195

1196
static int reset_one(int rfd, const char *path) {
6✔
1197
        _cleanup_close_ int pfd = -EBADF;
6✔
1198
        _cleanup_free_ char *f = NULL;
6✔
1199

1200
        assert(rfd >= 0);
6✔
1201
        assert(path);
6✔
1202

1203
        pfd = chase_and_open_parent_at(rfd, rfd, path, CHASE_WARN|CHASE_NOFOLLOW, &f);
6✔
1204
        if (pfd == -ENOENT)
6✔
1205
                return 0;
1206
        if (pfd < 0)
6✔
1207
                return log_error_errno(pfd, "Failed to resolve %s: %m", path);
×
1208

1209
        if (unlinkat(pfd, f, 0) < 0)
6✔
1210
                return errno == ENOENT ? 0 : log_error_errno(errno, "Failed to remove %s: %m", path);
×
1211

1212
        log_info("Removed %s", path);
6✔
1213
        return 0;
1214
}
1215

1216
static int process_reset(int rfd) {
140✔
1217
        int r;
140✔
1218

1219
        assert(rfd >= 0);
140✔
1220

1221
        if (!arg_reset)
140✔
1222
                return 0;
1223

1224
        FOREACH_STRING(p,
7✔
1225
                       etc_locale_conf(),
1226
                       etc_vconsole_conf(),
1227
                       etc_hostname(),
1228
                       "/etc/machine-id",
1229
                       "/etc/kernel/cmdline",
1230
                       etc_localtime()) {
1231
                r = reset_one(rfd, p);
6✔
1232
                if (r < 0)
6✔
1233
                        return r;
×
1234
        }
1235

1236
        return 0;
1✔
1237
}
1238

1239
static int help(void) {
×
1240
        _cleanup_free_ char *link = NULL;
×
1241
        _cleanup_(table_unrefp) Table *options = NULL;
×
1242
        int r;
×
1243

1244
        r = terminal_urlify_man("systemd-firstboot", "1", &link);
×
1245
        if (r < 0)
×
1246
                return log_oom();
×
1247

1248
        r = option_parser_get_help_table(&options);
×
1249
        if (r < 0)
×
1250
                return r;
1251

1252
        printf("%s [OPTIONS...]\n\n"
×
1253
               "%sConfigures basic settings of the system.%s\n\n",
1254
               program_invocation_short_name,
1255
               ansi_highlight(),
1256
               ansi_normal());
1257

1258
        r = table_print_or_warn(options);
×
1259
        if (r < 0)
×
1260
                return r;
1261

1262
        printf("\nSee the %s for details.\n", link);
×
1263
        return 0;
1264
}
1265

1266
static int parse_argv(int argc, char *argv[]) {
143✔
1267
        assert(argc >= 0);
143✔
1268
        assert(argv);
143✔
1269

1270
        OptionParser opts = { argc, argv };
143✔
1271
        int r;
143✔
1272

1273
        FOREACH_OPTION(c, &opts, /* on_error= */ return c)
921✔
1274
                switch (c) {
637✔
1275

UNCOV
1276
                OPTION_COMMON_HELP:
×
1277
                        return help();
×
1278

UNCOV
1279
                OPTION_COMMON_VERSION:
×
1280
                        return version();
×
1281

1282
                OPTION_LONG("root", "PATH", "Operate on an alternate filesystem root"):
38✔
1283
                        r = parse_path_argument(opts.arg, true, &arg_root);
38✔
1284
                        if (r < 0)
38✔
1285
                                return r;
1286
                        break;
1287

UNCOV
1288
                OPTION_LONG("image", "PATH", "Operate on disk image as filesystem root"):
×
1289
                        r = parse_path_argument(opts.arg, false, &arg_image);
×
1290
                        if (r < 0)
×
1291
                                return r;
1292
                        break;
1293

UNCOV
1294
                OPTION_LONG("image-policy", "POLICY", "Specify disk image dissection policy"):
×
1295
                        r = parse_image_policy_argument(opts.arg, &arg_image_policy);
×
1296
                        if (r < 0)
×
1297
                                return r;
1298
                        break;
1299

1300
                OPTION_LONG("locale", "LOCALE", "Set primary locale (LANG=)"):
5✔
1301
                        r = free_and_strdup_warn(&arg_locale, opts.arg);
5✔
1302
                        if (r < 0)
5✔
1303
                                return r;
1304
                        break;
1305

1306
                OPTION_LONG("locale-messages", "LOCALE", "Set message locale (LC_MESSAGES=)"):
4✔
1307
                        r = free_and_strdup_warn(&arg_locale_messages, opts.arg);
4✔
1308
                        if (r < 0)
4✔
1309
                                return r;
1310
                        break;
1311

1312
                OPTION_LONG("keymap", "KEYMAP", "Set keymap"):
4✔
1313
                        if (!keymap_is_valid(opts.arg))
4✔
UNCOV
1314
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1315
                                                       "Keymap %s is not valid.", opts.arg);
1316

1317
                        r = free_and_strdup_warn(&arg_keymap, opts.arg);
4✔
1318
                        if (r < 0)
4✔
1319
                                return r;
1320
                        break;
1321

1322
                OPTION_LONG("timezone", "TIMEZONE", "Set timezone"):
5✔
1323
                        if (!timezone_is_valid(opts.arg, LOG_ERR))
5✔
1324
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1✔
1325
                                                       "Timezone %s is not valid.", opts.arg);
1326

1327
                        r = free_and_strdup_warn(&arg_timezone, opts.arg);
4✔
1328
                        if (r < 0)
4✔
1329
                                return r;
1330
                        break;
1331

1332
                OPTION_LONG("hostname", "NAME", "Set hostname"):
5✔
1333
                        if (!hostname_is_valid(opts.arg, VALID_HOSTNAME_TRAILING_DOT|VALID_HOSTNAME_QUESTION_MARK))
5✔
UNCOV
1334
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1335
                                                       "Host name %s is not valid.", opts.arg);
1336

1337
                        r = free_and_strdup_warn(&arg_hostname, opts.arg);
5✔
1338
                        if (r < 0)
5✔
1339
                                return r;
1340

1341
                        hostname_cleanup(arg_hostname);
5✔
1342
                        break;
1343

1344
                OPTION_LONG("setup-machine-id", NULL, "Set a random machine ID"):
1✔
1345
                        r = sd_id128_randomize(&arg_machine_id);
1✔
1346
                        if (r < 0)
1✔
UNCOV
1347
                                return log_error_errno(r, "Failed to generate randomized machine ID: %m");
×
1348
                        break;
1349

1350
                OPTION_LONG("machine-id", "ID", "Set specified machine ID"):
4✔
1351
                        r = sd_id128_from_string(opts.arg, &arg_machine_id);
4✔
1352
                        if (r < 0)
4✔
1353
                                return log_error_errno(r, "Failed to parse machine id %s.", opts.arg);
1✔
1354
                        break;
1355

1356
                OPTION_LONG("root-password", "PASSWORD", "Set root password from plaintext password"):
4✔
1357
                        r = free_and_strdup_warn(&arg_root_password, opts.arg);
4✔
1358
                        if (r < 0)
4✔
1359
                                return r;
1360

1361
                        arg_root_password_is_hashed = false;
4✔
1362
                        break;
4✔
1363

1364
                OPTION_LONG("root-password-file", "FILE", "Set root password from file"):
1✔
1365
                        arg_root_password = mfree(arg_root_password);
1✔
1366

1367
                        r = read_one_line_file(opts.arg, &arg_root_password);
1✔
1368
                        if (r < 0)
1✔
UNCOV
1369
                                return log_error_errno(r, "Failed to read %s: %m", opts.arg);
×
1370

1371
                        arg_root_password_is_hashed = false;
1✔
1372
                        break;
1✔
1373

1374
                OPTION_LONG("root-password-hashed", "HASH", "Set root password from hashed password"):
4✔
1375
                        r = free_and_strdup_warn(&arg_root_password, opts.arg);
4✔
1376
                        if (r < 0)
4✔
1377
                                return r;
1378

1379
                        arg_root_password_is_hashed = true;
4✔
1380
                        break;
4✔
1381

1382
                OPTION_LONG("root-shell", "SHELL", "Set root shell"):
5✔
1383
                        r = free_and_strdup_warn(&arg_root_shell, opts.arg);
5✔
1384
                        if (r < 0)
5✔
1385
                                return r;
1386
                        break;
1387

1388
                OPTION_LONG("kernel-command-line", "CMDLINE", "Set kernel command line"):
3✔
1389
                        r = free_and_strdup_warn(&arg_kernel_cmdline, opts.arg);
3✔
1390
                        if (r < 0)
3✔
1391
                                return r;
1392
                        break;
1393

1394
                OPTION_LONG("prompt-locale", NULL, "Prompt the user for locale settings"):
107✔
1395
                        arg_prompt_locale = true;
107✔
1396
                        break;
107✔
1397

1398
                OPTION_LONG("prompt-keymap", NULL, "Prompt the user for keymap settings"):
2✔
1399
                        arg_prompt_keymap = true;
2✔
1400
                        arg_prompt_keymap_auto = false;
2✔
1401
                        break;
2✔
1402

1403
                OPTION_LONG("prompt-keymap-auto", NULL,
106✔
1404
                            "Prompt the user for keymap settings if invoked on local console"):
1405
                        arg_prompt_keymap_auto = true;
106✔
1406
                        break;
106✔
1407

1408
                OPTION_LONG("prompt-timezone", NULL, "Prompt the user for timezone"):
107✔
1409
                        arg_prompt_timezone = true;
107✔
1410
                        break;
107✔
1411

1412
                OPTION_LONG("prompt-hostname", NULL, "Prompt the user for hostname"):
1✔
1413
                        arg_prompt_hostname = true;
1✔
1414
                        break;
1✔
1415

1416
                OPTION_LONG("prompt-root-password", NULL, "Prompt the user for root password"):
107✔
1417
                        arg_prompt_root_password = true;
107✔
1418
                        break;
107✔
1419

1420
                OPTION_LONG("prompt-root-shell", NULL, "Prompt the user for root shell"):
4✔
1421
                        arg_prompt_root_shell = true;
4✔
1422
                        break;
4✔
1423

UNCOV
1424
                OPTION_LONG("prompt", NULL, "Prompt for all of the above"):
×
1425
                        arg_prompt_locale = arg_prompt_keymap = arg_prompt_timezone = arg_prompt_hostname =
×
1426
                                arg_prompt_root_password = arg_prompt_root_shell = true;
×
1427
                        arg_prompt_keymap_auto = false;
×
1428
                        break;
×
1429

1430
                OPTION_LONG("copy-locale", NULL, "Copy locale from host"):
2✔
1431
                        arg_copy_locale = true;
2✔
1432
                        break;
2✔
1433

1434
                OPTION_LONG("copy-keymap", NULL, "Copy keymap from host"):
2✔
1435
                        arg_copy_keymap = true;
2✔
1436
                        break;
2✔
1437

1438
                OPTION_LONG("copy-timezone", NULL, "Copy timezone from host"):
2✔
1439
                        arg_copy_timezone = true;
2✔
1440
                        break;
2✔
1441

1442
                OPTION_LONG("copy-root-password", NULL, "Copy root password from host"):
1✔
1443
                        arg_copy_root_password = true;
1✔
1444
                        break;
1✔
1445

1446
                OPTION_LONG("copy-root-shell", NULL, "Copy root shell from host"):
1✔
1447
                        arg_copy_root_shell = true;
1✔
1448
                        break;
1✔
1449

1450
                OPTION_LONG("copy", NULL, "Copy all of the above"):
1✔
1451
                        arg_copy_locale = arg_copy_keymap = arg_copy_timezone = arg_copy_root_password =
1✔
1452
                                arg_copy_root_shell = true;
1✔
1453
                        break;
1✔
1454

1455
                OPTION_LONG("force", NULL, "Overwrite existing files"):
3✔
1456
                        arg_force = true;
3✔
1457
                        break;
3✔
1458

1459
                OPTION_LONG("delete-root-password", NULL, "Delete root password"):
1✔
1460
                        arg_delete_root_password = true;
1✔
1461
                        break;
1✔
1462

1463
                OPTION_LONG("welcome", "BOOL", "Whether to show the welcome text"):
1✔
1464
                        r = parse_boolean_argument("--welcome=", opts.arg, &arg_welcome);
1✔
1465
                        if (r < 0)
1✔
1466
                                return r;
1467
                        break;
1468

UNCOV
1469
                OPTION_LONG("chrome", "BOOL",
×
1470
                            "Whether to show a color bar at top and bottom of terminal"):
UNCOV
1471
                        r = parse_boolean_argument("--chrome=", opts.arg, &arg_chrome);
×
1472
                        if (r < 0)
×
1473
                                return r;
1474
                        break;
1475

1476
                OPTION_LONG("mute-console", "BOOL",
105✔
1477
                            "Whether to disallow kernel/PID 1 writes to the console while running"):
1478
                        r = parse_boolean_argument("--mute-console=", opts.arg, &arg_mute_console);
105✔
1479
                        if (r < 0)
105✔
1480
                                return r;
1481
                        break;
1482

1483
                OPTION_LONG("reset", NULL, "Remove existing files"):
1✔
1484
                        arg_reset = true;
1✔
1485
                        break;
1✔
1486
                }
1487

1488
        if (arg_delete_root_password && (arg_copy_root_password || arg_root_password || arg_prompt_root_password))
141✔
UNCOV
1489
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1490
                                       "--delete-root-password cannot be combined with other root password options.");
1491

1492
        if (arg_image && arg_root)
141✔
UNCOV
1493
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1494
                                       "--root= and --image= cannot be used together.");
1495

1496
        if (!sd_id128_is_null(arg_machine_id) && !(arg_image || arg_root) && !arg_force)
278✔
UNCOV
1497
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1498
                                       "--machine-id=/--setup-machine-id only works with --root= or --image=.");
1499

1500
        return 1;
1501
}
1502

UNCOV
1503
static int reload_system_manager(sd_bus **bus) {
×
1504
        int r;
×
1505

UNCOV
1506
        assert(bus);
×
1507

UNCOV
1508
        if (!*bus) {
×
1509
                r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, RUNTIME_SCOPE_SYSTEM, bus);
×
1510
                if (r < 0)
×
1511
                        return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL, RUNTIME_SCOPE_SYSTEM);
×
1512
        }
1513

UNCOV
1514
        r = bus_service_manager_reload(*bus);
×
1515
        if (r < 0)
×
1516
                return r;
1517

UNCOV
1518
        log_info("Requested manager reload to apply locale configuration.");
×
1519
        return 0;
1520
}
1521

UNCOV
1522
static int reload_vconsole(sd_bus **bus) {
×
1523
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
1524
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
×
1525
        _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
×
1526
        const char *object;
×
1527
        int r;
×
1528

UNCOV
1529
        assert(bus);
×
1530

UNCOV
1531
        if (!*bus) {
×
1532
                r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, RUNTIME_SCOPE_SYSTEM, bus);
×
1533
                if (r < 0)
×
1534
                        return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL, RUNTIME_SCOPE_SYSTEM);
×
1535
        }
1536

UNCOV
1537
        r = bus_wait_for_jobs_new(*bus, &w);
×
1538
        if (r < 0)
×
1539
                return log_error_errno(r, "Could not watch jobs: %m");
×
1540

UNCOV
1541
        r = bus_call_method(*bus, bus_systemd_mgr, "RestartUnit", &error, &reply,
×
1542
                            "ss", "systemd-vconsole-setup.service", "replace");
UNCOV
1543
        if (r < 0)
×
1544
                return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
×
1545

UNCOV
1546
        r = sd_bus_message_read(reply, "o", &object);
×
1547
        if (r < 0)
×
1548
                return bus_log_parse_error(r);
×
1549

UNCOV
1550
        r = bus_wait_for_jobs_one(w, object, BUS_WAIT_JOBS_LOG_ERROR, NULL);
×
1551
        if (r < 0)
×
1552
                return log_error_errno(r, "Failed to wait for systemd-vconsole-setup.service/restart: %m");
×
1553
        return 0;
1554
}
1555

1556
static int run(int argc, char *argv[]) {
143✔
1557
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
143✔
1558
        _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
143✔
UNCOV
1559
        _cleanup_(umount_and_freep) char *mounted_dir = NULL;
×
1560
        _cleanup_close_ int rfd = -EBADF;
143✔
1561
        int r;
143✔
1562

1563
        r = parse_argv(argc, argv);
143✔
1564
        if (r <= 0)
143✔
1565
                return r;
1566

1567
        log_setup();
141✔
1568

1569
        umask(0022);
141✔
1570

1571
        bool offline = arg_root || arg_image;
141✔
1572

1573
        if (!offline) {
105✔
1574
                /* If we are called without --root=/--image= let's honour the systemd.firstboot kernel
1575
                 * command line option, because we are called to provision the host with basic settings (as
1576
                 * opposed to some other file system tree/image) */
1577

1578
                bool enabled;
105✔
1579
                r = proc_cmdline_get_bool("systemd.firstboot", /* flags= */ 0, &enabled);
105✔
1580
                if (r < 0)
105✔
UNCOV
1581
                        return log_error_errno(r, "Failed to parse systemd.firstboot= kernel command line argument, ignoring: %m");
×
1582
                if (r > 0 && !enabled) {
105✔
1583
                        log_debug("Found systemd.firstboot=no kernel command line argument, turning off all prompts.");
105✔
1584
                        arg_prompt_locale = arg_prompt_keymap = arg_prompt_keymap_auto = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = arg_prompt_root_shell = false;
105✔
1585
                }
1586
        }
1587

1588
        r = mac_init();
141✔
1589
        if (r < 0)
141✔
1590
                return r;
1591

1592
        if (arg_image) {
141✔
UNCOV
1593
                assert(!arg_root);
×
1594

UNCOV
1595
                r = mount_image_privately_interactively(
×
1596
                                arg_image,
1597
                                arg_image_policy,
1598
                                DISSECT_IMAGE_GENERIC_ROOT |
1599
                                DISSECT_IMAGE_REQUIRE_ROOT |
1600
                                DISSECT_IMAGE_VALIDATE_OS |
1601
                                DISSECT_IMAGE_RELAX_VAR_CHECK |
1602
                                DISSECT_IMAGE_FSCK |
1603
                                DISSECT_IMAGE_GROWFS |
1604
                                DISSECT_IMAGE_ALLOW_USERSPACE_VERITY,
1605
                                &mounted_dir,
1606
                                &rfd,
1607
                                &loop_device);
UNCOV
1608
                if (r < 0)
×
1609
                        return r;
1610

UNCOV
1611
                arg_root = strdup(mounted_dir);
×
1612
                if (!arg_root)
×
1613
                        return log_oom();
×
1614
        } else {
1615
                rfd = open(empty_to_root(arg_root), O_DIRECTORY|O_CLOEXEC);
141✔
1616
                if (rfd < 0)
141✔
UNCOV
1617
                        return log_error_errno(errno, "Failed to open %s: %m", empty_to_root(arg_root));
×
1618
        }
1619

1620
        LOG_SET_PREFIX(arg_image ?: arg_root);
284✔
UNCOV
1621
        DEFER_VOID_CALL(chrome_hide);
×
1622

1623
        /* We check these conditions here instead of in parse_argv() so that we can take the root directory
1624
         * into account. */
1625

1626
        if (arg_keymap && !keymap_is_ok(arg_keymap, FD_TO_PTR(rfd)))
141✔
UNCOV
1627
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Keymap %s is not installed.", arg_keymap);
×
1628
        if (arg_locale && !locale_is_ok(arg_locale, FD_TO_PTR(rfd)))
141✔
UNCOV
1629
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale %s is not installed.", arg_locale);
×
1630
        if (arg_locale_messages && !locale_is_ok(arg_locale_messages, FD_TO_PTR(rfd)))
141✔
UNCOV
1631
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale %s is not installed.", arg_locale_messages);
×
1632

1633
        if (arg_root_shell) {
141✔
1634
                r = find_shell(rfd, arg_root_shell);
5✔
1635
                if (r < 0)
5✔
1636
                        return r;
1637
        }
1638

1639
        r = process_reset(rfd);
140✔
1640
        if (r < 0)
140✔
1641
                return r;
1642

1643
        _cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *mute_console_link = NULL;
141✔
1644
        r = process_locale(rfd, &mute_console_link);
140✔
1645
        if (r < 0)
140✔
1646
                return r;
1647
        if (r > 0 && !offline)
140✔
UNCOV
1648
                (void) reload_system_manager(&bus);
×
1649

1650
        r = process_keymap(rfd, &mute_console_link);
140✔
1651
        if (r < 0)
140✔
1652
                return r;
1653
        if (r > 0 && !offline)
140✔
UNCOV
1654
                (void) reload_vconsole(&bus);
×
1655

1656
        r = process_timezone(rfd, &mute_console_link);
140✔
1657
        if (r < 0)
140✔
1658
                return r;
1659

1660
        r = process_hostname(rfd, &mute_console_link);
140✔
1661
        if (r < 0)
140✔
1662
                return r;
1663

1664
        r = process_root_account(rfd, &mute_console_link);
140✔
1665
        if (r < 0)
140✔
1666
                return r;
1667

1668
        r = process_kernel_cmdline(rfd);
140✔
1669
        if (r < 0)
140✔
1670
                return r;
1671

1672
        r = process_machine_id(rfd);
140✔
1673
        if (r < 0)
140✔
UNCOV
1674
                return r;
×
1675

1676
        return 0;
1677
}
1678

1679
DEFINE_MAIN_FUNCTION(run);
143✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc