1
0
mirror of https://github.com/systemd/systemd synced 2025-11-08 19:34:45 +01:00

Compare commits

...

12 Commits

Author SHA1 Message Date
Lennart Poettering
495454f40f update NEWS 2020-07-23 10:02:16 +02:00
Lennart Poettering
82ff544160
Merge pull request #16496 from DaanDeMeyer/firstboot-shell
firstboot: Add --root-shell option and tighten up passwd/shadow handling
2020-07-23 08:39:45 +02:00
Daan De Meyer
bd190899bb Get SOURCE_EPOCH from the latest git tag instead of NEWS
Currently, each change to NEWS triggers a meson reconfigure that
changes SOURCE_EPOCH which causes a full rebuild. Since NEWS changes
relatively often, we have a full rebuild each time we pull from
master even if we pull semi-regularly. This is further compounded
when using branches since NEWS has a relatively high chance to
differ between branches which causes git to update the modification
time, leading to a full rebuild when switching between branches.

We fix this by using the creation time of the latest git tag instead.
2020-07-23 08:38:30 +02:00
Lennart Poettering
00b868e857
Merge pull request #16542 from keszybz/make-targets-fail-again
Make targets fail again
2020-07-23 08:37:47 +02:00
Lennart Poettering
c3f8a065e9 execute: take ownership of more fields in ExecParameters
Let's simplify things a bit, and take ownership of more fields in
ExecParameters, so that they are automatically freed when the structure
is released.
2020-07-23 08:37:21 +02:00
Daan De Meyer
28900a1bfe firstboot: Add --root-shell option 2020-07-22 21:22:46 +01:00
Daan De Meyer
c4a53ebf7a firstboot: Tighten up passwd/shadow handling
There are a lot of edge cases that the current implementation
doesn't handle, especially in cases where one of passwd/shadow
exists and the other doesn't exist. For example, if
--root-password is specified, we will write /etc/shadow but
won't add a root entry to /etc/passwd if there is none.

To fix some of these issues, we constrain systemd-firstboot to
only modify /etc/passwd and /etc/shadow if both do not exist
already (or --force) is specified. On top of that, we calculate
all necessary information for both passwd and shadow upfront so
we can take it all into account when writing the actual files.

If no root password options are given --force is specified or both
files do not exist, we lock the root account for security purposes.
2020-07-22 21:22:41 +01:00
Zbigniew Jędrzejewski-Szmek
94d1ddbd7c pid1: target units can fail through dependencies
Fixes #16401.

c80a9a33d04fb4381327a69ce929c94a9f1d0e6c introduced the .can_fail field,
but didn't set it on .targets. Targets can fail through dependencies.
This leaves .slice and .device units as the types that cannot fail.

$ systemctl cat bad.service bad.target bad-fallback.service
[Service]
Type=oneshot
ExecStart=false

[Unit]
OnFailure=bad-fallback.service

[Service]
Type=oneshot
ExecStart=echo Fixing everythign!

$ sudo systemctl start bad.target
systemd[1]: Starting bad.service...
systemd[1]: bad.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: bad.service: Failed with result 'exit-code'.
systemd[1]: Failed to start bad.service.
systemd[1]: Dependency failed for bad.target.
systemd[1]: bad.target: Job bad.target/start failed with result 'dependency'.
systemd[1]: bad.target: Triggering OnFailure= dependencies.
systemd[1]: Starting bad-fallback.service...
echo[46901]: Fixing everythign!
systemd[1]: bad-fallback.service: Succeeded.
systemd[1]: Finished bad-fallback.service.
2020-07-22 17:58:12 +02:00
Zbigniew Jędrzejewski-Szmek
74c8e3c4e0 Revert "units: drop OnFailure= from .target units"
This reverts commit c7220ca8025e8dbded36131b23a502d975c45754.

The removal was done as a reaction to the messages from systemd:
initrd-root-fs.target: Requested dependency OnFailure=emergency.target ignored (target units cannot fail).
initrd.target: Requested dependency OnFailure=emergency.target ignored (target units cannot fail).
initrd-root-device.target: Requested dependency OnFailure=emergency.target ignored (target units cannot fail).
initrd-fs.target: Requested dependency OnFailure=emergency.target ignored (target units cannot fail).
local-fs.target: Requested dependency OnFailure=emergency.target ignored (target units cannot fail).
...
But it seems that the messages themselves are wrong, and the units were OK.
2020-07-22 17:58:12 +02:00
Zbigniew Jędrzejewski-Szmek
771b52427a core/job: adjust whitespace and comment 2020-07-22 17:58:12 +02:00
Zbigniew Jędrzejewski-Szmek
e3643b00a8 test-path: decrease variable scope 2020-07-22 12:12:54 +02:00
Zbigniew Jędrzejewski-Szmek
8f8c7801e9 test: increase timeout for test-path
The CI occasionally fail in test-path with a timeout. test-path loads
units from the filesystem, and this conceivably might take more than
the default limit of 3 s. Increase the timeout substantially to see if
this helps.
2020-07-22 12:12:36 +02:00
15 changed files with 192 additions and 75 deletions

17
NEWS
View File

@ -329,6 +329,13 @@ CHANGES WITH 246:
MESSAGE=. This is useful to retrieve a very specific set of fields
without any decoration.
* The sd-journal.h API gained two new functions:
sd_journal_enumerate_available_unique() and
sd_journal_enumerate_available_data() that operate like their
counterparts that lack the _available_ in the name, but skip items
that cannot be read and processed by the local implementation
(i.e. are compressed in an unsupported format or such),
* coredumpctl gained a new --file= switch, matching the same one in
journalctl: a specific journal file may be specified to read the
coredump data from.
@ -438,10 +445,12 @@ CHANGES WITH 246:
also gained a new switch --root-password-hashed= which is like
--root-password= but accepts a pre-hashed UNIX password as
argument. The new option --delete-root-password may be used to unset
any password for the root user (dangerous!). A new --force option may
be used to override any already set settings with the parameters
specified on the command line (by default, the tool will not override
what has already been set before, i.e. is purely incremental).
any password for the root user (dangerous!). The --root-shell= switch
may be used to control the shell to use for the root account. A new
--force option may be used to override any already set settings with
the parameters specified on the command line (by default, the tool
will not override what has already been set before, i.e. is purely
incremental).
* systemd-firstboot gained support for a new --image= switch, which is
similar to --root= but accepts the path to a disk image file, on

View File

@ -164,9 +164,10 @@
<term><option>--root-password-file=<replaceable>PATH</replaceable></option></term>
<term><option>--root-password-hashed=<replaceable>HASHED_PASSWORD</replaceable></option></term>
<listitem><para>Sets the password of the system's root user. This creates a
<listitem><para>Sets the password of the system's root user. This creates/modifies the
<citerefentry project='die-net'><refentrytitle>passwd</refentrytitle><manvolnum>5</manvolnum></citerefentry> and
<citerefentry project='die-net'><refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum></citerefentry>
file. This setting exists in three forms: <option>--root-password=</option> accepts the password to
files. This setting exists in three forms: <option>--root-password=</option> accepts the password to
set directly on the command line, <option>--root-password-file=</option> reads it from a file and
<option>--root-password-hashed=</option> accepts an already hashed password on the command line. See
<citerefentry project='die-net'><refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum></citerefentry>
@ -176,6 +177,14 @@
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--root-shell=<replaceable>SHELL</replaceable></option></term>
<listitem><para>Sets the shell of the system's root user. This creates/modifies the
<citerefentry project='die-net'><refentrytitle>passwd</refentrytitle><manvolnum>5</manvolnum></citerefentry>
file.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--kernel-command-line=<replaceable>CMDLINE</replaceable></option></term>
@ -191,6 +200,7 @@
<term><option>--prompt-timezone</option></term>
<term><option>--prompt-hostname</option></term>
<term><option>--prompt-root-password</option></term>
<term><option>--prompt-root-shell</option></term>
<listitem><para>Prompt the user interactively for a specific
basic setting. Note that any explicit configuration settings
@ -207,7 +217,8 @@
<option>--prompt-keymap</option>,
<option>--prompt-timezone</option>,
<option>--prompt-hostname</option>,
<option>--prompt-root-password</option> in combination.</para>
<option>--prompt-root-password</option>,
<option>--prompt-root-shell</option> in combination.</para>
</listitem>
</varlistentry>
@ -216,6 +227,7 @@
<term><option>--copy-keymap</option></term>
<term><option>--copy-timezone</option></term>
<term><option>--copy-root-password</option></term>
<term><option>--copy-root-shell</option></term>
<listitem><para>Copy a specific basic setting from the host.
This only works in combination with <option>--root=</option>
@ -230,7 +242,8 @@
<option>--copy-locale</option>,
<option>--copy-keymap</option>,
<option>--copy-timezone</option>,
<option>--copy-root-password</option> in combination.</para>
<option>--copy-root-password</option>,
<option>--copy-root-shell</option> in combination.</para>
</listitem>
</varlistentry>

View File

@ -679,6 +679,10 @@ if time_epoch == -1
source_date_epoch = run_command('sh', ['-c', 'echo "$SOURCE_DATE_EPOCH"']).stdout().strip()
if source_date_epoch != ''
time_epoch = source_date_epoch.to_int()
elif git.found() and run_command('test', '-e', '.git').returncode() == 0
# If we're in a git repository, use the creation time of the latest git tag.
latest_tag = run_command('git', 'describe', '--abbrev=0', '--tags').stdout().strip()
time_epoch = run_command('git', 'log', '-1', '--format=%at', latest_tag).stdout().to_int()
else
NEWS = files('NEWS')
time_epoch = run_command(stat, '-c', '%Y', NEWS).stdout().to_int()

View File

@ -5761,7 +5761,10 @@ void exec_params_clear(ExecParameters *p) {
if (!p)
return;
strv_free(p->environment);
p->environment = strv_free(p->environment);
p->fd_names = strv_free(p->fd_names);
p->fds = mfree(p->fds);
p->exec_fd = safe_close(p->exec_fd);
}
static const char* const exec_input_table[_EXEC_INPUT_MAX] = {

View File

@ -990,9 +990,10 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
j->result = result;
log_unit_debug(u, "Job %" PRIu32 " %s/%s finished, result=%s", j->id, u->id, job_type_to_string(t), job_result_to_string(result));
log_unit_debug(u, "Job %" PRIu32 " %s/%s finished, result=%s",
j->id, u->id, job_type_to_string(t), job_result_to_string(result));
/* If this job did nothing to respective unit we don't log the status message */
/* If this job did nothing to the respective unit we don't log the status message */
if (!already)
job_emit_done_status_message(u, j->id, t, result);

View File

@ -1442,17 +1442,15 @@ static int service_spawn(
pid_t *_pid) {
_cleanup_(exec_params_clear) ExecParameters exec_params = {
.flags = flags,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
.exec_fd = -1,
.flags = flags,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
.exec_fd = -1,
};
_cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
_cleanup_(sd_event_source_unrefp) sd_event_source *exec_fd_source = NULL;
size_t n_socket_fds = 0, n_storage_fds = 0, n_env = 0;
_cleanup_close_ int exec_fd = -1;
_cleanup_free_ int *fds = NULL;
_cleanup_strv_free_ char **final_env = NULL, **our_env = NULL;
size_t n_env = 0;
pid_t pid;
int r;
@ -1477,17 +1475,21 @@ static int service_spawn(
s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
s->exec_context.std_error == EXEC_OUTPUT_SOCKET) {
r = service_collect_fds(s, &fds, &fd_names, &n_socket_fds, &n_storage_fds);
r = service_collect_fds(s,
&exec_params.fds,
&exec_params.fd_names,
&exec_params.n_socket_fds,
&exec_params.n_storage_fds);
if (r < 0)
return r;
log_unit_debug(UNIT(s), "Passing %zu fds to service", n_socket_fds + n_storage_fds);
log_unit_debug(UNIT(s), "Passing %zu fds to service", exec_params.n_socket_fds + exec_params.n_storage_fds);
}
if (!FLAGS_SET(flags, EXEC_IS_CONTROL) && s->type == SERVICE_EXEC) {
assert(!s->exec_fd_event_source);
r = service_allocate_exec_fd(s, &exec_fd_source, &exec_fd);
r = service_allocate_exec_fd(s, &exec_fd_source, &exec_params.exec_fd);
if (r < 0)
return r;
}
@ -1527,7 +1529,6 @@ static int service_spawn(
if (getpeername(s->socket_fd, &sa.sa, &salen) >= 0 &&
IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
_cleanup_free_ char *addr = NULL;
char *t;
unsigned port;
@ -1582,10 +1583,6 @@ static int service_spawn(
MANAGER_IS_SYSTEM(UNIT(s)->manager) && unit_has_name(UNIT(s), SPECIAL_DBUS_SERVICE));
strv_free_and_replace(exec_params.environment, final_env);
exec_params.fds = fds;
exec_params.fd_names = fd_names;
exec_params.n_socket_fds = n_socket_fds;
exec_params.n_storage_fds = n_storage_fds;
exec_params.watchdog_usec = service_get_watchdog_usec(s);
exec_params.selinux_context_net = s->socket_fd_selinux_context_net;
if (s->type == SERVICE_IDLE)
@ -1593,7 +1590,6 @@ static int service_spawn(
exec_params.stdin_fd = s->stdin_fd;
exec_params.stdout_fd = s->stdout_fd;
exec_params.stderr_fd = s->stderr_fd;
exec_params.exec_fd = exec_fd;
r = exec_spawn(UNIT(s),
c,

View File

@ -193,6 +193,8 @@ const UnitVTable target_vtable = {
"Target\0"
"Install\0",
.can_fail = true,
.load = target_load,
.coldplug = target_coldplug,

View File

@ -49,16 +49,19 @@ static char *arg_timezone = NULL;
static char *arg_hostname = NULL;
static sd_id128_t arg_machine_id = {};
static char *arg_root_password = NULL;
static char *arg_root_shell = NULL;
static char *arg_kernel_cmdline = NULL;
static bool arg_prompt_locale = false;
static bool arg_prompt_keymap = false;
static bool arg_prompt_timezone = false;
static bool arg_prompt_hostname = false;
static bool arg_prompt_root_password = false;
static bool arg_prompt_root_shell = false;
static bool arg_copy_locale = false;
static bool arg_copy_keymap = false;
static bool arg_copy_timezone = false;
static bool arg_copy_root_password = false;
static bool arg_copy_root_shell = false;
static bool arg_force = false;
static bool arg_delete_root_password = false;
static bool arg_root_password_is_hashed = false;
@ -601,11 +604,46 @@ static int prompt_root_password(void) {
return 0;
}
static int write_root_passwd(const char *passwd_path, const char *password) {
static int prompt_root_shell(void) {
int r;
if (arg_root_shell || !arg_prompt_root_shell)
return 0;
print_welcome();
putchar('\n');
for (;;) {
_cleanup_free_ char *s = NULL;
r = ask_string(&s, "%s Please enter root shell for new system (empty to skip): ", special_glyph(SPECIAL_GLYPH_TRIANGULAR_BULLET));
if (r < 0)
return log_error_errno(r, "Failed to query root shell: %m");
if (isempty(s)) {
log_warning("No shell entered, skipping.");
break;
}
if (!valid_shell(s)) {
log_error("Specified shell invalid.");
continue;
}
arg_root_shell = TAKE_PTR(s);
break;
}
return 0;
}
static int write_root_passwd(const char *passwd_path, const char *password, const char *shell) {
_cleanup_fclose_ FILE *original = NULL, *passwd = NULL;
_cleanup_(unlink_and_freep) char *passwd_tmp = NULL;
int r;
assert(password);
r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
if (r < 0)
return r;
@ -620,8 +658,11 @@ static int write_root_passwd(const char *passwd_path, const char *password) {
while ((r = fgetpwent_sane(original, &i)) > 0) {
if (streq(i->pw_name, "root"))
if (streq(i->pw_name, "root")) {
i->pw_passwd = (char *) password;
if (shell)
i->pw_shell = (char *) shell;
}
r = putpwent_sane(i, passwd);
if (r < 0)
@ -638,7 +679,7 @@ static int write_root_passwd(const char *passwd_path, const char *password) {
.pw_gid = 0,
.pw_gecos = (char *) "Super User",
.pw_dir = (char *) "/root",
.pw_shell = (char *) "/bin/sh",
.pw_shell = (char *) (shell ?: "/bin/sh"),
};
if (errno != ENOENT)
@ -669,6 +710,8 @@ static int write_root_shadow(const char *shadow_path, const char *hashed_passwor
_cleanup_(unlink_and_freep) char *shadow_tmp = NULL;
int r;
assert(hashed_password);
r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
if (r < 0)
return r;
@ -731,73 +774,73 @@ static int write_root_shadow(const char *shadow_path, const char *hashed_passwor
return 0;
}
static int process_root_password(void) {
static int process_root_args(void) {
_cleanup_close_ int lock = -1;
struct crypt_data cd = {};
const char *hashed_password;
const char *etc_shadow;
const char *password, *hashed_password;
const char *etc_passwd, *etc_shadow;
int r;
etc_passwd = prefix_roota(arg_root, "/etc/passwd");
etc_shadow = prefix_roota(arg_root, "/etc/shadow");
if (laccess(etc_shadow, F_OK) >= 0 && !arg_force)
/* We only mess with passwd and shadow if both do not exist or --force is specified. These files are
* tightly coupled and hence we make sure we have permission from the user to create/modify both
* files. */
if ((laccess(etc_passwd, F_OK) >= 0 || laccess(etc_shadow, F_OK) >= 0) && !arg_force)
return 0;
(void) mkdir_parents(etc_shadow, 0755);
(void) mkdir_parents(etc_passwd, 0755);
lock = take_etc_passwd_lock(arg_root);
if (lock < 0)
return log_error_errno(lock, "Failed to take a lock: %m");
return log_error_errno(lock, "Failed to take a lock on %s: %m", etc_passwd);
if (arg_delete_root_password) {
const char *etc_passwd;
if (arg_copy_root_shell && arg_root) {
struct passwd *p;
/* Mixing alloca() and other stuff that touches the stack in one expression is not portable. */
etc_passwd = prefix_roota(arg_root, "/etc/passwd");
errno = 0;
p = getpwnam("root");
if (!p)
return log_error_errno(errno_or_else(EIO), "Failed to find passwd entry for root: %m");
r = write_root_passwd(etc_passwd, "");
r = free_and_strdup(&arg_root_shell, p->pw_shell);
if (r < 0)
return log_error_errno(r, "Failed to write %s: %m", etc_passwd);
log_info("%s written", etc_passwd);
return 0;
return log_oom();
}
r = prompt_root_shell();
if (r < 0)
return r;
if (arg_copy_root_password && arg_root) {
struct spwd *p;
errno = 0;
p = getspnam("root");
if (p || errno != ENOENT) {
if (!p) {
if (!errno)
errno = EIO;
if (!p)
return log_error_errno(errno_or_else(EIO), "Failed to find shadow entry for root: %m");
return log_error_errno(errno, "Failed to find shadow entry for root: %m");
}
r = free_and_strdup(&arg_root_password, p->sp_pwdp);
if (r < 0)
return log_oom();
r = write_root_shadow(etc_shadow, p->sp_pwdp);
if (r < 0)
return log_error_errno(r, "Failed to write %s: %m", etc_shadow);
log_info("%s copied.", etc_shadow);
return 0;
}
arg_root_password_is_hashed = true;
}
r = prompt_root_password();
if (r < 0)
return r;
if (!arg_root_password)
return 0;
if (arg_root_password_is_hashed)
if (arg_root_password && arg_root_password_is_hashed) {
password = "x";
hashed_password = arg_root_password;
else {
} else if (arg_root_password) {
_cleanup_free_ char *salt = NULL;
/* hashed_password points inside cd after crypt_r returns so cd has function scope. */
password = "x";
r = make_salt(&salt);
if (r < 0)
return log_error_errno(r, "Failed to get salt: %m");
@ -807,7 +850,16 @@ static int process_root_password(void) {
if (!hashed_password)
return log_error_errno(errno == 0 ? SYNTHETIC_ERRNO(EINVAL) : errno,
"Failed to encrypt password: %m");
}
} else if (arg_delete_root_password)
password = hashed_password = "";
else
password = hashed_password = "!";
r = write_root_passwd(etc_passwd, password, arg_root_shell);
if (r < 0)
return log_error_errno(r, "Failed to write %s: %m", etc_passwd);
log_info("%s written", etc_passwd);
r = write_root_shadow(etc_shadow, hashed_password);
if (r < 0)
@ -968,6 +1020,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_ROOT_PASSWORD,
ARG_ROOT_PASSWORD_FILE,
ARG_ROOT_PASSWORD_HASHED,
ARG_ROOT_SHELL,
ARG_KERNEL_COMMAND_LINE,
ARG_PROMPT,
ARG_PROMPT_LOCALE,
@ -975,11 +1028,13 @@ static int parse_argv(int argc, char *argv[]) {
ARG_PROMPT_TIMEZONE,
ARG_PROMPT_HOSTNAME,
ARG_PROMPT_ROOT_PASSWORD,
ARG_PROMPT_ROOT_SHELL,
ARG_COPY,
ARG_COPY_LOCALE,
ARG_COPY_KEYMAP,
ARG_COPY_TIMEZONE,
ARG_COPY_ROOT_PASSWORD,
ARG_COPY_ROOT_SHELL,
ARG_SETUP_MACHINE_ID,
ARG_FORCE,
ARG_DELETE_ROOT_PASSWORD,
@ -1000,6 +1055,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "root-password", required_argument, NULL, ARG_ROOT_PASSWORD },
{ "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE },
{ "root-password-hashed", required_argument, NULL, ARG_ROOT_PASSWORD_HASHED },
{ "root-shell", required_argument, NULL, ARG_ROOT_SHELL },
{ "kernel-command-line", required_argument, NULL, ARG_KERNEL_COMMAND_LINE },
{ "prompt", no_argument, NULL, ARG_PROMPT },
{ "prompt-locale", no_argument, NULL, ARG_PROMPT_LOCALE },
@ -1007,11 +1063,13 @@ static int parse_argv(int argc, char *argv[]) {
{ "prompt-timezone", no_argument, NULL, ARG_PROMPT_TIMEZONE },
{ "prompt-hostname", no_argument, NULL, ARG_PROMPT_HOSTNAME },
{ "prompt-root-password", no_argument, NULL, ARG_PROMPT_ROOT_PASSWORD },
{ "prompt-root-shell", no_argument, NULL, ARG_PROMPT_ROOT_SHELL },
{ "copy", no_argument, NULL, ARG_COPY },
{ "copy-locale", no_argument, NULL, ARG_COPY_LOCALE },
{ "copy-keymap", no_argument, NULL, ARG_COPY_KEYMAP },
{ "copy-timezone", no_argument, NULL, ARG_COPY_TIMEZONE },
{ "copy-root-password", no_argument, NULL, ARG_COPY_ROOT_PASSWORD },
{ "copy-root-shell", no_argument, NULL, ARG_COPY_ROOT_SHELL },
{ "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID },
{ "force", no_argument, NULL, ARG_FORCE },
{ "delete-root-password", no_argument, NULL, ARG_DELETE_ROOT_PASSWORD },
@ -1108,6 +1166,17 @@ static int parse_argv(int argc, char *argv[]) {
arg_root_password_is_hashed = true;
break;
case ARG_ROOT_SHELL:
if (!valid_shell(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"%s is not a valid shell path", optarg);
r = free_and_strdup(&arg_root_shell, optarg);
if (r < 0)
return log_oom();
break;
case ARG_HOSTNAME:
if (!hostname_is_valid(optarg, true))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
@ -1135,7 +1204,8 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_PROMPT:
arg_prompt_locale = arg_prompt_keymap = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true;
arg_prompt_locale = arg_prompt_keymap = arg_prompt_timezone = arg_prompt_hostname =
arg_prompt_root_password = arg_prompt_root_shell = true;
break;
case ARG_PROMPT_LOCALE:
@ -1158,8 +1228,13 @@ static int parse_argv(int argc, char *argv[]) {
arg_prompt_root_password = true;
break;
case ARG_PROMPT_ROOT_SHELL:
arg_prompt_root_shell = true;
break;
case ARG_COPY:
arg_copy_locale = arg_copy_keymap = arg_copy_timezone = arg_copy_root_password = true;
arg_copy_locale = arg_copy_keymap = arg_copy_timezone = arg_copy_root_password =
arg_copy_root_shell = true;
break;
case ARG_COPY_LOCALE:
@ -1178,6 +1253,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_copy_root_password = true;
break;
case ARG_COPY_ROOT_SHELL:
arg_copy_root_shell = true;
break;
case ARG_SETUP_MACHINE_ID:
r = sd_id128_randomize(&arg_machine_id);
if (r < 0)
@ -1278,7 +1357,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
r = process_root_password();
r = process_root_args();
if (r < 0)
return r;

View File

@ -671,7 +671,8 @@ tests += [
libseccomp,
libselinux,
libmount,
libblkid]],
libblkid],
'', 'timeout=120'],
[['src/test/test-execute.c'],
[libcore,

View File

@ -346,10 +346,8 @@ int main(int argc, char *argv[]) {
NULL,
};
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
_cleanup_free_ char *test_path = NULL;
const test_function_t *test = NULL;
Manager *m = NULL;
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
umask(022);
@ -359,7 +357,8 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(test_path) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
for (test = tests; test && *test; test++) {
for (const test_function_t *test = tests; test && *test; test++) {
Manager *m = NULL;
int r;
/* We create a clean environment for each test */

View File

@ -10,6 +10,8 @@
[Unit]
Description=Initrd File Systems
Documentation=man:systemd.special(7)
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
ConditionPathExists=/etc/initrd-release
After=initrd-parse-etc.service
DefaultDependencies=no

View File

@ -11,5 +11,7 @@
Description=Initrd Root Device
Documentation=man:systemd.special(7)
ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
DefaultDependencies=no
Conflicts=shutdown.target

View File

@ -11,5 +11,7 @@
Description=Initrd Root File System
Documentation=man:systemd.special(7)
ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
DefaultDependencies=no
Conflicts=shutdown.target

View File

@ -10,6 +10,8 @@
[Unit]
Description=Initrd Default Target
Documentation=man:systemd.special(7)
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
ConditionPathExists=/etc/initrd-release
Requires=basic.target
Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-parse-etc.service

View File

@ -13,3 +13,5 @@ Documentation=man:systemd.special(7)
DefaultDependencies=no
Conflicts=shutdown.target
After=local-fs-pre.target
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly