mirror of
https://github.com/systemd/systemd.git
synced 2025-03-28 02:50:16 +03:00
firstboot: get rid of firstboot generator again, introduce ConditionFirstBoot= instead
As Zbigniew pointed out a new ConditionFirstBoot= appears like the nicer way to hook in systemd-firstboot.service on first boots (those with /etc unpopulated), so let's do this, and get rid of the generator again.
This commit is contained in:
parent
45035609fc
commit
e26807239b
1
.gitignore
vendored
1
.gitignore
vendored
@ -65,7 +65,6 @@
|
||||
/systemd-detect-virt
|
||||
/systemd-efi-boot-generator
|
||||
/systemd-firstboot
|
||||
/systemd-firstboot-generator
|
||||
/systemd-fsck
|
||||
/systemd-fstab-generator
|
||||
/systemd-getty-generator
|
||||
|
@ -63,7 +63,7 @@ MANPAGES += \
|
||||
man/systemd-delta.1 \
|
||||
man/systemd-detect-virt.1 \
|
||||
man/systemd-efi-boot-generator.8 \
|
||||
man/systemd-firstboot.8 \
|
||||
man/systemd-firstboot.1 \
|
||||
man/systemd-fsck@.service.8 \
|
||||
man/systemd-fstab-generator.8 \
|
||||
man/systemd-getty-generator.8 \
|
||||
@ -194,7 +194,7 @@ MANPAGES_ALIAS += \
|
||||
man/systemd-ask-password-console.path.8 \
|
||||
man/systemd-ask-password-wall.path.8 \
|
||||
man/systemd-ask-password-wall.service.8 \
|
||||
man/systemd-firstboot.service.8 \
|
||||
man/systemd-firstboot.service.1 \
|
||||
man/systemd-fsck-root.service.8 \
|
||||
man/systemd-fsck.8 \
|
||||
man/systemd-hibernate.service.8 \
|
||||
@ -300,7 +300,7 @@ man/sd_notifyf.3: man/sd_notify.3
|
||||
man/systemd-ask-password-console.path.8: man/systemd-ask-password-console.service.8
|
||||
man/systemd-ask-password-wall.path.8: man/systemd-ask-password-console.service.8
|
||||
man/systemd-ask-password-wall.service.8: man/systemd-ask-password-console.service.8
|
||||
man/systemd-firstboot.service.8: man/systemd-firstboot.8
|
||||
man/systemd-firstboot.service.1: man/systemd-firstboot.1
|
||||
man/systemd-fsck-root.service.8: man/systemd-fsck@.service.8
|
||||
man/systemd-fsck.8: man/systemd-fsck@.service.8
|
||||
man/systemd-hibernate.service.8: man/systemd-suspend.service.8
|
||||
|
11
Makefile.am
11
Makefile.am
@ -1894,15 +1894,8 @@ nodist_systemunit_DATA += \
|
||||
EXTRA_DIST += \
|
||||
units/systemd-firstboot.service.in
|
||||
|
||||
systemgenerator_PROGRAMS += \
|
||||
systemd-firstboot-generator
|
||||
|
||||
systemd_firstboot_generator_SOURCES = \
|
||||
src/firstboot/firstboot-generator.c
|
||||
|
||||
systemd_firstboot_generator_LDADD = \
|
||||
libsystemd-label.la \
|
||||
libsystemd-shared.la
|
||||
SYSINIT_TARGET_WANTS += \
|
||||
systemd-firstboot.service
|
||||
|
||||
endif
|
||||
|
||||
|
@ -901,6 +901,7 @@
|
||||
<term><varname>ConditionCapability=</varname></term>
|
||||
<term><varname>ConditionACPower=</varname></term>
|
||||
<term><varname>ConditionNeedsUpdate=</varname></term>
|
||||
<term><varname>ConditionFirstBoot=</varname></term>
|
||||
<term><varname>ConditionPathExists=</varname></term>
|
||||
<term><varname>ConditionPathExistsGlob=</varname></term>
|
||||
<term><varname>ConditionPathIsDirectory=</varname></term>
|
||||
@ -1101,6 +1102,18 @@
|
||||
files's modification time gets reset
|
||||
indicating a completed update.</para>
|
||||
|
||||
<para><varname>ConditionFirstBoot=</varname>
|
||||
takes a boolean argument. This
|
||||
condition may be used to
|
||||
conditionalize units on whether the
|
||||
system is booting up with an
|
||||
unpopulated <filename>/etc</filename>
|
||||
directory. This may be used to
|
||||
populate <filename>/etc</filename> on
|
||||
the first boot after factory reset, or
|
||||
when a new system instances boots up
|
||||
for the first time.</para>
|
||||
|
||||
<para>With
|
||||
<varname>ConditionPathExists=</varname>
|
||||
a file existence condition is
|
||||
|
@ -120,6 +120,20 @@ static bool condition_test_needs_update(Condition *c) {
|
||||
(usr.st_mtim.tv_sec == other.st_mtim.tv_sec && usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec)) == !c->negate;
|
||||
}
|
||||
|
||||
static bool condition_test_first_boot(Condition *c) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_FIRST_BOOT);
|
||||
|
||||
r = parse_boolean(c->parameter);
|
||||
if (r < 0)
|
||||
return c->negate;
|
||||
|
||||
return ((access("/run/systemd/first-boot", F_OK) >= 0) == !!r) == !c->negate;
|
||||
}
|
||||
|
||||
static bool condition_test(Condition *c) {
|
||||
assert(c);
|
||||
|
||||
@ -202,6 +216,9 @@ static bool condition_test(Condition *c) {
|
||||
case CONDITION_NEEDS_UPDATE:
|
||||
return condition_test_needs_update(c);
|
||||
|
||||
case CONDITION_FIRST_BOOT:
|
||||
return condition_test_first_boot(c);
|
||||
|
||||
case CONDITION_NULL:
|
||||
return !c->negate;
|
||||
|
||||
|
@ -162,6 +162,7 @@ Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path, CONDITION_D
|
||||
Unit.ConditionFileNotEmpty, config_parse_unit_condition_path, CONDITION_FILE_NOT_EMPTY, 0
|
||||
Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_FILE_IS_EXECUTABLE, 0
|
||||
Unit.ConditionNeedsUpdate, config_parse_unit_condition_path, CONDITION_NEEDS_UPDATE, 0
|
||||
Unit.ConditionFirstBoot, config_parse_unit_condition_path, CONDITION_FIRST_BOOT, 0
|
||||
Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0
|
||||
Unit.ConditionArchitecture, config_parse_unit_condition_string, CONDITION_ARCHITECTURE, 0
|
||||
Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, 0
|
||||
|
@ -1648,11 +1648,11 @@ int main(int argc, char *argv[]) {
|
||||
m->initrd_timestamp = initrd_timestamp;
|
||||
m->security_start_timestamp = security_start_timestamp;
|
||||
m->security_finish_timestamp = security_finish_timestamp;
|
||||
m->is_first_boot = empty_etc;
|
||||
|
||||
manager_set_default_rlimits(m, arg_default_rlimit);
|
||||
manager_environment_add(m, NULL, arg_default_environment);
|
||||
manager_set_show_status(m, arg_show_status);
|
||||
manager_set_first_boot(m, empty_etc);
|
||||
|
||||
/* Remember whether we should queue the default job */
|
||||
queue_default_job = !arg_serialization || arg_switched_root;
|
||||
|
@ -2477,7 +2477,7 @@ void manager_check_finished(Manager *m) {
|
||||
m->confirm_spawn = false;
|
||||
|
||||
/* This is no longer the first boot */
|
||||
m->is_first_boot = false;
|
||||
manager_set_first_boot(m, false);
|
||||
|
||||
if (dual_timestamp_is_set(&m->finish_timestamp))
|
||||
return;
|
||||
@ -2631,7 +2631,6 @@ void manager_run_generators(Manager *m) {
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
const char *generator_path;
|
||||
const char *argv[5];
|
||||
const char *env[2];
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -2665,14 +2664,8 @@ void manager_run_generators(Manager *m) {
|
||||
argv[3] = m->generator_unit_path_late;
|
||||
argv[4] = NULL;
|
||||
|
||||
if (m->is_first_boot) {
|
||||
env[0] = (char*) "SYSTEMD_FIRST_BOOT=1";
|
||||
env[1] = NULL;
|
||||
} else
|
||||
env[0] = NULL;
|
||||
|
||||
RUN_WITH_UMASK(0022)
|
||||
execute_directory(generator_path, d, DEFAULT_TIMEOUT_USEC, (char**) argv, (char**) env);
|
||||
execute_directory(generator_path, d, DEFAULT_TIMEOUT_USEC, (char**) argv);
|
||||
|
||||
finish:
|
||||
trim_generator_dir(m, &m->generator_unit_path);
|
||||
@ -2816,6 +2809,20 @@ static bool manager_get_show_status(Manager *m) {
|
||||
return plymouth_running();
|
||||
}
|
||||
|
||||
void manager_set_first_boot(Manager *m, bool b) {
|
||||
assert(m);
|
||||
|
||||
if (m->running_as != SYSTEMD_SYSTEM)
|
||||
return;
|
||||
|
||||
m->first_boot = b;
|
||||
|
||||
if (m->first_boot)
|
||||
touch("/run/systemd/first-boot");
|
||||
else
|
||||
unlink("/run/systemd/first-boot");
|
||||
}
|
||||
|
||||
void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) {
|
||||
va_list ap;
|
||||
|
||||
|
@ -228,6 +228,7 @@ struct Manager {
|
||||
bool dispatching_dbus_queue:1;
|
||||
|
||||
bool taint_usr:1;
|
||||
bool first_boot:1;
|
||||
|
||||
ShowStatus show_status;
|
||||
bool confirm_spawn;
|
||||
@ -243,7 +244,6 @@ struct Manager {
|
||||
bool default_cpu_accounting;
|
||||
bool default_memory_accounting;
|
||||
bool default_blockio_accounting;
|
||||
bool is_first_boot;
|
||||
|
||||
usec_t default_timer_accuracy_usec;
|
||||
|
||||
@ -334,6 +334,8 @@ void manager_undo_generators(Manager *m);
|
||||
void manager_recheck_journal(Manager *m);
|
||||
|
||||
void manager_set_show_status(Manager *m, ShowStatus mode);
|
||||
void manager_set_first_boot(Manager *m, bool b);
|
||||
|
||||
void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) _printf_(4,5);
|
||||
void manager_flip_auto_status(Manager *m, bool enable);
|
||||
|
||||
|
@ -375,7 +375,7 @@ int main(int argc, char *argv[]) {
|
||||
arguments[0] = NULL;
|
||||
arguments[1] = arg_verb;
|
||||
arguments[2] = NULL;
|
||||
execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments, NULL);
|
||||
execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
|
||||
|
||||
if (!in_container && !in_initrd() &&
|
||||
access("/run/initramfs/shutdown", X_OK) == 0) {
|
||||
|
@ -1,71 +0,0 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2014 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "util.h"
|
||||
#include "mkdir.h"
|
||||
|
||||
static const char *arg_dest = "/tmp";
|
||||
|
||||
static bool is_first_boot(void) {
|
||||
const char *e;
|
||||
|
||||
e = getenv("SYSTEMD_FIRST_BOOT");
|
||||
if (!e)
|
||||
return false;
|
||||
|
||||
return parse_boolean(e) > 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int r;
|
||||
|
||||
if (argc > 1 && argc != 4) {
|
||||
log_error("This program takes three or no arguments.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
arg_dest = argv[2];
|
||||
|
||||
log_set_target(LOG_TARGET_SAFE);
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
umask(0022);
|
||||
|
||||
if (is_first_boot()) {
|
||||
const char *t;
|
||||
|
||||
t = strappenda(arg_dest, "/default.target.wants/systemd-firstboot.service");
|
||||
|
||||
mkdir_parents(t, 0755);
|
||||
if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-firstboot.service", t) < 0 && errno != EEXIST) {
|
||||
log_error("Failed to create firstboot service symlinks %s: %m", t);
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
@ -257,6 +257,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
|
||||
[CONDITION_AC_POWER] = "ConditionACPower",
|
||||
[CONDITION_ARCHITECTURE] = "ConditionArchitecture",
|
||||
[CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
|
||||
[CONDITION_FIRST_BOOT] = "ConditionFirstBoot",
|
||||
[CONDITION_NULL] = "ConditionNull"
|
||||
};
|
||||
|
||||
|
@ -45,6 +45,7 @@ typedef enum ConditionType {
|
||||
CONDITION_AC_POWER,
|
||||
CONDITION_ARCHITECTURE,
|
||||
CONDITION_NEEDS_UPDATE,
|
||||
CONDITION_FIRST_BOOT,
|
||||
CONDITION_NULL,
|
||||
_CONDITION_TYPE_MAX,
|
||||
_CONDITION_TYPE_INVALID = -1
|
||||
|
@ -3795,7 +3795,7 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
|
||||
return endswith(de->d_name, suffix);
|
||||
}
|
||||
|
||||
void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[], char *env[]) {
|
||||
void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) {
|
||||
pid_t executor_pid;
|
||||
int r;
|
||||
|
||||
@ -3826,14 +3826,6 @@ void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv
|
||||
|
||||
assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
|
||||
|
||||
if (!strv_isempty(env)) {
|
||||
char **i;
|
||||
|
||||
STRV_FOREACH(i, env)
|
||||
putenv(*i);
|
||||
}
|
||||
|
||||
|
||||
if (!d) {
|
||||
d = _d = opendir(directory);
|
||||
if (!d) {
|
||||
|
@ -505,7 +505,7 @@ bool tty_is_console(const char *tty) _pure_;
|
||||
int vtnr_from_tty(const char *tty);
|
||||
const char *default_term_for_tty(const char *tty);
|
||||
|
||||
void execute_directory(const char *directory, DIR *_d, usec_t timeout, char *argv[], char *env[]);
|
||||
void execute_directory(const char *directory, DIR *_d, usec_t timeout, char *argv[]);
|
||||
|
||||
int kill_and_sigcont(pid_t pid, int sig);
|
||||
|
||||
|
@ -110,7 +110,7 @@ static int execute(char **modes, char **states) {
|
||||
arguments[1] = (char*) "pre";
|
||||
arguments[2] = arg_verb;
|
||||
arguments[3] = NULL;
|
||||
execute_directory(SYSTEM_SLEEP_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments, NULL);
|
||||
execute_directory(SYSTEM_SLEEP_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
|
||||
|
||||
log_struct(LOG_INFO,
|
||||
MESSAGE_ID(SD_MESSAGE_SLEEP_START),
|
||||
@ -129,7 +129,7 @@ static int execute(char **modes, char **states) {
|
||||
NULL);
|
||||
|
||||
arguments[1] = (char*) "post";
|
||||
execute_directory(SYSTEM_SLEEP_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments, NULL);
|
||||
execute_directory(SYSTEM_SLEEP_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ Conflicts=shutdown.target
|
||||
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service systemd-sysusers.service
|
||||
Before=sysinit.target shutdown.target
|
||||
ConditionPathIsReadWrite=/etc
|
||||
ConditionFirstBoot=yes
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
Loading…
x
Reference in New Issue
Block a user