[systemd-commits] 13 commits - .gitignore Makefile.am man/systemd.unit.xml src/ac-power.c src/ac-power.h src/condition.c src/condition.h src/cryptsetup.c src/cryptsetup-generator.c src/dbus-manager.c src/label.c src/load-fragment.c src/log.c src/main.c src/manager.c src/manager.h src/modules-load.c src/mount.c src/mount-setup.c src/selinux-setup.c src/service.c src/timestamp.c src/util.c src/util.h TODO
Lennart Poettering
lennart at kemper.freedesktop.org
Wed Nov 10 13:40:25 PST 2010
.gitignore | 4
Makefile.am | 46 ++++++++
TODO | 2
man/systemd.unit.xml | 27 +++--
src/ac-power.c | 17 ++-
src/ac-power.h | 27 -----
src/condition.c | 15 +-
src/condition.h | 1
src/cryptsetup-generator.c | 239 +++++++++++++++++++++++++++++++++++++++++++++
src/cryptsetup.c | 53 +++++++++
src/dbus-manager.c | 3
src/label.c | 13 --
src/load-fragment.c | 41 +++++++
src/log.c | 4
src/main.c | 40 +++++++
src/manager.c | 43 +++++---
src/manager.h | 1
src/modules-load.c | 3
src/mount-setup.c | 18 +++
src/mount.c | 50 ---------
src/selinux-setup.c | 10 +
src/service.c | 7 +
src/timestamp.c | 39 +++++++
src/util.c | 68 ++++++++++++
src/util.h | 6 -
25 files changed, 653 insertions(+), 124 deletions(-)
New commits:
commit f3b6a3edbce43df47374761529dd663c9a39c612
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Nov 10 22:35:05 2010 +0100
main: rename process on startup to 'systemd' to avoid confusion
diff --git a/src/main.c b/src/main.c
index cd73ee2..ea2f0c1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -31,6 +31,7 @@
#include <signal.h>
#include <sys/wait.h>
#include <fcntl.h>
+#include <sys/prctl.h>
#include "manager.h"
#include "log.h"
@@ -896,6 +897,7 @@ int main(int argc, char *argv[]) {
bool reexecute = false;
const char *shutdown_verb = NULL;
dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
+ char systemd[] = "systemd";
if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
/* This is compatbility support for SysV, where
@@ -907,6 +909,14 @@ int main(int argc, char *argv[]) {
return 1;
}
+ /* If we get started via the /sbin/init symlink then we are
+ called 'init'. After a subsequent reexecution we are then
+ called 'systemd'. That is confusing, hence let's call us
+ systemd right-away. */
+
+ program_invocation_short_name = systemd;
+ prctl(PR_SET_NAME, systemd);
+
log_show_color(isatty(STDERR_FILENO) > 0);
log_show_location(false);
log_set_max_level(LOG_INFO);
commit d257ddef22ff1a1b98e6172799819e6511b1bcfb
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Nov 10 22:28:19 2010 +0100
unit: add ConditionNull= condition
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 4e1d9f3..39862cf 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -574,6 +574,7 @@
<varlistentry>
<term><varname>ConditionPathExists=</varname></term>
<term><varname>ConditionKernelCommandLine=</varname></term>
+ <term><varname>ConditionNull=</varname></term>
<listitem><para>Before starting a unit
verify that the specified condition is
@@ -602,15 +603,23 @@
must either be a single word, or an
assignment (i.e. two words, seperated
by the equality sign). In the former
- case the kernel command line is search
- for the word appearing as is, or as
- left hand side of an assignment. In
- the latter case the exact assignment
- is looked for with right and left hand
- side matching. If multiple conditions
- are specified the unit will be
- executed iff at least one of them
- applies (i.e. a logical OR is
+ case the kernel command line is
+ searched for the word appearing as is,
+ or as left hand side of an
+ assignment. In the latter case the
+ exact assignment is looked for with
+ right and left hand side
+ matching. Finally,
+ <varname>ConditionNull=</varname> may
+ be used to add a constant condition
+ check value to the unit. It takes a
+ boolean argument. If set to
+ <varname>false</varname> the condition
+ will always fail, otherwise
+ succeed. If multiple conditions are
+ specified the unit will be executed
+ iff at least one of them applies
+ (i.e. a logical OR is
applied).</para></listitem>
</varlistentry>
</variablelist>
diff --git a/src/condition.c b/src/condition.c
index 1e69b61..4bbd4db 100644
--- a/src/condition.c
+++ b/src/condition.c
@@ -34,10 +34,11 @@ Condition* condition_new(ConditionType type, const char *parameter, bool negate)
c->type = type;
c->negate = negate;
- if (!(c->parameter = strdup(parameter))) {
- free(c);
- return NULL;
- }
+ if (parameter)
+ if (!(c->parameter = strdup(parameter))) {
+ free(c);
+ return NULL;
+ }
return c;
}
@@ -108,6 +109,9 @@ bool condition_test(Condition *c) {
case CONDITION_KERNEL_COMMAND_LINE:
return !!test_kernel_command_line(c->parameter) == !c->negate;
+ case CONDITION_NULL:
+ return !c->negate;
+
default:
assert_not_reached("Invalid condition type.");
}
@@ -152,7 +156,8 @@ void condition_dump_list(Condition *first, FILE *f, const char *prefix) {
static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
- [CONDITION_PATH_EXISTS] = "ConditionPathExists"
+ [CONDITION_PATH_EXISTS] = "ConditionPathExists",
+ [CONDITION_NULL] = "ConditionNull"
};
DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);
diff --git a/src/condition.h b/src/condition.h
index 4e0d63c..b9d3f34 100644
--- a/src/condition.h
+++ b/src/condition.h
@@ -29,6 +29,7 @@
typedef enum ConditionType {
CONDITION_PATH_EXISTS,
CONDITION_KERNEL_COMMAND_LINE,
+ CONDITION_NULL,
_CONDITION_TYPE_MAX,
_CONDITION_TYPE_INVALID = -1
} ConditionType;
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 4f94c64..424e6c3 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1444,7 +1444,7 @@ static int config_parse_condition_path(
rvalue++;
if (!path_is_absolute(rvalue)) {
- log_error("[%s:%u] Path in condition not absolute: %s", filename, line, rvalue);
+ log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue);
return 0;
}
@@ -1483,6 +1483,43 @@ static int config_parse_condition_kernel(
return 0;
}
+static int config_parse_condition_null(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Unit *u = data;
+ Condition *c;
+ bool negate;
+ int b;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if ((negate = rvalue[0] == '!'))
+ rvalue++;
+
+ if ((b = parse_boolean(rvalue)) < 0) {
+ log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue);
+ return 0;
+ }
+
+ if (!b)
+ negate = !negate;
+
+ if (!(c = condition_new(CONDITION_NULL, NULL, negate)))
+ return -ENOMEM;
+
+ LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
+ return 0;
+}
+
static DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
#define FOLLOW_MAX 8
@@ -1656,6 +1693,7 @@ static void dump_items(FILE *f, const ConfigItem *items) {
{ config_parse_ip_tos, "TOS" },
{ config_parse_condition_path, "CONDITION" },
{ config_parse_condition_kernel, "CONDITION" },
+ { config_parse_condition_null, "CONDITION" },
};
assert(f);
@@ -1778,6 +1816,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "JobTimeoutSec", config_parse_usec, &u->meta.job_timeout, "Unit" },
{ "ConditionPathExists", config_parse_condition_path, u, "Unit" },
{ "ConditionKernelCommandLine", config_parse_condition_kernel, u, "Unit" },
+ { "ConditionNull", config_parse_condition_null, u, "Unit" },
{ "PIDFile", config_parse_path, &u->service.pid_file, "Service" },
{ "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" },
commit 06cdd2484c5d0b7792168a7c2d99311e35b0fb8e
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 8 00:43:33 2010 -0500
ac-power: make ac-power a proper binary that scripts can call
diff --git a/.gitignore b/.gitignore
index a99cd17..21dd394 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+systemd-ac-power
systemd-timestamp
systemd-cryptsetup
systemd-cryptsetup-generator
diff --git a/Makefile.am b/Makefile.am
index 52bd13f..69faa55 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -116,7 +116,8 @@ rootlibexec_PROGRAMS = \
systemd-quotacheck \
systemd-cryptsetup \
systemd-cryptsetup-generator \
- systemd-timestamp
+ systemd-timestamp \
+ systemd-ac-power
noinst_PROGRAMS = \
test-engine \
@@ -724,6 +725,17 @@ systemd_timestamp_CFLAGS = \
systemd_timestamp_LDADD = \
libsystemd-basic.la
+systemd_ac_power_SOURCES = \
+ src/ac-power.c
+
+systemd_ac_power_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(UDEV_CFLAGS)
+
+systemd_ac_power_LDADD = \
+ libsystemd-basic.la \
+ $(UDEV_LIBS)
+
systemd_cryptsetup_SOURCES = \
src/cryptsetup.c
diff --git a/src/ac-power.c b/src/ac-power.c
index a30216f..24a68e7 100644
--- a/src/ac-power.c
+++ b/src/ac-power.c
@@ -26,9 +26,8 @@
#include <libudev.h>
#include "util.h"
-#include "ac-power.h"
-int on_ac_power(void) {
+static int on_ac_power(void) {
int r;
struct udev *udev;
@@ -96,3 +95,17 @@ finish:
return r;
}
+
+int main(int argc, char *argv[]) {
+ int r;
+
+ /* This is mostly intended to be used for scripts which want
+ * to detect whether AC power is plugged in or not. */
+
+ if ((r = on_ac_power()) < 0) {
+ log_error("Failed to read AC status: %s", strerror(-r));
+ return EXIT_FAILURE;
+ }
+
+ return r == 0;
+}
diff --git a/src/ac-power.h b/src/ac-power.h
deleted file mode 100644
index 24f28b5..0000000
--- a/src/ac-power.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#ifndef fooacpowerhfoo
-#define fooacpowerhfoo
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 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
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-int on_ac_power(void);
-
-#endif
commit e9ddabc246ced239cbce436e16792dc4c3d1b52d
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 8 00:31:09 2010 -0500
manager: parse RD_TIMESTAMP passed from initrd
diff --git a/.gitignore b/.gitignore
index 4223788..a99cd17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+systemd-timestamp
systemd-cryptsetup
systemd-cryptsetup-generator
systemd-tty-ask-password-agent
diff --git a/Makefile.am b/Makefile.am
index 3371c59..52bd13f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -115,7 +115,8 @@ rootlibexec_PROGRAMS = \
systemd-fsck \
systemd-quotacheck \
systemd-cryptsetup \
- systemd-cryptsetup-generator
+ systemd-cryptsetup-generator \
+ systemd-timestamp
noinst_PROGRAMS = \
test-engine \
@@ -714,6 +715,15 @@ systemd_quotacheck_CFLAGS = \
systemd_quotacheck_LDADD = \
libsystemd-basic.la
+systemd_timestamp_SOURCES = \
+ src/timestamp.c
+
+systemd_timestamp_CFLAGS = \
+ $(AM_CFLAGS)
+
+systemd_timestamp_LDADD = \
+ libsystemd-basic.la
+
systemd_cryptsetup_SOURCES = \
src/cryptsetup.c
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index c195031..769035f 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -150,7 +150,9 @@
#define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \
" <property name=\"Version\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"RunningAs\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"InitRDTimestamp\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"StartupTimestamp\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"FinishTimestamp\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"LogLevel\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"LogTarget\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"NNames\" type=\"u\" access=\"read\"/>\n" \
@@ -300,6 +302,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
const BusProperty properties[] = {
{ "org.freedesktop.systemd1.Manager", "Version", bus_property_append_string, "s", PACKAGE_STRING },
{ "org.freedesktop.systemd1.Manager", "RunningAs", bus_manager_append_running_as, "s", &m->running_as },
+ { "org.freedesktop.systemd1.Manager", "InitRDTimestamp", bus_property_append_uint64, "t", &m->initrd_timestamp.realtime },
{ "org.freedesktop.systemd1.Manager", "StartupTimestamp", bus_property_append_uint64, "t", &m->startup_timestamp.realtime },
{ "org.freedesktop.systemd1.Manager", "FinishTimestamp", bus_property_append_uint64, "t", &m->finish_timestamp.realtime },
{ "org.freedesktop.systemd1.Manager", "LogLevel", bus_manager_append_log_level, "s", NULL },
diff --git a/src/main.c b/src/main.c
index f7d76a2..cd73ee2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -871,12 +871,31 @@ fail:
return r;
}
+static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
+ const char *e;
+ unsigned long long a, b;
+
+ assert(t);
+
+ if (!(e = getenv("RD_TIMESTAMP")))
+ return NULL;
+
+ if (sscanf(e, "%llu %llu", &a, &b) != 2)
+ return NULL;
+
+ t->realtime = (usec_t) a;
+ t->monotonic = (usec_t) b;
+
+ return t;
+}
+
int main(int argc, char *argv[]) {
Manager *m = NULL;
int r, retval = EXIT_FAILURE;
FDSet *fds = NULL;
bool reexecute = false;
const char *shutdown_verb = NULL;
+ dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
/* This is compatbility support for SysV, where
@@ -965,9 +984,13 @@ int main(int argc, char *argv[]) {
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
arg_running_as == MANAGER_SYSTEM);
- /* Unset some environment variables passed in from the kernel
- * that don't really make sense for us. */
if (arg_running_as == MANAGER_SYSTEM) {
+ /* Parse the data passed to us by the initrd and unset it */
+ parse_initrd_timestamp(&initrd_timestamp);
+ filter_environ("RD_");
+
+ /* Unset some environment variables passed in from the
+ * kernel that don't really make sense for us. */
unsetenv("HOME");
unsetenv("TERM");
}
@@ -1030,6 +1053,9 @@ int main(int argc, char *argv[]) {
m->mount_auto = arg_mount_auto;
m->swap_auto = arg_swap_auto;
+ if (dual_timestamp_is_set(&initrd_timestamp))
+ m->initrd_timestamp = initrd_timestamp;
+
if (arg_console)
manager_set_console(m, arg_console);
diff --git a/src/manager.c b/src/manager.c
index c7de1ea..d690a0f 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -2501,6 +2501,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
assert(f);
assert(fds);
+ dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp);
dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
@@ -2555,7 +2556,9 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
if (l[0] == 0)
break;
- if (startswith(l, "startup-timestamp="))
+ if (startswith(l, "initrd-timestamp="))
+ dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
+ else if (startswith(l, "startup-timestamp="))
dual_timestamp_deserialize(l+18, &m->startup_timestamp);
else if (startswith(l, "finish-timestamp="))
dual_timestamp_deserialize(l+17, &m->finish_timestamp);
@@ -2715,7 +2718,7 @@ bool manager_unit_pending_inactive(Manager *m, const char *name) {
}
void manager_check_finished(Manager *m) {
- char userspace[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
+ char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
assert(m);
@@ -2727,15 +2730,26 @@ void manager_check_finished(Manager *m) {
dual_timestamp_get(&m->finish_timestamp);
- if (m->running_as == MANAGER_SYSTEM)
- log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
- format_timespan(kernel, sizeof(kernel),
- m->startup_timestamp.monotonic),
- format_timespan(userspace, sizeof(userspace),
- m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
- format_timespan(sum, sizeof(sum),
- m->finish_timestamp.monotonic));
- else
+ if (m->running_as == MANAGER_SYSTEM) {
+ if (dual_timestamp_is_set(&m->initrd_timestamp)) {
+ log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
+ format_timespan(kernel, sizeof(kernel),
+ m->initrd_timestamp.monotonic),
+ format_timespan(initrd, sizeof(initrd),
+ m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic),
+ format_timespan(userspace, sizeof(userspace),
+ m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
+ format_timespan(sum, sizeof(sum),
+ m->finish_timestamp.monotonic));
+ } else
+ log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
+ format_timespan(kernel, sizeof(kernel),
+ m->startup_timestamp.monotonic),
+ format_timespan(userspace, sizeof(userspace),
+ m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
+ format_timespan(sum, sizeof(sum),
+ m->finish_timestamp.monotonic));
+ } else
log_debug("Startup finished in %s.",
format_timespan(userspace, sizeof(userspace),
m->finish_timestamp.monotonic - m->startup_timestamp.monotonic));
diff --git a/src/manager.h b/src/manager.h
index 8a64750..ab7f263 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -143,6 +143,7 @@ struct Manager {
char **environment;
+ dual_timestamp initrd_timestamp;
dual_timestamp startup_timestamp;
dual_timestamp finish_timestamp;
diff --git a/src/timestamp.c b/src/timestamp.c
new file mode 100644
index 0000000..ce51429
--- /dev/null
+++ b/src/timestamp.c
@@ -0,0 +1,39 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+
+#include "util.h"
+
+int main(int argc, char *argv[]) {
+ struct dual_timestamp t;
+
+ /* This is mostly useful for stuff like init ram disk scripts
+ * which want to take a proper timestamp to do minimal bootup
+ * profiling. */
+
+ dual_timestamp_get(&t);
+ printf("%llu %llu\n",
+ (unsigned long long) t.realtime,
+ (unsigned long long) t.monotonic);
+
+ return 0;
+}
diff --git a/src/util.c b/src/util.c
index 6f9399b..f41861b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -3566,7 +3566,6 @@ void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
}
}
-
char *fstab_node_to_udev_node(const char *p) {
char *dn, *t, *u;
int r;
@@ -3617,6 +3616,24 @@ char *fstab_node_to_udev_node(const char *p) {
return strdup(p);
}
+void filter_environ(const char *prefix) {
+ int i, j;
+ assert(prefix);
+
+ if (!environ)
+ return;
+
+ for (i = 0, j = 0; environ[i]; i++) {
+
+ if (startswith(environ[i], prefix))
+ continue;
+
+ environ[j++] = environ[i];
+ }
+
+ environ[j] = NULL;
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
diff --git a/src/util.h b/src/util.h
index b7ef51e..5567da8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -372,6 +372,8 @@ void dual_timestamp_deserialize(const char *value, dual_timestamp *t);
char *fstab_node_to_udev_node(const char *p);
+void filter_environ(const char *prefix);
+
#define NULSTR_FOREACH(i, l) \
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
commit 70ca520f43d8cd3f9c6895d20ec87498b626bd75
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Nov 7 23:03:42 2010 -0500
modules-load: fix minor race
diff --git a/src/modules-load.c b/src/modules-load.c
index a1738bb..3e3ccb0 100644
--- a/src/modules-load.c
+++ b/src/modules-load.c
@@ -101,6 +101,9 @@ int main(int argc, char *argv[]) {
free(fn);
if (!f) {
+ if (errno == ENOENT)
+ continue;
+
log_error("Failed to open %s: %m", fn);
r = EXIT_FAILURE;
continue;
commit dce8e2e12304946a13c261b2324ce1e14ed9f5cd
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Nov 7 23:03:19 2010 -0500
label: use internal utility functions wher epossible
diff --git a/src/label.c b/src/label.c
index d037c4c..218d0df 100644
--- a/src/label.c
+++ b/src/label.c
@@ -258,20 +258,15 @@ int label_mkdir(
if (use_selinux() && label_hnd) {
- if (path[0] == '/')
+ if (path_is_absolute(path))
r = selabel_lookup_raw(label_hnd, &fcon, path, mode);
else {
- char *cwd = NULL, *newpath = NULL;
+ char *newpath = NULL;
- cwd = get_current_dir_name();
-
- if (cwd || asprintf(&newpath, "%s/%s", cwd, path) < 0) {
- free(cwd);
- return -errno;
- }
+ if (!(newpath = path_make_absolute_cwd(path)))
+ return -ENOMEM;
r = selabel_lookup_raw(label_hnd, &fcon, newpath, mode);
- free(cwd);
free(newpath);
}
commit e23a0ce8badd09aefa961a3a576bfe85f6ebbad7
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Nov 7 23:02:45 2010 -0500
cryptsetup: minimal cryptsetup unit generator
diff --git a/.gitignore b/.gitignore
index 2a30fab..4223788 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+systemd-cryptsetup
+systemd-cryptsetup-generator
systemd-tty-ask-password-agent
systemd-fsck
systemd-quotacheck
diff --git a/Makefile.am b/Makefile.am
index 456553f..3371c59 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -57,6 +57,7 @@ AM_CPPFLAGS = \
-DRUNTIME_DIR=\"$(localstatedir)/run\" \
-DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \
-DKEXEC_BINARY_PATH=\"/sbin/kexec\" \
+ -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \
-I $(top_srcdir)/src
if TARGET_GENTOO
@@ -112,7 +113,9 @@ rootlibexec_PROGRAMS = \
systemd-tmpfiles \
systemd-user-sessions \
systemd-fsck \
- systemd-quotacheck
+ systemd-quotacheck \
+ systemd-cryptsetup \
+ systemd-cryptsetup-generator
noinst_PROGRAMS = \
test-engine \
@@ -711,6 +714,25 @@ systemd_quotacheck_CFLAGS = \
systemd_quotacheck_LDADD = \
libsystemd-basic.la
+systemd_cryptsetup_SOURCES = \
+ src/cryptsetup.c
+
+systemd_cryptsetup_CFLAGS = \
+ $(AM_CFLAGS)
+
+systemd_cryptsetup_LDADD = \
+ libsystemd-basic.la
+
+systemd_cryptsetup_generator_SOURCES = \
+ src/cryptsetup-generator.c \
+ src/unit-name.c
+
+systemd_cryptsetup_generator_CFLAGS = \
+ $(AM_CFLAGS)
+
+systemd_cryptsetup_generator_LDADD = \
+ libsystemd-basic.la
+
systemd_user_sessions_SOURCES = \
src/user-sessions.c \
src/cgroup-util.c
diff --git a/src/cryptsetup-generator.c b/src/cryptsetup-generator.c
new file mode 100644
index 0000000..792c1f5
--- /dev/null
+++ b/src/cryptsetup-generator.c
@@ -0,0 +1,239 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+#include "unit-name.h"
+
+const char *arg_dest = "/tmp";
+
+static bool has_option(const char *haystack, const char *needle) {
+ const char *f = haystack;
+ size_t l;
+
+ l = strlen(needle);
+
+ while ((f = strstr(f, needle))) {
+
+ if (f > haystack && f[-1] != ',') {
+ f++;
+ continue;
+ }
+
+ if (f[l] != 0 && f[l] == ',') {
+ f++;
+ continue;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+static int create_disk(
+ const char *name,
+ const char *device,
+ const char *password,
+ const char *options) {
+
+ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL;
+ int r;
+ FILE *f = NULL;
+
+ assert(name);
+ assert(device);
+
+ if (!(n = unit_name_build_escape("cryptsetup", name, ".service"))) {
+ r = -ENOMEM;
+ log_error("Failed to allocate unit name.");
+ goto fail;
+ }
+
+ if (asprintf(&p, "%s/%s", arg_dest, n) < 0) {
+ r = -ENOMEM;
+ log_error("Failed to allocate unit file name.");
+ goto fail;
+ }
+
+ if (!(u = fstab_node_to_udev_node(device))) {
+ r = -ENOMEM;
+ log_error("Failed to allocate device node.");
+ goto fail;
+ }
+
+ if (!(d = unit_name_from_path(u, ".device"))) {
+ r = -ENOMEM;
+ log_error("Failed to allocate device name.");
+ goto fail;
+ }
+
+ if (!(f = fopen(p, "wxe"))) {
+ r = -errno;
+ log_error("Failed to create unit file: %m");
+ goto fail;
+ }
+
+ fprintf(f,
+ "[Unit]\n"
+ "Description=Cryptography Setup for %%f\n"
+ "DefaultDependencies=no\n"
+ "BindTo=%s\n"
+ "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n"
+ "Before=dev-mapper-%%f.device shutdown.target\n",
+ d, d);
+
+ if (password && (streq(password, "/dev/urandom") ||
+ streq(password, "/dev/random") ||
+ streq(password, "/dev/hw_random")))
+ fprintf(f,
+ "After=systemd-random-seed-load.service\n");
+
+ fprintf(f,
+ "\n[Service]\n"
+ "Type=oneshot\n"
+ "RemainAfterExit=yes\n"
+ "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " %s '%s' '%s' '%s' '%s'\n"
+ "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " remove '%s'\n",
+ options && has_option(options, "swap") ? "format" : "create",
+ name, u, strempty(password), strempty(options),
+ name);
+
+ if (options && has_option(options, "tmp"))
+ fprintf(f,
+ "ExecStartPost=/sbin/mke2fs '%s'",
+ u);
+
+ if (options && has_option(options, "swap"))
+ fprintf(f,
+ "ExecStartPost=/sbin/mkswap '%s'",
+ u);
+
+ fflush(f);
+
+ if (ferror(f)) {
+ r = -errno;
+ log_error("Failed to write file: %m");
+ goto fail;
+ }
+
+ if (!options || !has_option(options, "noauto")) {
+
+ if (asprintf(&to, "%s/%s.wants/%s", arg_dest, d, n) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ if (asprintf(&from, "../%s", n) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ mkdir_parents(to, 0755);
+
+ if (symlink(from, to) < 0) {
+ log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+ r = -errno;
+ goto fail;
+ }
+ }
+
+ r = 0;
+
+fail:
+ free(p);
+ free(n);
+ free(d);
+
+ free(from);
+ free(to);
+
+ if (f)
+ fclose(f);
+
+ return r;
+}
+
+int main(int argc, char *argv[]) {
+ FILE *f;
+ int r = EXIT_SUCCESS;
+ unsigned n = 0;
+
+ if (argc > 2) {
+ log_error("This program takes one or no arguments.");
+ return EXIT_FAILURE;
+ }
+
+ arg_dest = argv[1];
+
+ log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
+ log_parse_environment();
+ log_open();
+
+ if (!(f = fopen("/etc/crypttab", "re"))) {
+
+ if (errno == ENOENT)
+ r = EXIT_SUCCESS;
+ else {
+ r = EXIT_FAILURE;
+ log_error("Failed to open /etc/crypttab: %m");
+ }
+
+ goto finish;
+ }
+
+ for (;;) {
+ char line[LINE_MAX], *l;
+ char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
+ int k;
+
+ if (!(fgets(line, sizeof(line), f)))
+ break;
+
+ n++;
+
+ l = strstrip(line);
+ if (*l == '#' || *l == 0)
+ continue;
+
+ if ((k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options)) < 2 || k > 4) {
+ log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
+ r = EXIT_FAILURE;
+ goto next;
+ }
+
+ if (create_disk(name, device, password, options) < 0)
+ r = EXIT_FAILURE;
+
+ next:
+ free(name);
+ free(device);
+ free(password);
+ free(options);
+ }
+
+finish:
+ return r;
+}
diff --git a/src/cryptsetup.c b/src/cryptsetup.c
new file mode 100644
index 0000000..2231247
--- /dev/null
+++ b/src/cryptsetup.c
@@ -0,0 +1,53 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "log.h"
+#include "util.h"
+
+int main(int argc, char *argv[]) {
+ int r = EXIT_SUCCESS;
+
+ if (argc < 3) {
+ log_error("This program requires at least two arguments.");
+ return EXIT_FAILURE;
+ }
+
+ log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
+ log_parse_environment();
+ log_open();
+
+ if (streq(argv[1], "create")) {
+
+ } else if (streq(argv[1], "format")) {
+
+
+ } else if (streq(argv[1], "remove")) {
+
+ } else {
+ log_error("Unknown verb %s.", argv[1]);
+ goto finish;
+ }
+
+finish:
+ return r;
+}
diff --git a/src/mount.c b/src/mount.c
index 781c7a8..5d4944a 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -1297,56 +1297,6 @@ fail:
return r;
}
-static char *fstab_node_to_udev_node(char *p) {
- char *dn, *t, *u;
- int r;
-
- /* FIXME: to follow udev's logic 100% we need to leave valid
- * UTF8 chars unescaped */
-
- if (startswith(p, "LABEL=")) {
-
- if (!(u = unquote(p+6, "\"\'")))
- return NULL;
-
- t = xescape(u, "/ ");
- free(u);
-
- if (!t)
- return NULL;
-
- r = asprintf(&dn, "/dev/disk/by-label/%s", t);
- free(t);
-
- if (r < 0)
- return NULL;
-
- return dn;
- }
-
- if (startswith(p, "UUID=")) {
-
- if (!(u = unquote(p+5, "\"\'")))
- return NULL;
-
- t = xescape(u, "/ ");
- free(u);
-
- if (!t)
- return NULL;
-
- r = asprintf(&dn, "/dev/disk/by-uuid/%s", ascii_strlower(t));
- free(t);
-
- if (r < 0)
- return NULL;
-
- return dn;
- }
-
- return strdup(p);
-}
-
static int mount_find_pri(char *options) {
char *end, *pri;
unsigned long r;
diff --git a/src/util.c b/src/util.c
index fecdee1..6f9399b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -3566,6 +3566,57 @@ void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
}
}
+
+char *fstab_node_to_udev_node(const char *p) {
+ char *dn, *t, *u;
+ int r;
+
+ /* FIXME: to follow udev's logic 100% we need to leave valid
+ * UTF8 chars unescaped */
+
+ if (startswith(p, "LABEL=")) {
+
+ if (!(u = unquote(p+6, "\"\'")))
+ return NULL;
+
+ t = xescape(u, "/ ");
+ free(u);
+
+ if (!t)
+ return NULL;
+
+ r = asprintf(&dn, "/dev/disk/by-label/%s", t);
+ free(t);
+
+ if (r < 0)
+ return NULL;
+
+ return dn;
+ }
+
+ if (startswith(p, "UUID=")) {
+
+ if (!(u = unquote(p+5, "\"\'")))
+ return NULL;
+
+ t = xescape(u, "/ ");
+ free(u);
+
+ if (!t)
+ return NULL;
+
+ r = asprintf(&dn, "/dev/disk/by-uuid/%s", ascii_strlower(t));
+ free(t);
+
+ if (r < 0)
+ return NULL;
+
+ return dn;
+ }
+
+ return strdup(p);
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
diff --git a/src/util.h b/src/util.h
index b469009..b7ef51e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -370,7 +370,9 @@ int ask_password_tty(const char *message, usec_t until, const char *flag_file, c
void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t);
void dual_timestamp_deserialize(const char *value, dual_timestamp *t);
-#define NULSTR_FOREACH(i, l) \
+char *fstab_node_to_udev_node(const char *p);
+
+#define NULSTR_FOREACH(i, l) \
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
#define NULSTR_FOREACH_PAIR(i, j, l) \
commit 1829dc9dc5f38cd1aaa43912de56c3bb5d8b5617
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Nov 7 22:59:39 2010 -0500
selinux: relabel /dev after loading policy
diff --git a/src/mount-setup.c b/src/mount-setup.c
index fe99f58..84a729e 100644
--- a/src/mount-setup.c
+++ b/src/mount-setup.c
@@ -27,6 +27,7 @@
#include <libgen.h>
#include <assert.h>
#include <unistd.h>
+#include <ftw.h>
#include "mount-setup.h"
#include "log.h"
@@ -189,6 +190,16 @@ static int symlink_and_label(const char *old_path, const char *new_path) {
return r;
}
+static int nftw_cb(
+ const char *fpath,
+ const struct stat *sb,
+ int tflag,
+ struct FTW *ftwbuf) {
+
+ label_fix(fpath);
+ return 0;
+};
+
int mount_setup(void) {
const char *symlinks =
@@ -207,6 +218,13 @@ int mount_setup(void) {
if ((r = mount_one(mount_table+i)) < 0)
return r;
+ /* Nodes in devtmpfs need to be manually updated for the
+ * appropriate labels, after mounting. The other virtual API
+ * file systems do not need. */
+
+ if (unlink("/dev/.systemd/relabel-devtmpfs") >= 0)
+ nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS);
+
/* Create a few default symlinks, which are normally created
* bei udevd, but some scripts might need them before we start
* udevd. */
diff --git a/src/selinux-setup.c b/src/selinux-setup.c
index d4da693..b2beb33 100644
--- a/src/selinux-setup.c
+++ b/src/selinux-setup.c
@@ -42,8 +42,14 @@ int selinux_setup(char *const argv[]) {
if (path_is_mount_point("/selinux") > 0)
return 0;
+ /* Before we load the policy we create a flag file to ensure
+ * that after the reexec we iterate through /dev to relabel
+ * things. */
+ mkdir_p("/dev/.systemd", 0755);
+ touch("/dev/.systemd/relabel-devtmpfs");
+
if (selinux_init_load_policy(&enforce) == 0) {
- log_info("Successfully loaded SELinux policy, reexecuting.");
+ log_debug("Successfully loaded SELinux policy, reexecuting.");
/* FIXME: Ideally we'd just call setcon() here instead
* of having to reexecute ourselves here. */
@@ -55,6 +61,8 @@ int selinux_setup(char *const argv[]) {
} else {
log_full(enforce > 0 ? LOG_ERR : LOG_DEBUG, "Failed to load SELinux policy.");
+ unlink("/dev/.systemd/relabel-devtmpfs");
+
if (enforce > 0)
return -EIO;
}
commit 31a7034d38fd7550699e6fbd002bbe42d9ea3b7e
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Nov 7 22:43:17 2010 -0500
log: downgrade syslog connection failure message since it might happen during normal operation
diff --git a/src/log.c b/src/log.c
index 575ed51..cc636a2 100644
--- a/src/log.c
+++ b/src/log.c
@@ -96,7 +96,7 @@ static int log_open_kmsg(void) {
return 0;
if ((kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) {
- log_info("Failed to open /dev/kmsg for logging: %s", strerror(errno));
+ log_error("Failed to open /dev/kmsg for logging: %s", strerror(errno));
return -errno;
}
@@ -177,7 +177,7 @@ static int log_open_syslog(void) {
fail:
log_close_syslog();
- log_info("Failed to open syslog for logging: %s", strerror(-r));
+ log_debug("Failed to open syslog for logging: %s", strerror(-r));
return r;
}
commit 2edfa36685588a5e224d1f86b3fcc16c46766fea
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 1 17:50:43 2010 +0100
service: delay automatic restart if job is pending
diff --git a/TODO b/TODO
index 8ae5fc5..a97ba9f 100644
--- a/TODO
+++ b/TODO
@@ -74,8 +74,6 @@
* we now order plymouth after udev-trigger. Can we optimize this?
-* disable respawn when we are going down anyway.
-
* drop tmp.mount
External:
diff --git a/src/service.c b/src/service.c
index d3c750e..0b54e5b 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2039,6 +2039,13 @@ static void service_enter_restart(Service *s) {
assert(s);
dbus_error_init(&error);
+ if (s->meta.job) {
+ log_info("Job pending for unit, delaying automatic restart.");
+
+ if ((r = unit_watch_timer(UNIT(s), s->restart_usec, &s->timer_watch)) < 0)
+ goto fail;
+ }
+
service_enter_dead(s, true, false);
if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT(s), JOB_FAIL, false, &error, NULL)) < 0)
commit 52da68821bb66871cf574989084c55b4d13d02b4
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 1 17:27:28 2010 +0100
update fixme
diff --git a/TODO b/TODO
index c968272..8ae5fc5 100644
--- a/TODO
+++ b/TODO
@@ -76,10 +76,6 @@
* disable respawn when we are going down anyway.
-* isolate doesn't kill pending jobs.
-
-* warum wird fsck-root und plymouth-start.service von bluetooth.target reingezogen?
-
* drop tmp.mount
External:
commit 2ce5c8f9ab32f11110e61208ba8671e48cf8ae6d
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 1 16:16:15 2010 +0100
manager: when isolating undo all pending jobs, too
diff --git a/src/manager.c b/src/manager.c
index afd29cf..c7de1ea 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -1528,7 +1528,7 @@ static int transaction_add_isolate_jobs(Manager *m) {
continue;
/* No need to stop inactive jobs */
- if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)))
+ if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)) && !u->meta.job)
continue;
/* Is there already something listed for this? */
commit 143072edeabe163377d45dedd252d173a56f6455
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 1 16:09:36 2010 +0100
manager: only minimize impact if we are in fail mode
diff --git a/TODO b/TODO
index fcdf1b5..c968272 100644
--- a/TODO
+++ b/TODO
@@ -74,6 +74,14 @@
* we now order plymouth after udev-trigger. Can we optimize this?
+* disable respawn when we are going down anyway.
+
+* isolate doesn't kill pending jobs.
+
+* warum wird fsck-root und plymouth-start.service von bluetooth.target reingezogen?
+
+* drop tmp.mount
+
External:
* patch kernel for xattr support in /dev, /proc/, /sys and /sys/fs/cgroup.
diff --git a/src/manager.c b/src/manager.c
index 9fa4877..afd29cf 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -1133,7 +1133,8 @@ static void transaction_minimize_impact(Manager *m) {
j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit));
changes_existing_job =
- j->unit->meta.job && job_type_is_conflicting(j->type, j->unit->meta.job->type);
+ j->unit->meta.job &&
+ job_type_is_conflicting(j->type, j->unit->meta.job->type);
if (!stops_running_service && !changes_existing_job)
continue;
@@ -1234,7 +1235,7 @@ static int transaction_activate(Manager *m, JobMode mode, DBusError *e) {
/* Second step: Try not to stop any running services if
* we don't have to. Don't try to reverse running
* jobs if we don't have to. */
- if (mode != JOB_ISOLATE)
+ if (mode == JOB_FAIL)
transaction_minimize_impact(m);
/* Third step: Drop redundant jobs */
More information about the systemd-commits
mailing list