summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-07-07 19:25:31 +0200
committerLennart Poettering <lennart@poettering.net>2014-07-07 21:05:09 +0200
commite26807239bd65bc17535a53cd540f38600e7ef24 (patch)
tree3100aec0ebcf4743d138fcf4d6d03977b8a90817
parent45035609fcfc3fe09324988c4929a3c147171c23 (diff)
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.
-rw-r--r--.gitignore1
-rw-r--r--Makefile-man.am6
-rw-r--r--Makefile.am11
-rw-r--r--man/systemd.unit.xml13
-rw-r--r--src/core/condition.c17
-rw-r--r--src/core/load-fragment-gperf.gperf.m41
-rw-r--r--src/core/main.c2
-rw-r--r--src/core/manager.c25
-rw-r--r--src/core/manager.h4
-rw-r--r--src/core/shutdown.c2
-rw-r--r--src/firstboot/firstboot-generator.c71
-rw-r--r--src/shared/condition-util.c1
-rw-r--r--src/shared/condition-util.h1
-rw-r--r--src/shared/util.c10
-rw-r--r--src/shared/util.h2
-rw-r--r--src/sleep/sleep.c4
-rw-r--r--units/systemd-firstboot.service.in1
17 files changed, 64 insertions, 108 deletions
diff --git a/.gitignore b/.gitignore
index 1ba3d06cf..e3ddbf8d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,7 +65,6 @@
/systemd-detect-virt
/systemd-efi-boot-generator
/systemd-firstboot
-/systemd-firstboot-generator
/systemd-fsck
/systemd-fstab-generator
/systemd-getty-generator
diff --git a/Makefile-man.am b/Makefile-man.am
index e6043f1ff..66c40b466 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -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
diff --git a/Makefile.am b/Makefile.am
index 321379ca5..3ddbdf77d 100644
--- a/Makefile.am
+++ b/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
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index cd3279c19..b1f810898 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -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
diff --git a/src/core/condition.c b/src/core/condition.c
index 410fb3679..353e0c97f 100644
--- a/src/core/condition.c
+++ b/src/core/condition.c
@@ -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;
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index a7c4469a4..4c092d77a 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -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
diff --git a/src/core/main.c b/src/core/main.c
index e1fc3f371..a21a959be 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -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;
diff --git a/src/core/manager.c b/src/core/manager.c
index 9d078c0af..3dffbe259 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -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;
diff --git a/src/core/manager.h b/src/core/manager.h
index eff639d1b..718c29fa0 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -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);
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index e7771c968..fde3ce9c2 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -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) {
diff --git a/src/firstboot/firstboot-generator.c b/src/firstboot/firstboot-generator.c
deleted file mode 100644
index 6d23f40fa..000000000
--- a/src/firstboot/firstboot-generator.c
+++ /dev/null
@@ -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;
-}
diff --git a/src/shared/condition-util.c b/src/shared/condition-util.c
index 7b89b0fba..928edeeb9 100644
--- a/src/shared/condition-util.c
+++ b/src/shared/condition-util.c
@@ -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"
};
diff --git a/src/shared/condition-util.h b/src/shared/condition-util.h
index 0b09f83f9..047fdbfd8 100644
--- a/src/shared/condition-util.h
+++ b/src/shared/condition-util.h
@@ -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
diff --git a/src/shared/util.c b/src/shared/util.c
index 88511b69c..33427981e 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -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) {
diff --git a/src/shared/util.h b/src/shared/util.h
index fb852d697..c5eadc97c 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -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);
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index 3b0e927c4..5adbea595 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -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;
}
diff --git a/units/systemd-firstboot.service.in b/units/systemd-firstboot.service.in
index e7ae74556..a8719a8c7 100644
--- a/units/systemd-firstboot.service.in
+++ b/units/systemd-firstboot.service.in
@@ -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