diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-05-23 18:53:13 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-23 18:53:13 +0200 |
commit | 3fa7e62c4c94cf2268730d64a10f39285a431f20 (patch) | |
tree | 7452c6e3412e7751cd8c5fc815ac802ad6810c08 | |
parent | sd-bus: refuse to send messages with an invalid string (diff) | |
parent | firstboot: process the root account after sysusers created it (diff) | |
download | systemd-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
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 |