summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-05-23 18:53:13 +0200
committerGitHub <noreply@github.com>2023-05-23 18:53:13 +0200
commit3fa7e62c4c94cf2268730d64a10f39285a431f20 (patch)
tree7452c6e3412e7751cd8c5fc815ac802ad6810c08
parentsd-bus: refuse to send messages with an invalid string (diff)
parentfirstboot: process the root account after sysusers created it (diff)
downloadsystemd-3fa7e62c4c94cf2268730d64a10f39285a431f20.tar.xz
systemd-3fa7e62c4c94cf2268730d64a10f39285a431f20.zip
Merge pull request #27750 from keszybz/fix-root-resize-new
Allow firstboot.service to be started after sysusers.service
-rw-r--r--docs/ENVIRONMENT.md3
-rw-r--r--man/systemd-firstboot.xml63
-rw-r--r--man/systemd-tmpfiles.xml12
-rw-r--r--src/basic/user-util.c8
-rw-r--r--src/basic/user-util.h5
-rw-r--r--src/firstboot/firstboot.c94
-rw-r--r--src/partition/repart.c18
-rw-r--r--src/shared/condition.c33
-rw-r--r--src/shared/generator.c18
-rw-r--r--src/sysusers/sysusers.c42
-rw-r--r--src/tmpfiles/tmpfiles.c107
-rw-r--r--units/local-fs.target3
-rw-r--r--units/proc-sys-fs-binfmt_misc.automount7
-rw-r--r--units/quotaon.service.in7
-rw-r--r--units/systemd-boot-update.service3
-rw-r--r--units/systemd-firstboot.service11
-rw-r--r--units/systemd-growfs-root.service.in3
-rw-r--r--units/systemd-growfs@.service.in3
-rw-r--r--units/systemd-hwdb-update.service.in11
-rw-r--r--units/systemd-journal-catalog-update.service9
-rw-r--r--units/systemd-journal-flush.service9
-rw-r--r--units/systemd-quotacheck.service.in7
-rw-r--r--units/systemd-random-seed.service.in13
-rw-r--r--units/systemd-remount-fs.service.in6
-rw-r--r--units/systemd-repart.service.in16
-rw-r--r--units/systemd-rfkill.socket3
-rw-r--r--units/systemd-sysusers.service6
-rw-r--r--units/systemd-tmpfiles-setup-dev.service3
-rw-r--r--units/systemd-tmpfiles-setup.service2
-rw-r--r--units/systemd-update-utmp.service.in8
-rw-r--r--units/systemd-vconsole-setup.service.in4
31 files changed, 361 insertions, 176 deletions
diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md
index 2ba222d3a6..f1b9fd7715 100644
--- a/docs/ENVIRONMENT.md
+++ b/docs/ENVIRONMENT.md
@@ -35,6 +35,9 @@ All tools:
as `start` into no-ops. If that's what's explicitly desired, you might
consider setting `$SYSTEMD_OFFLINE=1`.
+* `$SYSTEMD_FIRST_BOOT=0|1` — if set, assume "first boot" condition to be false
+ or true, instead of checking the flag file created by PID 1.
+
* `$SD_EVENT_PROFILE_DELAYS=1` — if set, the sd-event event loop implementation
will print latency information at runtime.
diff --git a/man/systemd-firstboot.xml b/man/systemd-firstboot.xml
index 42666c96f8..9984683967 100644
--- a/man/systemd-firstboot.xml
+++ b/man/systemd-firstboot.xml
@@ -34,18 +34,18 @@
<refsect1>
<title>Description</title>
- <para><command>systemd-firstboot</command> initializes the most
- basic system settings interactively on the first boot, or
- optionally non-interactively when a system image is created.
- The service is started if <varname>ConditionFirstBoot=yes</varname>
- is satisfied. This essentially means that <filename>/etc/</filename>
+ <para><command>systemd-firstboot</command> initializes basic system settings interactively during the
+ first boot, or non-interactively on an offline system image. The service is started during boot if
+ <varname>ConditionFirstBoot=yes</varname> is met, which essentially means that <filename>/etc/</filename>
is empty, see
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for details.</para>
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+ details.</para>
- <para>The following settings may be set up:</para>
+ <para>The following settings may be configured:</para>
<itemizedlist>
+ <listitem><para>The machine ID of the system</para></listitem>
+
<listitem><para>The system locale, more specifically the two
locale variables <varname>LANG=</varname> and
<varname>LC_MESSAGES</varname></para></listitem>
@@ -56,9 +56,9 @@
<listitem><para>The system hostname</para></listitem>
- <listitem><para>The machine ID of the system</para></listitem>
+ <listitem><para>The kernel command line used when installing kernel images</para></listitem>
- <listitem><para>The root user's password</para></listitem>
+ <listitem><para>The root user's password and shell</para></listitem>
</itemizedlist>
<para>Each of the fields may either be queried interactively by
@@ -79,7 +79,7 @@
This allows <command>systemd-firstboot</command> to operate on
mounted but not booted disk images and in early boot. It is not
recommended to use <command>systemd-firstboot</command> on the
- running system while it is up.</para>
+ running system after it has been set up.</para>
</refsect1>
<refsect1>
@@ -151,12 +151,24 @@
</varlistentry>
<varlistentry>
+ <term><option>--setup-machine-id</option></term>
+
+ <listitem><para>Initialize the system's machine ID to a random ID. This controls the
+ <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> file.
+ </para>
+
+ <para>This option only works in combination with <option>--root=</option> or
+ <option>--image=</option>. On a running system, <filename>machine-id</filename> is written by the
+ manager with help from
+ <citerefentry><refentrytitle>systemd-machine-id-commit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--machine-id=<replaceable>ID</replaceable></option></term>
- <listitem><para>Sets the system's machine ID. This controls
- the
- <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- file.</para></listitem>
+ <listitem><para>Set the system's machine ID to the specified value. The same restrictions apply
+ as to <option>--setup-machine-id</option>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -230,8 +242,8 @@
<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>
- (see above).</para></listitem>
+ This only works in combination with <option>--root=</option> or <option>--image=</option>.
+ </para></listitem>
</varlistentry>
<varlistentry>
@@ -248,20 +260,13 @@
</varlistentry>
<varlistentry>
- <term><option>--setup-machine-id</option></term>
-
- <listitem><para>Initialize the system's machine ID to a random
- ID. This only works in combination with
- <option>--root=</option>.</para></listitem>
- </varlistentry>
-
- <varlistentry>
<term><option>--force</option></term>
- <listitem><para>systemd-firstboot doesn't modify existing files unless <option>--force</option>
- is specified. For modifications to <filename>/etc/passwd</filename> and
- <filename>/etc/shadow</filename>, systemd-firstboot only modifies the entry of the
- <literal>root</literal> user instead of overwriting the entire file.</para></listitem>
+ <listitem><para>Write configuration even if the relevant files already exist. Without this option,
+ <filename>systemd-firstboot</filename> doesn't modify or replace existing files. Note that when
+ configuring the root account, even with this option, <filename>systemd-firstboot</filename> only
+ modifies the entry of the <literal>root</literal> user, leaving other entries in
+ <filename>/etc/passwd</filename> and <filename>/etc/shadow</filename> intact.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
index 5612b4803d..735f59cc11 100644
--- a/man/systemd-tmpfiles.xml
+++ b/man/systemd-tmpfiles.xml
@@ -144,8 +144,16 @@
<varlistentry>
<term><option>--boot</option></term>
- <listitem><para>Also execute lines with an exclamation mark.
- </para></listitem>
+ <listitem><para>Also execute lines with an exclamation mark. Lines that are not safe to be executed
+ on a running system may be marked in this way. <command>systemd-tmpfiles</command> is executed in
+ early boot with <option>--boot</option> specified and will execute those lines. When invoked again
+ later, it should be called without <option>--boot</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--graceful</option></term>
+ <listitem><para>Ignore configuration lines pertaining to unknown users or groups. This option is
+ intended to be used in early boot before all users or groups have been created.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index dd2642d214..3325aabe4d 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -287,7 +287,9 @@ int get_user_creds(
p = getpwnam(*username);
}
if (!p) {
- r = errno_or_else(ESRCH);
+ /* getpwnam() may fail with ENOENT if /etc/passwd is missing.
+ * For us that is equivalent to the name not being defined. */
+ r = IN_SET(errno, 0, ENOENT) ? -ESRCH : -errno;
/* If the user requested that we only synthesize as fallback, do so now */
if (FLAGS_SET(flags, USER_CREDS_PREFER_NSS)) {
@@ -381,7 +383,9 @@ int get_group_creds(const char **groupname, gid_t *gid, UserCredsFlags flags) {
}
if (!g)
- return errno_or_else(ESRCH);
+ /* getgrnam() may fail with ENOENT if /etc/group is missing.
+ * For us that is equivalent to the name not being defined. */
+ return IN_SET(errno, 0, ENOENT) ? -ESRCH : -errno;
if (gid) {
if (!gid_is_valid(g->gr_gid))
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
index 5aca6307e0..c82941dd81 100644
--- a/src/basic/user-util.h
+++ b/src/basic/user-util.h
@@ -150,3 +150,8 @@ static inline bool hashed_password_is_locked_or_invalid(const char *password) {
/* A password indicating "hey, no password required for login" */
#define PASSWORD_NONE ""
+
+/* Used by sysusers to indicate that the password should be filled in by firstboot.
+ * Also see https://github.com/systemd/systemd/pull/24680#pullrequestreview-1439464325.
+ */
+#define PASSWORD_UNPROVISIONED "!unprovisioned"
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 6d50054baf..6b42e64043 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -234,17 +234,72 @@ static int prompt_loop(const char *text, char **l, unsigned percentage, bool (*i
}
static int should_configure(int dir_fd, const char *filename) {
+ _cleanup_fclose_ FILE *passwd = NULL, *shadow = NULL;
+ int r;
+
assert(dir_fd >= 0);
assert(filename);
- if (faccessat(dir_fd, filename, F_OK, AT_SYMLINK_NOFOLLOW) < 0) {
- if (errno != ENOENT)
- return log_error_errno(errno, "Failed to access %s: %m", filename);
+ if (streq(filename, "passwd") && !arg_force)
+ /* We may need to do additional checks, so open the file. */
+ r = xfopenat(dir_fd, filename, "re", O_NOFOLLOW, &passwd);
+ else
+ r = RET_NERRNO(faccessat(dir_fd, filename, F_OK, AT_SYMLINK_NOFOLLOW));
+
+ if (r == -ENOENT)
+ return true; /* missing */
+ if (r < 0)
+ return log_error_errno(r, "Failed to access %s: %m", filename);
+ if (arg_force)
+ return true; /* exists, but if --force was given we should still configure the file. */
+
+ if (!passwd)
+ return false;
+
+ /* In case of /etc/passwd, do an additional check for the root password field.
+ * We first check that passwd redirects to shadow, and then we check shadow.
+ */
+ struct passwd *i;
+ while ((r = fgetpwent_sane(passwd, &i)) > 0) {
+ if (!streq(i->pw_name, "root"))
+ continue;
+
+ if (streq_ptr(i->pw_passwd, PASSWORD_SEE_SHADOW))
+ break;
+ log_debug("passwd: root account with non-shadow password found, treating root as configured");
+ return false;
+ }
+ if (r < 0)
+ return log_error_errno(r, "Failed to read %s: %m", filename);
+ if (r == 0) {
+ log_debug("No root account found in %s, assuming root is not configured.", filename);
+ return true;
+ }
+ r = xfopenat(dir_fd, "shadow", "re", O_NOFOLLOW, &shadow);
+ if (r == -ENOENT) {
+ log_debug("No shadow file found, assuming root is not configured.");
return true; /* missing */
}
+ if (r < 0)
+ return log_error_errno(r, "Failed to access shadow: %m");
- return arg_force; /* exists, but if --force was given we should still configure the file. */
+ struct spwd *j;
+ while ((r = fgetspent_sane(shadow, &j)) > 0) {
+ if (!streq(j->sp_namp, "root"))
+ continue;
+
+ bool unprovisioned = streq_ptr(j->sp_pwdp, PASSWORD_UNPROVISIONED);
+ log_debug("Root account found, %s.",
+ unprovisioned ? "with unprovisioned password, treating root as not configured" :
+ "treating root as configured");
+ return unprovisioned;
+ }
+ if (r < 0)
+ return log_error_errno(r, "Failed to read shadow: %m");
+ assert(r == 0);
+ log_debug("No root account found in shadow, assuming root is not configured.");
+ return true;
}
static bool locale_is_installed_bool(const char *name) {
@@ -1172,7 +1227,8 @@ static int help(void) {
" --keymap=KEYMAP Set keymap\n"
" --timezone=TIMEZONE Set timezone\n"
" --hostname=NAME Set hostname\n"
- " --machine-ID=ID Set machine ID\n"
+ " --setup-machine-id Set a random machine ID\n"
+ " --machine-ID=ID Set specified machine ID\n"
" --root-password=PASSWORD Set root password from plaintext password\n"
" --root-password-file=FILE Set root password from file\n"
" --root-password-hashed=HASH Set root password from hashed password\n"
@@ -1190,7 +1246,6 @@ static int help(void) {
" --copy-root-password Copy root password from host\n"
" --copy-root-shell Copy root shell from host\n"
" --copy Copy locale, keymap, timezone, root password\n"
- " --setup-machine-id Generate a new random machine ID\n"
" --force Overwrite existing files\n"
" --delete-root-password Delete root password\n"
" --welcome=no Disable the welcome text\n"
@@ -1214,6 +1269,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_KEYMAP,
ARG_TIMEZONE,
ARG_HOSTNAME,
+ ARG_SETUP_MACHINE_ID,
ARG_MACHINE_ID,
ARG_ROOT_PASSWORD,
ARG_ROOT_PASSWORD_FILE,
@@ -1233,7 +1289,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_COPY_TIMEZONE,
ARG_COPY_ROOT_PASSWORD,
ARG_COPY_ROOT_SHELL,
- ARG_SETUP_MACHINE_ID,
ARG_FORCE,
ARG_DELETE_ROOT_PASSWORD,
ARG_WELCOME,
@@ -1251,6 +1306,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "keymap", required_argument, NULL, ARG_KEYMAP },
{ "timezone", required_argument, NULL, ARG_TIMEZONE },
{ "hostname", required_argument, NULL, ARG_HOSTNAME },
+ { "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID },
{ "machine-id", required_argument, NULL, ARG_MACHINE_ID },
{ "root-password", required_argument, NULL, ARG_ROOT_PASSWORD },
{ "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE },
@@ -1270,7 +1326,6 @@ static int parse_argv(int argc, char *argv[]) {
{ "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 },
{ "welcome", required_argument, NULL, ARG_WELCOME },
@@ -1392,6 +1447,13 @@ static int parse_argv(int argc, char *argv[]) {
hostname_cleanup(arg_hostname);
break;
+ case ARG_SETUP_MACHINE_ID:
+ r = sd_id128_randomize(&arg_machine_id);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate randomized machine ID: %m");
+
+ break;
+
case ARG_MACHINE_ID:
r = sd_id128_from_string(optarg, &arg_machine_id);
if (r < 0)
@@ -1460,13 +1522,6 @@ static int parse_argv(int argc, char *argv[]) {
arg_copy_root_shell = true;
break;
- case ARG_SETUP_MACHINE_ID:
- r = sd_id128_randomize(&arg_machine_id);
- if (r < 0)
- return log_error_errno(r, "Failed to generate randomized machine ID: %m");
-
- break;
-
case ARG_FORCE:
arg_force = true;
break;
@@ -1496,10 +1551,15 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_delete_root_password && (arg_copy_root_password || arg_root_password || arg_prompt_root_password))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "--delete-root-password cannot be combined with other root password options");
+ "--delete-root-password cannot be combined with other root password options.");
if (arg_image && arg_root)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "--root= and --image= cannot be used together.");
+
+ if (!sd_id128_is_null(arg_machine_id) && !(arg_image || arg_root) && !arg_force)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "--machine-id=/--setup-machine-id only works with --root= or --image=.");
return 1;
}
diff --git a/src/partition/repart.c b/src/partition/repart.c
index d5d5e2353f..5a2f992e2d 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -5515,15 +5515,11 @@ static int fd_apparent_size(int fd, uint64_t *ret) {
}
static int context_minimize(Context *context) {
- const char *vt;
+ const char *vt = NULL;
int r;
assert(context);
- r = var_tmp_dir(&vt);
- if (r < 0)
- return log_error_errno(r, "Could not determine temporary directory: %m");
-
LIST_FOREACH(partitions, p, context->partitions) {
_cleanup_(rm_rf_physical_and_freep) char *root = NULL;
_cleanup_(unlink_and_freep) char *temp = NULL;
@@ -5556,6 +5552,12 @@ static int context_minimize(Context *context) {
log_info("Pre-populating %s filesystem of partition %s twice to calculate minimal partition size",
p->format, strna(hint));
+ if (!vt) {
+ r = var_tmp_dir(&vt);
+ if (r < 0)
+ return log_error_errno(r, "Could not determine temporary directory: %m");
+ }
+
r = tempfn_random_child(vt, "repart", &temp);
if (r < 0)
return log_error_errno(r, "Failed to generate temporary file path: %m");
@@ -5713,6 +5715,12 @@ static int context_minimize(Context *context) {
log_info("Pre-populating verity hash data of partition %s to calculate minimal partition size",
strna(hint));
+ if (!vt) {
+ r = var_tmp_dir(&vt);
+ if (r < 0)
+ return log_error_errno(r, "Could not determine temporary directory: %m");
+ }
+
r = tempfn_random_child(vt, "repart", &temp);
if (r < 0)
return log_error_errno(r, "Failed to generate temporary file path: %m");
diff --git a/src/shared/condition.c b/src/shared/condition.c
index e5a80757e0..fce3fc2afb 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -821,22 +821,43 @@ static int condition_test_needs_update(Condition *c, char **env) {
return timespec_load_nsec(&usr.st_mtim) > timestamp;
}
+static bool in_first_boot(void) {
+ static int first_boot = -1;
+ int r;
+
+ if (first_boot >= 0)
+ return first_boot;
+
+ const char *e = secure_getenv("SYSTEMD_FIRST_BOOT");
+ if (e) {
+ r = parse_boolean(e);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_FIRST_BOOT, ignoring: %m");
+ else
+ return (first_boot = r);
+ }
+
+ r = RET_NERRNO(access("/run/systemd/first-boot", F_OK));
+ if (r < 0 && r != -ENOENT)
+ log_debug_errno(r, "Failed to check if /run/systemd/first-boot exists, assuming no: %m");
+ return r >= 0;
+}
+
static int condition_test_first_boot(Condition *c, char **env) {
- int r, q;
+ int r;
assert(c);
assert(c->parameter);
assert(c->type == CONDITION_FIRST_BOOT);
+ // TODO: Parse c->parameter immediately when reading the config.
+ // Apply negation when parsing too.
+
r = parse_boolean(c->parameter);
if (r < 0)
return r;
- q = access("/run/systemd/first-boot", F_OK);
- if (q < 0 && errno != ENOENT)
- log_debug_errno(errno, "Failed to check if /run/systemd/first-boot exists, assuming no: %m");
-
- return (q >= 0) == r;
+ return in_first_boot() == r;
}
static int condition_test_environment(Condition *c, char **env) {
diff --git a/src/shared/generator.c b/src/shared/generator.c
index b16d0a0ef2..49c5fe5c05 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -224,6 +224,7 @@ static int write_fsck_sysroot_service(
"[Unit]\n"
"Description=File System Check on %2$s\n"
"Documentation=man:%3$s(8)\n"
+ "\n"
"DefaultDependencies=no\n"
"BindsTo=%4$s\n"
"Conflicts=shutdown.target\n"
@@ -517,11 +518,13 @@ int generator_hook_up_mkswap(
"[Unit]\n"
"Description=Make Swap on %%f\n"
"Documentation=man:systemd-mkswap@.service(8)\n"
+ "\n"
"DefaultDependencies=no\n"
"BindsTo=%%i.device\n"
- "Conflicts=shutdown.target\n"
"After=%%i.device\n"
- "Before=shutdown.target %s\n"
+ "Before=%s\n"
+ "Conflicts=shutdown.target\n"
+ "Before=shutdown.target\n"
"\n"
"[Service]\n"
"Type=oneshot\n"
@@ -602,13 +605,15 @@ int generator_hook_up_mkfs(
"[Unit]\n"
"Description=Make File System on %%f\n"
"Documentation=man:systemd-makefs@.service(8)\n"
+ "\n"
"DefaultDependencies=no\n"
"BindsTo=%%i.device\n"
- "Conflicts=shutdown.target\n"
"After=%%i.device\n"
/* fsck might or might not be used, so let's be safe and order
* ourselves before both systemd-fsck@.service and the mount unit. */
- "Before=shutdown.target %s %s\n"
+ "Before=%s %s\n"
+ "Conflicts=shutdown.target\n"
+ "Before=shutdown.target\n"
"\n"
"[Service]\n"
"Type=oneshot\n"
@@ -748,11 +753,12 @@ int generator_write_cryptsetup_unit_section(
fprintf(f, "SourcePath=%s\n", source);
fprintf(f,
+ "\n"
"DefaultDependencies=no\n"
- "IgnoreOnIsolate=true\n"
"After=cryptsetup-pre.target systemd-udevd-kernel.socket\n"
"Before=blockdev@dev-mapper-%%i.target\n"
- "Wants=blockdev@dev-mapper-%%i.target\n");
+ "Wants=blockdev@dev-mapper-%%i.target\n"
+ "IgnoreOnIsolate=true\n");
return 0;
}
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index aa1f1356dc..12adad516e 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -415,7 +415,7 @@ static const char* pick_shell(const Item *i) {
return NOLOGIN;
}
-static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char **tmpfile_path) {
+static int write_temporary_passwd(const char *passwd_path, FILE **ret_tmpfile, char **ret_tmpfile_path) {
_cleanup_fclose_ FILE *original = NULL, *passwd = NULL;
_cleanup_(unlink_and_freep) char *passwd_tmp = NULL;
struct passwd *pw = NULL;
@@ -511,7 +511,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
r = putpwent_sane(&n, passwd);
if (r < 0)
return log_debug_errno(r, "Failed to add new user \"%s\" to temporary passwd file: %m",
- pw->pw_name);
+ i->name);
}
/* Append the remaining NIS entries if any */
@@ -532,8 +532,8 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
if (r < 0)
return log_debug_errno(r, "Failed to flush %s: %m", passwd_tmp);
- *tmpfile = TAKE_PTR(passwd);
- *tmpfile_path = TAKE_PTR(passwd_tmp);
+ *ret_tmpfile = TAKE_PTR(passwd);
+ *ret_tmpfile_path = TAKE_PTR(passwd_tmp);
return 0;
}
@@ -550,7 +550,7 @@ static usec_t epoch_or_now(void) {
return now(CLOCK_REALTIME);
}
-static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char **tmpfile_path) {
+static int write_temporary_shadow(const char *shadow_path, FILE **ret_tmpfile, char **ret_tmpfile_path) {
_cleanup_fclose_ FILE *original = NULL, *shadow = NULL;
_cleanup_(unlink_and_freep) char *shadow_tmp = NULL;
struct spwd *sp = NULL;
@@ -618,7 +618,6 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
struct spwd n = {
.sp_namp = i->name,
- .sp_pwdp = (char*) PASSWORD_LOCKED_AND_INVALID,
.sp_lstchg = lstchg,
.sp_min = -1,
.sp_max = -1,
@@ -641,11 +640,16 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
if (creds_password)
n.sp_pwdp = creds_password;
+ else if (streq(i->name, "root"))
+ /* Let firstboot set the password later */
+ n.sp_pwdp = (char*) PASSWORD_UNPROVISIONED;
+ else
+ n.sp_pwdp = (char*) PASSWORD_LOCKED_AND_INVALID;
r = putspent_sane(&n, shadow);
if (r < 0)
return log_debug_errno(r, "Failed to add new user \"%s\" to temporary shadow file: %m",
- sp->sp_namp);
+ i->name);
}
/* Append the remaining NIS entries if any */
@@ -668,13 +672,13 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
if (r < 0)
return log_debug_errno(r, "Failed to flush %s: %m", shadow_tmp);
- *tmpfile = TAKE_PTR(shadow);
- *tmpfile_path = TAKE_PTR(shadow_tmp);
+ *ret_tmpfile = TAKE_PTR(shadow);
+ *ret_tmpfile_path = TAKE_PTR(shadow_tmp);
return 0;
}
-static int write_temporary_group(const char *group_path, FILE **tmpfile, char **tmpfile_path) {
+static int write_temporary_group(const char *group_path, FILE **ret_tmpfile, char **ret_tmpfile_path) {
_cleanup_fclose_ FILE *original = NULL, *group = NULL;
_cleanup_(unlink_and_freep) char *group_tmp = NULL;
bool group_changed = false;
@@ -774,13 +778,13 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
return log_error_errno(r, "Failed to flush %s: %m", group_tmp);
if (group_changed) {
- *tmpfile = TAKE_PTR(group);
- *tmpfile_path = TAKE_PTR(group_tmp);
+ *ret_tmpfile = TAKE_PTR(group);
+ *ret_tmpfile_path = TAKE_PTR(group_tmp);
}
return 0;
}
-static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, char **tmpfile_path) {
+static int write_temporary_gshadow(const char * gshadow_path, FILE **ret_tmpfile, char **ret_tmpfile_path) {
#if ENABLE_GSHADOW
_cleanup_fclose_ FILE *original = NULL, *gshadow = NULL;
_cleanup_(unlink_and_freep) char *gshadow_tmp = NULL;
@@ -853,8 +857,8 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch
return log_error_errno(r, "Failed to flush %s: %m", gshadow_tmp);
if (group_changed) {
- *tmpfile = TAKE_PTR(gshadow);
- *tmpfile_path = TAKE_PTR(gshadow_tmp);
+ *ret_tmpfile = TAKE_PTR(gshadow);
+ *ret_tmpfile_path = TAKE_PTR(gshadow_tmp);
}
#endif
return 0;
@@ -891,23 +895,23 @@ static int write_files(void) {
if (group) {
r = make_backup("/etc/group", group_path);
if (r < 0)
- return log_error_errno(r, "Failed to make backup %s: %m", group_path);
+ return log_error_errno(r, "Failed to backup %s: %m", group_path);
}
if (gshadow) {
r = make_backup("/etc/gshadow", gshadow_path);
if (r < 0)
- return log_error_errno(r, "Failed to make backup %s: %m", gshadow_path);
+ return log_error_errno(r, "Failed to backup %s: %m", gshadow_path);
}
if (passwd) {
r = make_backup("/etc/passwd", passwd_path);
if (r < 0)
- return log_error_errno(r, "Failed to make backup %s: %m", passwd_path);
+ return log_error_errno(r, "Failed to backup %s: %m", passwd_path);
}
if (shadow) {
r = make_backup("/etc/shadow", shadow_path);
if (r < 0)
- return log_error_errno(r, "Failed to make backup %s: %m", shadow_path);
+ return log_error_errno(r, "Failed to backup %s: %m", shadow_path);
}
/* And make the new files count */
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index be04b25653..518d8012da 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -86,35 +86,35 @@ typedef enum OperationMask {
typedef enum ItemType {
/* These ones take file names */
- CREATE_FILE = 'f',
- TRUNCATE_FILE = 'F', /* deprecated: use f+ */
- CREATE_DIRECTORY = 'd',
- TRUNCATE_DIRECTORY = 'D',
- CREATE_SUBVOLUME = 'v',
+ CREATE_FILE = 'f',
+ TRUNCATE_FILE = 'F', /* deprecated: use f+ */
+ CREATE_DIRECTORY = 'd',
+ TRUNCATE_DIRECTORY = 'D',
+ CREATE_SUBVOLUME = 'v',
CREATE_SUBVOLUME_INHERIT_QUOTA = 'q',
- CREATE_SUBVOLUME_NEW_QUOTA = 'Q',
- CREATE_FIFO = 'p',
- CREATE_SYMLINK = 'L',
- CREATE_CHAR_DEVICE = 'c',
- CREATE_BLOCK_DEVICE = 'b',
- COPY_FILES = 'C',
+ CREATE_SUBVOLUME_NEW_QUOTA = 'Q',
+ CREATE_FIFO = 'p',
+ CREATE_SYMLINK = 'L',
+ CREATE_CHAR_DEVICE = 'c',
+ CREATE_BLOCK_DEVICE = 'b',
+ COPY_FILES = 'C',
/* These ones take globs */
- WRITE_FILE = 'w',
- EMPTY_DIRECTORY = 'e',
- SET_XATTR = 't',
- RECURSIVE_SET_XATTR = 'T',
- SET_ACL = 'a',
- RECURSIVE_SET_ACL = 'A',
- SET_ATTRIBUTE = 'h',
- RECURSIVE_SET_ATTRIBUTE = 'H',
- IGNORE_PATH = 'x',
- IGNORE_DIRECTORY_PATH = 'X',
- REMOVE_PATH = 'r',
- RECURSIVE_REMOVE_PATH = 'R',
- RELABEL_PATH = 'z',
- RECURSIVE_RELABEL_PATH = 'Z',
- ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
+ WRITE_FILE = 'w',
+ EMPTY_DIRECTORY = 'e',
+ SET_XATTR = 't',
+ RECURSIVE_SET_XATTR = 'T',
+ SET_ACL = 'a',
+ RECURSIVE_SET_ACL = 'A',
+ SET_ATTRIBUTE = 'h',
+ RECURSIVE_SET_ATTRIBUTE = 'H',
+ IGNORE_PATH = 'x',
+ IGNORE_DIRECTORY_PATH = 'X',
+ REMOVE_PATH = 'r',
+ RECURSIVE_REMOVE_PATH = 'R',
+ RELABEL_PATH = 'z',
+ RECURSIVE_RELABEL_PATH = 'Z',
+ ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
} ItemType;
typedef enum AgeBy {
@@ -125,7 +125,7 @@ typedef enum AgeBy {
/* All file timestamp types are checked by default. */
AGE_BY_DEFAULT_FILE = AGE_BY_ATIME | AGE_BY_BTIME | AGE_BY_CTIME | AGE_BY_MTIME,
- AGE_BY_DEFAULT_DIR = AGE_BY_ATIME | AGE_BY_BTIME | AGE_BY_MTIME
+ AGE_BY_DEFAULT_DIR = AGE_BY_ATIME | AGE_BY_BTIME | AGE_BY_MTIME,
} AgeBy;
typedef struct Item {
@@ -200,6 +200,7 @@ static bool arg_cat_config = false;
static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
static OperationMask arg_operation = 0;
static bool arg_boot = false;
+static bool arg_graceful = false;
static PagerFlags arg_pager_flags = 0;
static char **arg_include_prefixes = NULL;
@@ -1131,7 +1132,8 @@ static int parse_acls_from_arg(Item *item) {
r = parse_acl(item->argument, &item->acl_access, &item->acl_access_exec,
&item->acl_default, !item->append_or_force);
if (r < 0)
- log_warning_errno(r, "Failed to parse ACL \"%s\", ignoring: %m", item->argument);
+ log_full_errno(arg_graceful && IN_SET(r, -ENOENT, -ESRCH) ? LOG_DEBUG : LOG_WARNING,
+ r, "Failed to parse ACL \"%s\", ignoring: %m", item->argument);
#else
log_warning("ACLs are not supported, ignoring.");
#endif
@@ -3322,7 +3324,8 @@ static int parse_line(
ItemArray *existing;
OrderedHashmap *h;
int r, pos;
- bool append_or_force = false, boot = false, allow_failure = false, try_replace = false, unbase64 = false, from_cred = false;
+ bool append_or_force = false, boot = false, allow_failure = false, try_replace = false,
+ unbase64 = false, from_cred = false, missing_user_or_group = false;
assert(fname);
assert(line >= 1);
@@ -3669,12 +3672,15 @@ static int parse_line(
u = user;
r = find_uid(u, &i.uid, uid_cache);
- if (r < 0) {
+ if (r == -ESRCH && arg_graceful) {
+ log_syntax(NULL, LOG_DEBUG, fname, line, r,
+ "%s: user '%s' not found, not adjusting ownership.", i.path, u);
+ missing_user_or_group = true;
+ } else if (r < 0) {
*invalid_config = true;
return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve user '%s': %m", u);
- }
-
- i.uid_set = true;
+ } else
+ i.uid_set = true;
}
if (!empty_or_dash(group)) {
@@ -3687,12 +3693,15 @@ static int parse_line(
g = group;
r = find_gid(g, &i.gid, gid_cache);
- if (r < 0) {
+ if (r == -ESRCH && arg_graceful) {
+ log_syntax(NULL, LOG_DEBUG, fname, line, r,
+ "%s: group '%s' not found, not adjusting ownership.", i.path, g);
+ missing_user_or_group = true;
+ } else if (r < 0) {
*invalid_config = true;
- return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve group '%s'.", g);
- }
-
- i.gid_set = true;
+ return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve group '%s': %m", g);
+ } else
+ i.gid_set = true;
}
if (!empty_or_dash(mode)) {
@@ -3717,7 +3726,20 @@ static int parse_line(
i.mode = m;
i.mode_set = true;
} else
- i.mode = IN_SET(i.type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA) ? 0755 : 0644;
+ i.mode = IN_SET(i.type,
+ CREATE_DIRECTORY,
+ TRUNCATE_DIRECTORY,
+ CREATE_SUBVOLUME,
+ CREATE_SUBVOLUME_INHERIT_QUOTA,
+ CREATE_SUBVOLUME_NEW_QUOTA) ? 0755 : 0644;
+
+ if (missing_user_or_group && (i.mode & ~0777) != 0) {
+ /* Refuse any special bits for nodes where we couldn't resolve the ownership properly. */
+ mode_t adjusted = i.mode & 0777;
+ log_syntax(NULL, LOG_INFO, fname, line, 0,
+ "Changing mode 0%o to 0%o because of changed ownership.", i.mode, adjusted);
+ i.mode = adjusted;
+ }
if (!empty_or_dash(age)) {
const char *a = age;
@@ -3839,6 +3861,7 @@ static int help(void) {
" --clean Clean up marked directories\n"
" --remove Remove marked files/directories\n"
" --boot Execute actions only safe at boot\n"
+ " --graceful Quitely ignore unknown users or groups\n"
" --prefix=PATH Only apply rules with the specified prefix\n"
" --exclude-prefix=PATH Ignore rules with the specified prefix\n"
" -E Ignore rules prefixed with /dev, /proc, /run, /sys\n"
@@ -3866,6 +3889,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_CLEAN,
ARG_REMOVE,
ARG_BOOT,
+ ARG_GRACEFUL,
ARG_PREFIX,
ARG_EXCLUDE_PREFIX,
ARG_ROOT,
@@ -3884,6 +3908,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "clean", no_argument, NULL, ARG_CLEAN },
{ "remove", no_argument, NULL, ARG_REMOVE },
{ "boot", no_argument, NULL, ARG_BOOT },
+ { "graceful", no_argument, NULL, ARG_GRACEFUL },
{ "prefix", required_argument, NULL, ARG_PREFIX },
{ "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX },
{ "root", required_argument, NULL, ARG_ROOT },
@@ -3933,6 +3958,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_boot = true;
break;
+ case ARG_GRACEFUL:
+ arg_graceful = true;
+ break;
+
case ARG_PREFIX:
if (strv_push(&arg_include_prefixes, optarg) < 0)
return log_oom();
diff --git a/units/local-fs.target b/units/local-fs.target
index 02797953a5..fe175a7af9 100644
--- a/units/local-fs.target
+++ b/units/local-fs.target
@@ -10,8 +10,9 @@
[Unit]
Description=Local File Systems
Documentation=man:systemd.special(7)
+
DefaultDependencies=no
-Conflicts=shutdown.target
After=local-fs-pre.target
+Conflicts=shutdown.target
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount
index 6b1bbdc91e..5d212015a5 100644
--- a/units/proc-sys-fs-binfmt_misc.automount
+++ b/units/proc-sys-fs-binfmt_misc.automount
@@ -11,11 +11,14 @@
Description=Arbitrary Executable File Formats File System Automount Point
Documentation=https://docs.kernel.org/admin-guide/binfmt-misc.html
Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+
+ConditionPathExists=/proc/sys/fs/binfmt_misc/
+ConditionPathIsReadWrite=/proc/sys/
+
DefaultDependencies=no
Before=sysinit.target
Conflicts=shutdown.target
-ConditionPathExists=/proc/sys/fs/binfmt_misc/
-ConditionPathIsReadWrite=/proc/sys/
+Before=shutdown.target
[Automount]
Where=/proc/sys/fs/binfmt_misc
diff --git a/units/quotaon.service.in b/units/quotaon.service.in
index ffabebfafe..7fa7061eea 100644
--- a/units/quotaon.service.in
+++ b/units/quotaon.service.in
@@ -10,10 +10,13 @@
[Unit]
Description=Enable File System Quotas
Documentation=man:quotaon(8)
+
+ConditionPathExists={{QUOTAON}}
+
DefaultDependencies=no
After=systemd-quotacheck.service
-Before=remote-fs.target shutdown.target
-ConditionPathExists={{QUOTAON}}
+Before=remote-fs.target
+Before=shutdown.target
[Service]
Type=oneshot
diff --git a/units/systemd-boot-update.service b/units/systemd-boot-update.service
index fe63fde35a..ce9187bbfe 100644
--- a/units/systemd-boot-update.service
+++ b/units/systemd-boot-update.service
@@ -13,8 +13,9 @@ Documentation=man:bootctl(1)
DefaultDependencies=no
After=local-fs.target
+Before=sysinit.target systemd-update-done.service
Conflicts=shutdown.target
-Before=sysinit.target shutdown.target systemd-update-done.service
+Before=shutdown.target
[Service]
Type=oneshot
diff --git a/units/systemd-firstboot.service b/units/systemd-firstboot.service
index 2e57b064c1..5fee85a287 100644
--- a/units/systemd-firstboot.service
+++ b/units/systemd-firstboot.service
@@ -10,13 +10,16 @@
[Unit]
Description=First Boot Wizard
Documentation=man:systemd-firstboot(1)
+
+ConditionPathIsReadWrite=/etc
+ConditionFirstBoot=yes
+
DefaultDependencies=no
-Conflicts=shutdown.target
After=systemd-remount-fs.service
-Before=systemd-sysusers.service systemd-vconsole-setup.service sysinit.target first-boot-complete.target shutdown.target
+Before=systemd-vconsole-setup.service sysinit.target first-boot-complete.target
Wants=first-boot-complete.target
-ConditionPathIsReadWrite=/etc
-ConditionFirstBoot=yes
+Conflicts=shutdown.target
+Before=shutdown.target
[Service]
Type=oneshot
diff --git a/units/systemd-growfs-root.service.in b/units/systemd-growfs-root.service.in
index 295bafd5af..61b825672d 100644
--- a/units/systemd-growfs-root.service.in
+++ b/units/systemd-growfs-root.service.in
@@ -10,9 +10,10 @@
[Unit]
Description=Grow Root File System
Documentation=man:systemd-growfs-root.service(8)
+
DefaultDependencies=no
-Conflicts=shutdown.target
After=systemd-repart.service systemd-remount-fs.service
+Conflicts=shutdown.target
Before=shutdown.target
[Service]
diff --git a/units/systemd-growfs@.service.in b/units/systemd-growfs@.service.in
index 7154e4ca76..d7c90e96fc 100644
--- a/units/systemd-growfs@.service.in
+++ b/units/systemd-growfs@.service.in
@@ -10,10 +10,11 @@
[Unit]
Description=Grow File System on %f
Documentation=man:systemd-growfs@.service(8)
+
DefaultDependencies=no
BindsTo=%i.mount
-Conflicts=shutdown.target
After=systemd-repart.service %i.mount
+Conflicts=shutdown.target
Before=shutdown.target
[Service]
diff --git a/units/systemd-hwdb-update.service.in b/units/systemd-hwdb-update.service.in
index a09fe8aa52..4ba36d1fc6 100644
--- a/units/systemd-hwdb-update.service.in
+++ b/units/systemd-hwdb-update.service.in
@@ -10,15 +10,18 @@
[Unit]
Description=Rebuild Hardware Database
Documentation=man:hwdb(7) man:systemd-hwdb(8)
-DefaultDependencies=no
-Conflicts=shutdown.target
-After=systemd-remount-fs.service
-Before=sysinit.target shutdown.target systemd-update-done.service
+
ConditionNeedsUpdate=/etc
ConditionPathExists=|!{{UDEVLIBEXECDIR}}/hwdb.bin
ConditionPathExists=|/etc/udev/hwdb.bin
ConditionDirectoryNotEmpty=|/etc/udev/hwdb.d/
+DefaultDependencies=no
+After=systemd-remount-fs.service
+Before=sysinit.target systemd-update-done.service
+Conflicts=shutdown.target
+Before=shutdown.target
+
[Service]
Type=oneshot
RemainAfterExit=yes
diff --git a/units/systemd-journal-catalog-update.service b/units/systemd-journal-catalog-update.service
index 477925685a..691e03fe62 100644
--- a/units/systemd-journal-catalog-update.service
+++ b/units/systemd-journal-catalog-update.service
@@ -10,11 +10,14 @@
[Unit]
Description=Rebuild Journal Catalog
Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+
+ConditionNeedsUpdate=/var
+
DefaultDependencies=no
-Conflicts=shutdown.target
After=local-fs.target systemd-tmpfiles-setup.service
-Before=sysinit.target shutdown.target systemd-update-done.service
-ConditionNeedsUpdate=/var
+Before=sysinit.target systemd-update-done.service
+Conflicts=shutdown.target
+Before=shutdown.target
[Service]
Type=oneshot
diff --git a/units/systemd-journal-flush.service b/units/systemd-journal-flush.service
index 5d0b811ae3..8c01587cad 100644
--- a/units/systemd-journal-flush.service
+++ b/units/systemd-journal-flush.service
@@ -10,12 +10,15 @@
[Unit]
Description=Flush Journal to Persistent Storage
Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+
+ConditionPathExists=!/etc/initrd-release
+
DefaultDependencies=no
-Wants=systemd-journald.service
-After=systemd-journald.service systemd-remount-fs.service
+After=systemd-remount-fs.service
Before=systemd-tmpfiles-setup.service
+Wants=systemd-journald.service
+After=systemd-journald.service
RequiresMountsFor=/var/log/journal
-ConditionPathExists=!/etc/initrd-release
[Service]
ExecStart=journalctl --flush
diff --git a/units/systemd-quotacheck.service.in b/units/systemd-quotacheck.service.in
index c3e936d220..05c14ff8b6 100644
--- a/units/systemd-quotacheck.service.in
+++ b/units/systemd-quotacheck.service.in
@@ -10,10 +10,13 @@
[Unit]
Description=File System Quota Check
Documentation=man:systemd-quotacheck.service(8)
+
+ConditionPathExists={{QUOTACHECK}}
+
DefaultDependencies=no
After=systemd-remount-fs.service
-Before=remote-fs.target shutdown.target
-ConditionPathExists={{QUOTACHECK}}
+Before=remote-fs.target
+Before=shutdown.target
[Service]
Type=oneshot
diff --git a/units/systemd-random-seed.service.in b/units/systemd-random-seed.service.in
index d57b2d1269..820fdd8536 100644
--- a/units/systemd-random-seed.service.in
+++ b/units/systemd-random-seed.service.in
@@ -11,15 +11,16 @@
Description=Load/Save OS Random Seed
Documentation=man:systemd-random-seed.service(8) man:random(4)
+ConditionVirtualization=!container
+ConditionPathExists=!/etc/initrd-release
+
DefaultDependencies=no
-RequiresMountsFor={{RANDOM_SEED}}
-Conflicts=shutdown.target
After=systemd-remount-fs.service
-Before=first-boot-complete.target shutdown.target
+Before=first-boot-complete.target
+RequiresMountsFor={{RANDOM_SEED}}
Wants=first-boot-complete.target
-
-ConditionVirtualization=!container
-ConditionPathExists=!/etc/initrd-release
+Conflicts=shutdown.target
+Before=shutdown.target
[Service]
Type=oneshot
diff --git a/units/systemd-remount-fs.service.in b/units/systemd-remount-fs.service.in
index 2abed1d0a9..be1dfd6199 100644
--- a/units/systemd-remount-fs.service.in
+++ b/units/systemd-remount-fs.service.in
@@ -11,11 +11,13 @@
Description=Remount Root and Kernel File Systems
Documentation=man:systemd-remount-fs.service(8)
Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+
DefaultDependencies=no
-Conflicts=shutdown.target
After=systemd-fsck-root.service
-Before=local-fs-pre.target local-fs.target shutdown.target
+Before=local-fs-pre.target local-fs.target
Wants=local-fs-pre.target
+Conflicts=shutdown.target
+Before=shutdown.target
[Service]
Type=oneshot
diff --git a/units/systemd-repart.service.in b/units/systemd-repart.service.in
index 105be680cd..35c4ca8ca5 100644
--- a/units/systemd-repart.service.in
+++ b/units/systemd-repart.service.in
@@ -10,22 +10,22 @@
[Unit]
Description=Repartition Root Disk
Documentation=man:systemd-repart.service(8)
-DefaultDependencies=no
-Conflicts=shutdown.target
-Wants=modprobe@loop.service modprobe@dm_mod.service
-After=initrd-usr-fs.target modprobe@loop.service modprobe@dm_mod.service
-Before=initrd-root-fs.target shutdown.target
+
ConditionVirtualization=!container
ConditionDirectoryNotEmpty=|/usr/lib/repart.d
ConditionDirectoryNotEmpty=|/usr/local/lib/repart.d
ConditionDirectoryNotEmpty=|/etc/repart.d
ConditionDirectoryNotEmpty=|/run/repart.d
-ConditionDirectoryNotEmpty=|/sysroot/usr/lib/repart.d
-ConditionDirectoryNotEmpty=|/sysroot/usr/local/lib/repart.d
-ConditionDirectoryNotEmpty=|/sysroot/etc/repart.d
ConditionDirectoryNotEmpty=|/sysusr/usr/lib/repart.d
ConditionDirectoryNotEmpty=|/sysusr/usr/local/lib/repart.d
+DefaultDependencies=no
+Wants=modprobe@loop.service modprobe@dm_mod.service
+After=initrd-usr-fs.target modprobe@loop.service modprobe@dm_mod.service
+Before=initrd-root-fs.target
+Conflicts=shutdown.target initrd-switch-root.target
+Before=shutdown.target initrd-switch-root.target
+
[Service]
Type=oneshot
RemainAfterExit=yes
diff --git a/units/systemd-rfkill.socket b/units/systemd-rfkill.socket
index 4ca8d6fc04..81c0e8c9c6 100644
--- a/units/systemd-rfkill.socket
+++ b/units/systemd-rfkill.socket
@@ -10,12 +10,13 @@
[Unit]
Description=Load/Save RF Kill Switch Status /dev/rfkill Watch
Documentation=man:systemd-rfkill.socket(8)
+
DefaultDependencies=no
BindsTo=sys-devices-virtual-misc-rfkill.device
After=sys-devices-virtual-misc-rfkill.device systemd-remount-fs.service
-RequiresMountsFor=/var/lib/systemd/rfkill
Conflicts=shutdown.target
Before=shutdown.target
+RequiresMountsFor=/var/lib/systemd/rfkill
[Socket]
ListenSpecial=/dev/rfkill
diff --git a/units/systemd-sysusers.service b/units/systemd-sysusers.service
index 0eb40294b2..2ec2766841 100644
--- a/units/systemd-sysusers.service
+++ b/units/systemd-sysusers.service
@@ -11,15 +11,15 @@
Description=Create System Users
Documentation=man:sysusers.d(5) man:systemd-sysusers.service(8)
+ConditionNeedsUpdate=|/etc
+ConditionCredential=|sysusers.extra
+
DefaultDependencies=no
After=systemd-remount-fs.service
Before=sysinit.target systemd-update-done.service
Conflicts=shutdown.target initrd-switch-root.target
Before=shutdown.target initrd-switch-root.target
-ConditionNeedsUpdate=|/etc
-ConditionCredential=|sysusers.extra
-
[Service]
Type=oneshot
RemainAfterExit=yes
diff --git a/units/systemd-tmpfiles-setup-dev.service b/units/systemd-tmpfiles-setup-dev.service
index c65539aa79..d9cb3de554 100644
--- a/units/systemd-tmpfiles-setup-dev.service
+++ b/units/systemd-tmpfiles-setup-dev.service
@@ -12,7 +12,6 @@ Description=Create Static Device Nodes in /dev
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
DefaultDependencies=no
-After=systemd-sysusers.service
Before=sysinit.target local-fs-pre.target systemd-udevd.service
Conflicts=shutdown.target initrd-switch-root.target
Before=shutdown.target initrd-switch-root.target
@@ -20,6 +19,6 @@ Before=shutdown.target initrd-switch-root.target
[Service]
Type=oneshot
RemainAfterExit=yes
-ExecStart=systemd-tmpfiles --prefix=/dev --create --boot
+ExecStart=systemd-tmpfiles --prefix=/dev --create --boot --graceful
SuccessExitStatus=DATAERR CANTCREAT
LoadCredential=tmpfiles.extra
diff --git a/units/systemd-tmpfiles-setup.service b/units/systemd-tmpfiles-setup.service
index a420465534..506f53eaa2 100644
--- a/units/systemd-tmpfiles-setup.service
+++ b/units/systemd-tmpfiles-setup.service
@@ -21,7 +21,7 @@ RefuseManualStop=yes
[Service]
Type=oneshot
RemainAfterExit=yes
-ExecStart=systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev
+ExecStart=systemd-tmpfiles --create --remove --boot
SuccessExitStatus=DATAERR CANTCREAT
LoadCredential=tmpfiles.extra
LoadCredential=login.motd
diff --git a/units/systemd-update-utmp.service.in b/units/systemd-update-utmp.service.in
index cedefa8e08..f1278fae32 100644
--- a/units/systemd-update-utmp.service.in
+++ b/units/systemd-update-utmp.service.in
@@ -10,11 +10,13 @@
[Unit]
Description=Record System Boot/Shutdown in UTMP
Documentation=man:systemd-update-utmp.service(8) man:utmp(5)
+
DefaultDependencies=no
-RequiresMountsFor=/var/log/wtmp
-Conflicts=shutdown.target
After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service
-Before=sysinit.target shutdown.target
+Before=sysinit.target
+Conflicts=shutdown.target
+Before=shutdown.target
+RequiresMountsFor=/var/log/wtmp
[Service]
Type=oneshot
diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
index 0009528307..41d738a63d 100644
--- a/units/systemd-vconsole-setup.service.in
+++ b/units/systemd-vconsole-setup.service.in
@@ -10,10 +10,12 @@
[Unit]
Description=Setup Virtual Console
Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5)
+
+ConditionPathExists=/dev/tty0
+
DefaultDependencies=no
Before=sysinit.target
Before=initrd-switch-root.target shutdown.target
-ConditionPathExists=/dev/tty0
[Service]
Type=oneshot