[systemd-commits] 11 commits - fixme .gitignore Makefile.am man/daemon.xml man/telinit.xml src/auto-console-getty.c src/auto-serial-getty.c src/dbus-manager.c src/fdset.c src/kmsg-syslogd.c src/log.c src/logger.c src/main.c src/manager.h src/mount.c src/swap.c src/system.conf src/systemctl.c src/update-utmp.c src/util.c src/util.h units/emergency.service units/fedora units/getty at .service.m4 units/.gitignore units/serial-getty at .service.m4 units/systemd-auto-console-getty.service.in units/systemd-auto-serial-getty.service units/systemd-kmsg-syslogd.service.in units/systemd-kmsg-syslogd.socket
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Aug 24 18:15:43 PDT 2010
.gitignore | 3
Makefile.am | 37 +
fixme | 32 +
man/daemon.xml | 2
man/telinit.xml | 4
src/auto-console-getty.c | 189 ---------
src/auto-serial-getty.c | 189 +++++++++
src/dbus-manager.c | 6
src/fdset.c | 2
src/kmsg-syslogd.c | 545 ++++++++++++++++++++++++++++
src/log.c | 22 -
src/logger.c | 7
src/main.c | 29 -
src/manager.h | 4
src/mount.c | 7
src/swap.c | 4
src/system.conf | 5
src/systemctl.c | 77 +++
src/update-utmp.c | 4
src/util.c | 57 ++
src/util.h | 4
units/.gitignore | 2
units/emergency.service | 2
units/fedora/prefdm.service | 2
units/fedora/single.service | 2
units/getty at .service.m4 | 2
units/serial-getty at .service.m4 | 37 +
units/systemd-auto-console-getty.service.in | 16
units/systemd-auto-serial-getty.service | 16
units/systemd-kmsg-syslogd.service.in | 16
units/systemd-kmsg-syslogd.socket | 20 +
31 files changed, 1063 insertions(+), 281 deletions(-)
New commits:
commit 1a7fdcad3ae37fae7789584d203eca97bf0a223a
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:15:32 2010 +0200
units: make sure prefdm is automatically respawned
diff --git a/units/fedora/prefdm.service b/units/fedora/prefdm.service
index 931b47f..22ee54d 100644
--- a/units/fedora/prefdm.service
+++ b/units/fedora/prefdm.service
@@ -15,6 +15,8 @@ Conflicts=getty at tty1.service plymouth-quit.service
[Service]
ExecStart=/etc/X11/prefdm -nodaemon
+Restart=restart-always
+RestartSec=0
[Install]
Alias=display-manager.service
commit ddad68097d307fd8cdfd06946691211fb65b74e3
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:15:12 2010 +0200
units: invoke sulogin instead of /bin/sh
diff --git a/units/emergency.service b/units/emergency.service
index dda7e16..4a1e31a 100644
--- a/units/emergency.service
+++ b/units/emergency.service
@@ -14,7 +14,7 @@ DefaultDependencies=no
[Service]
ExecStartPre=-/bin/plymouth --hide-splash
ExecStartPre=-/bin/echo 'Welcome to emergency mode. Use "systemctl default" to activate default mode.'
-ExecStart=/bin/sh
+ExecStart=-/sbin/sulogin
StandardInput=tty-force
Restart=restart-always
RestartSec=0
diff --git a/units/fedora/single.service b/units/fedora/single.service
index 75b8ecc..2eba886 100644
--- a/units/fedora/single.service
+++ b/units/fedora/single.service
@@ -17,7 +17,7 @@ Before=multi-user.target
[Service]
ExecStartPre=-/bin/plymouth --hide-splash
ExecStartPre=-/bin/echo 'Welcome to rescue mode. Use "systemctl default" to activate default mode.'
-ExecStart=/bin/sh
+ExecStart=-/sbin/sulogin
StandardInput=tty-force
Restart=restart-always
RestartSec=0
commit 3006982d93e92019dd6d94a7518684593b43a05e
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:14:53 2010 +0200
utmp: write out runlevels 5 and 3 preferrably if multiples make sense, and S instead of 1
diff --git a/src/update-utmp.c b/src/update-utmp.c
index 5a48bd9..3ec0a16 100644
--- a/src/update-utmp.c
+++ b/src/update-utmp.c
@@ -116,10 +116,10 @@ static int get_current_runlevel(Context *c) {
/* The first target of this list that is active or has
* a job scheduled wins */
{ '5', SPECIAL_RUNLEVEL5_TARGET },
- { '4', SPECIAL_RUNLEVEL4_TARGET },
{ '3', SPECIAL_RUNLEVEL3_TARGET },
+ { '4', SPECIAL_RUNLEVEL4_TARGET },
{ '2', SPECIAL_RUNLEVEL2_TARGET },
- { '1', SPECIAL_RESCUE_TARGET },
+ { 'S', SPECIAL_RESCUE_TARGET },
};
const char
*interface = "org.freedesktop.systemd1.Unit",
commit f3d41013e24a81b2c853393593d1d52c156826ec
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:14:04 2010 +0200
systemctl: rename a few status lines
diff --git a/src/systemctl.c b/src/systemctl.c
index 0c33abb..9da8303 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1613,7 +1613,7 @@ static void print_status_info(UnitStatusInfo *i) {
continue;
t = strv_join(p->argv, " ");
- printf("\t Exited: %u (%s, code=%s, ", p->pid, strna(t), sigchld_code_to_string(p->code));
+ printf("\t Process: %u (%s, code=%s, ", p->pid, strna(t), sigchld_code_to_string(p->code));
free(t);
if (p->code == CLD_EXITED) {
@@ -1642,7 +1642,7 @@ static void print_status_info(UnitStatusInfo *i) {
printf("\t");
if (i->main_pid > 0) {
- printf(" Main: %u", (unsigned) i->main_pid);
+ printf("Main PID: %u", (unsigned) i->main_pid);
if (i->running) {
char *t = NULL;
commit 584be568b99633eb48c21ece92e241de011ecc9a
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:13:44 2010 +0200
systemctl: show timestamps for state changes
diff --git a/src/systemctl.c b/src/systemctl.c
index f9317ad..0c33abb 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1489,6 +1489,11 @@ typedef struct UnitStatusInfo {
const char *path;
const char *default_control_group;
+ usec_t inactive_exit_timestamp;
+ usec_t active_enter_timestamp;
+ usec_t active_exit_timestamp;
+ usec_t inactive_enter_timestamp;
+
bool need_daemon_reload;
/* Service */
@@ -1523,6 +1528,9 @@ typedef struct UnitStatusInfo {
static void print_status_info(UnitStatusInfo *i) {
ExecStatusInfo *p;
const char *on, *off, *ss;
+ usec_t timestamp;
+ char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1;
+ char since2[FORMAT_TIMESTAMP_MAX], *s2;
assert(i);
@@ -1559,17 +1567,34 @@ static void print_status_info(UnitStatusInfo *i) {
on = off = "";
if (ss)
- printf("\t Active: %s%s (%s)%s\n",
+ printf("\t Active: %s%s (%s)%s",
on,
strna(i->active_state),
ss,
off);
else
- printf("\t Active: %s%s%s\n",
+ printf("\t Active: %s%s%s",
on,
strna(i->active_state),
off);
+ timestamp = (streq_ptr(i->active_state, "active") ||
+ streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
+ (streq_ptr(i->active_state, "inactive") ||
+ streq_ptr(i->active_state, "maintenance")) ? i->inactive_enter_timestamp :
+ streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
+ i->active_exit_timestamp;
+
+ s1 = format_timestamp_pretty(since1, sizeof(since1), timestamp);
+ s2 = format_timestamp(since2, sizeof(since2), timestamp);
+
+ if (s1)
+ printf(" since [%s; %s]\n", s2, s1);
+ else if (s2)
+ printf(" since [%s]\n", s2);
+ else
+ printf("\n");
+
if (i->sysfs_path)
printf("\t Device: %s\n", i->sysfs_path);
else if (i->where)
@@ -1782,6 +1807,14 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
i->start_timestamp = (usec_t) u;
else if (streq(name, "ExecMainExitTimestamp"))
i->exit_timestamp = (usec_t) u;
+ else if (streq(name, "ActiveEnterTimestamp"))
+ i->active_enter_timestamp = (usec_t) u;
+ else if (streq(name, "InactiveEnterTimestamp"))
+ i->inactive_enter_timestamp = (usec_t) u;
+ else if (streq(name, "InactiveExitTimestamp"))
+ i->inactive_exit_timestamp = (usec_t) u;
+ else if (streq(name, "ActiveExitTimestamp"))
+ i->active_exit_timestamp = (usec_t) u;
break;
}
diff --git a/src/util.c b/src/util.c
index f1a7bbd..a09b704 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1659,6 +1659,63 @@ char *format_timestamp(char *buf, size_t l, usec_t t) {
return buf;
}
+char *format_timestamp_pretty(char *buf, size_t l, usec_t t) {
+ usec_t n, d;
+
+ n = now(CLOCK_REALTIME);
+
+ if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
+ return NULL;
+
+ d = n - t;
+
+ if (d >= USEC_PER_YEAR)
+ snprintf(buf, l, "%llu years and %llu months ago",
+ (unsigned long long) (d / USEC_PER_YEAR),
+ (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
+ else if (d >= USEC_PER_MONTH)
+ snprintf(buf, l, "%llu months and %llu days ago",
+ (unsigned long long) (d / USEC_PER_MONTH),
+ (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
+ else if (d >= USEC_PER_WEEK)
+ snprintf(buf, l, "%llu weeks and %llu days ago",
+ (unsigned long long) (d / USEC_PER_WEEK),
+ (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
+ else if (d >= 2*USEC_PER_DAY)
+ snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
+ else if (d >= 25*USEC_PER_HOUR)
+ snprintf(buf, l, "1 day and %lluh ago",
+ (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
+ else if (d >= 6*USEC_PER_HOUR)
+ snprintf(buf, l, "%lluh ago",
+ (unsigned long long) (d / USEC_PER_HOUR));
+ else if (d >= USEC_PER_HOUR)
+ snprintf(buf, l, "%lluh %llumin ago",
+ (unsigned long long) (d / USEC_PER_HOUR),
+ (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
+ else if (d >= 5*USEC_PER_MINUTE)
+ snprintf(buf, l, "%llumin ago",
+ (unsigned long long) (d / USEC_PER_MINUTE));
+ else if (d >= USEC_PER_MINUTE)
+ snprintf(buf, l, "%llumin %llus ago",
+ (unsigned long long) (d / USEC_PER_MINUTE),
+ (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
+ else if (d >= USEC_PER_SEC)
+ snprintf(buf, l, "%llus ago",
+ (unsigned long long) (d / USEC_PER_SEC));
+ else if (d >= USEC_PER_MSEC)
+ snprintf(buf, l, "%llums ago",
+ (unsigned long long) (d / USEC_PER_MSEC));
+ else if (d > 0)
+ snprintf(buf, l, "%lluus ago",
+ (unsigned long long) d);
+ else
+ snprintf(buf, l, "now");
+
+ buf[l-1] = 0;
+ return buf;
+}
+
char *format_timespan(char *buf, size_t l, usec_t t) {
static const struct {
const char *suffix;
diff --git a/src/util.h b/src/util.h
index 4063ee7..3a7ac29 100644
--- a/src/util.h
+++ b/src/util.h
@@ -52,12 +52,15 @@ typedef struct dual_timestamp {
#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE)
#define USEC_PER_DAY (24ULL*USEC_PER_HOUR)
#define USEC_PER_WEEK (7ULL*USEC_PER_DAY)
+#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC)
+#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC)
/* What is interpreted as whitespace? */
#define WHITESPACE " \t\n\r"
#define NEWLINE "\n\r"
#define FORMAT_TIMESTAMP_MAX 64
+#define FORMAT_TIMESTAMP_PRETTY_MAX 256
#define FORMAT_TIMESPAN_MAX 64
#define ANSI_HIGHLIGHT_ON "\x1B[1;31m"
@@ -248,6 +251,7 @@ bool ignore_file(const char *filename);
bool chars_intersect(const char *a, const char *b);
char *format_timestamp(char *buf, size_t l, usec_t t);
+char *format_timestamp_pretty(char *buf, size_t l, usec_t t);
char *format_timespan(char *buf, size_t l, usec_t t);
int make_stdio(int fd);
commit f1e36d677ac771408e40c34ead368a7fdbcc0622
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:13:09 2010 +0200
systemctl: add --sysv-compat
diff --git a/src/systemctl.c b/src/systemctl.c
index 30f6b2a..f9317ad 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -69,6 +69,11 @@ static bool arg_quiet = false;
static bool arg_full = false;
static bool arg_force = false;
static bool arg_defaults = false;
+static bool arg_sysv_compat = false; /* this is undocumented, and
+ * exists simply to make
+ * implementation of SysV
+ * compatible shell glue
+ * easier */
static char **arg_wall = NULL;
static usec_t arg_when = 0;
static enum action {
@@ -1359,7 +1364,7 @@ static int check_unit(DBusConnection *bus, char **args, unsigned n) {
if (!arg_quiet)
puts(state);
- if (streq(state, "active") || startswith(state, "reloading"))
+ if (streq(state, "active") || streq(state, "reloading"))
r = 0;
dbus_message_unref(m);
@@ -2150,16 +2155,27 @@ static int show_one(DBusConnection *bus, const char *path, bool show_properties,
dbus_message_iter_next(&sub);
}
- if (!show_properties)
- print_status_info(&info);
+ r = 0;
+
+ if (!show_properties) {
+ if (arg_sysv_compat &&
+ !streq_ptr(info.active_state, "active") &&
+ !streq_ptr(info.active_state, "reloading")) {
+
+ /* If the SysV compatibility mode is on, we
+ * will refuse to run "status" on units that
+ * aren't active */
+ log_error("Unit not active.");
+ r = -EADDRNOTAVAIL;
+ } else
+ print_status_info(&info);
+ }
while ((p = info.exec)) {
LIST_REMOVE(ExecStatusInfo, exec, info.exec, p);
exec_status_info_free(p);
}
- r = 0;
-
finish:
if (m)
dbus_message_unref(m);
@@ -3895,7 +3911,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
ARG_FULL,
ARG_FORCE,
ARG_NO_RELOAD,
- ARG_DEFAULTS
+ ARG_DEFAULTS,
+ ARG_SYSV_COMPAT
};
static const struct option options[] = {
@@ -3915,7 +3932,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "require", no_argument, NULL, ARG_REQUIRE },
{ "force", no_argument, NULL, ARG_FORCE },
{ "no-reload", no_argument, NULL, ARG_NO_RELOAD },
- { "defaults", no_argument, NULL, ARG_DEFAULTS },
+ { "defaults", no_argument, NULL, ARG_DEFAULTS },
+ { "sysv-compat", no_argument, NULL, ARG_SYSV_COMPAT },
{ NULL, 0, NULL, 0 }
};
@@ -4009,6 +4027,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_defaults = true;
break;
+ case ARG_SYSV_COMPAT:
+ arg_sysv_compat = true;
+ break;
+
case '?':
return -EINVAL;
commit 44bcea66542e398fcada22ba9cb24d07bd8e04ef
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:12:19 2010 +0200
log: SCM_CREDENTIALS will be added by the kernel anyway, so there's no need to write them manually
diff --git a/src/log.c b/src/log.c
index 3c42e8e..21fc9f4 100644
--- a/src/log.c
+++ b/src/log.c
@@ -248,11 +248,6 @@ static int write_to_syslog(
char header_priority[16], header_time[64], header_pid[16];
struct iovec iovec[5];
struct msghdr msghdr;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
- } control;
- struct ucred *ucred;
time_t t;
struct tm *tm;
@@ -279,21 +274,9 @@ static int write_to_syslog(
IOVEC_SET_STRING(iovec[3], header_pid);
IOVEC_SET_STRING(iovec[4], buffer);
- zero(control);
- control.cmsghdr.cmsg_level = SOL_SOCKET;
- control.cmsghdr.cmsg_type = SCM_CREDENTIALS;
- control.cmsghdr.cmsg_len = CMSG_LEN(sizeof(struct ucred));
-
- ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
- ucred->pid = getpid();
- ucred->uid = getuid();
- ucred->gid = getgid();
-
zero(msghdr);
msghdr.msg_iov = iovec;
msghdr.msg_iovlen = ELEMENTSOF(iovec);
- msghdr.msg_control = &control;
- msghdr.msg_controllen = control.cmsghdr.cmsg_len;
if (sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL) < 0)
return -errno;
commit d3689161a2870a56ba5a2837daa2ca3463e24710
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:11:26 2010 +0200
mount: add global configuration options for handling of auto mounts
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index eb37684..5571247 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -141,6 +141,9 @@
" <property name=\"SysVRcndPath\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"NotifySocket\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ControlGroupHierarchy\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"MountOnPlug\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"SwapOnPlug\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"MountAuto\" type=\"b\" access=\"read\"/>\n" \
" </interface>\n"
#define INTROSPECTION_BEGIN \
@@ -252,6 +255,9 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
{ "org.freedesktop.systemd1.Manager", "SysVRcndPath", bus_property_append_strv, "as", m->lookup_paths.sysvrcnd_path },
{ "org.freedesktop.systemd1.Manager", "NotifySocket", bus_property_append_string, "s", m->notify_socket },
{ "org.freedesktop.systemd1.Manager", "ControlGroupHierarchy", bus_property_append_string, "s", m->cgroup_hierarchy },
+ { "org.freedesktop.systemd1.Manager", "MountOnPlug", bus_property_append_bool, "b", &m->mount_on_plug },
+ { "org.freedesktop.systemd1.Manager", "SwapOnPlug", bus_property_append_bool, "b", &m->swap_on_plug },
+ { "org.freedesktop.systemd1.Manager", "MountAuto", bus_property_append_bool, "b", &m->mount_auto },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/src/main.c b/src/main.c
index 35ee1c7..54fc054 100644
--- a/src/main.c
+++ b/src/main.c
@@ -64,6 +64,9 @@ static int arg_crash_chvt = -1;
static bool arg_confirm_spawn = false;
static bool arg_show_status = true;
static bool arg_sysv_console = true;
+static bool arg_mount_on_plug = true;
+static bool arg_swap_on_plug = true;
+static bool arg_mount_auto = true;
static FILE* serialization = NULL;
@@ -472,16 +475,19 @@ static int config_parse_cpu_affinity(
static int parse_config_file(void) {
const ConfigItem items[] = {
- { "LogLevel", config_parse_level, NULL, "Manager" },
- { "LogTarget", config_parse_target, NULL, "Manager" },
- { "LogColor", config_parse_color, NULL, "Manager" },
- { "LogLocation", config_parse_location, NULL, "Manager" },
- { "DumpCore", config_parse_bool, &arg_dump_core, "Manager" },
- { "CrashShell", config_parse_bool, &arg_crash_shell, "Manager" },
- { "ShowStatus", config_parse_bool, &arg_show_status, "Manager" },
- { "SysVConsole", config_parse_bool, &arg_sysv_console,"Manager" },
- { "CrashChVT", config_parse_int, &arg_crash_chvt, "Manager" },
- { "CPUAffinity", config_parse_cpu_affinity, NULL, "Manager" },
+ { "LogLevel", config_parse_level, NULL, "Manager" },
+ { "LogTarget", config_parse_target, NULL, "Manager" },
+ { "LogColor", config_parse_color, NULL, "Manager" },
+ { "LogLocation", config_parse_location, NULL, "Manager" },
+ { "DumpCore", config_parse_bool, &arg_dump_core, "Manager" },
+ { "CrashShell", config_parse_bool, &arg_crash_shell, "Manager" },
+ { "ShowStatus", config_parse_bool, &arg_show_status, "Manager" },
+ { "SysVConsole", config_parse_bool, &arg_sysv_console, "Manager" },
+ { "CrashChVT", config_parse_int, &arg_crash_chvt, "Manager" },
+ { "CPUAffinity", config_parse_cpu_affinity, NULL, "Manager" },
+ { "MountOnPlug", config_parse_bool, &arg_mount_on_plug, "Manager" },
+ { "SwapOnPlug", config_parse_bool, &arg_swap_on_plug, "Manager" },
+ { "MountAuto", config_parse_bool, &arg_mount_auto, "Manager" },
{ NULL, NULL, NULL, NULL }
};
@@ -986,6 +992,9 @@ int main(int argc, char *argv[]) {
m->confirm_spawn = arg_confirm_spawn;
m->show_status = arg_show_status;
m->sysv_console = arg_sysv_console;
+ m->mount_on_plug = arg_mount_on_plug;
+ m->swap_on_plug = arg_swap_on_plug;
+ m->mount_auto = arg_mount_auto;
if ((r = manager_startup(m, serialization, fds)) < 0)
log_error("Failed to fully start up daemon: %s", strerror(-r));
diff --git a/src/manager.h b/src/manager.h
index 2b4eee9..dd48593 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -202,6 +202,10 @@ struct Manager {
bool confirm_spawn;
bool sysv_console;
+ bool mount_on_plug;
+ bool swap_on_plug;
+ bool mount_auto;
+
int n_deserializing;
};
diff --git a/src/mount.c b/src/mount.c
index b667ae5..b49443c 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -244,7 +244,8 @@ static int mount_add_target_links(Mount *m) {
noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO);
user = mount_test_option(p->options, "user") || mount_test_option(p->options, "users");
- handle = !!mount_test_option(p->options, "comment=systemd.mount");
+ handle = !!mount_test_option(p->options, "comment=systemd.mount") ||
+ m->meta.manager->mount_auto;
automount = !!mount_test_option(p->options, "comment=systemd.automount");
if (mount_test_option(p->options, "_netdev") ||
@@ -362,7 +363,9 @@ static int mount_load(Unit *u) {
what = m->parameters_proc_self_mountinfo.what;
if (what && !path_equal(m->where, "/"))
- if ((r = unit_add_node_link(u, what, u->meta.manager->running_as == MANAGER_SYSTEM)) < 0)
+ if ((r = unit_add_node_link(u, what,
+ u->meta.manager->running_as == MANAGER_SYSTEM &&
+ u->meta.manager->mount_on_plug)) < 0)
return r;
if ((r = mount_add_mount_links(m)) < 0)
diff --git a/src/swap.c b/src/swap.c
index c81fd67..4a672fb 100644
--- a/src/swap.c
+++ b/src/swap.c
@@ -195,7 +195,9 @@ static int swap_load(Unit *u) {
if ((r = unit_set_description(u, s->what)) < 0)
return r;
- if ((r = unit_add_node_link(u, s->what, u->meta.manager->running_as == MANAGER_SYSTEM)) < 0)
+ if ((r = unit_add_node_link(u, s->what,
+ u->meta.manager->running_as == MANAGER_SYSTEM &&
+ u->meta.manager->swap_on_plug)) < 0)
return r;
if ((r = swap_add_mount_links(s)) < 0)
diff --git a/src/system.conf b/src/system.conf
index 11885e0..9d87c6d 100644
--- a/src/system.conf
+++ b/src/system.conf
@@ -5,7 +5,7 @@
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
-# See system.conf(5) for details
+# See systemd(1) for details
[Manager]
#LogLevel=info
@@ -18,3 +18,6 @@
#SysVConsole=yes
#CrashChVT=1
#CPUAffinity=1 2
+#MountOnPlug=yes
+#SwapOnPlug=yes
+#MountAuto=yes
commit 20604ebc04ce5d3b7d7d63e79f94cf0febf851c5
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:10:13 2010 +0200
man: minor updates
diff --git a/fixme b/fixme
index 2aa4dc6..56efcaf 100644
--- a/fixme
+++ b/fixme
@@ -58,24 +58,42 @@
* bash completion a la gdbus
-* use sulogin
-
* [Install] section rausmachen für early boot krams, uznd per default nach /lib linken
-* s/Exited/Process/ in systemctl status
+* systemctl list-jobs deps anzeigen
-* systemctl status: "active since 5min"
+* ConditionFileExists=, ConditionKernelCommandLine=, ConditionEnvironment= mit !
-* systemctl list-jobs deps anzeigen
+* oom_score_adj
-* /etc/systemd/system.conf: mounten per default option
+* accountsservice is dod
-* ConditionFileExists=, ConditionKernelCommandLine=, ConditionEnvironment= mit !
+* follow LSB exit codes spec in "systemctl start"
+
+* auditd service files
+
+* override the human readable dbus error code for permission denied.
+
+* discuss reexec on shutdown, async. vs. sync?
+
+* auto-serial-getty vs. isolate
+
+* add RefuseManualIsolate= (default on?)
+
+* add systemctl switch to dump transaction without executing it
+
+* shell wenn fsck im arsch is
+
+* system.conf/session.conf brauch ne man page
External:
+* make sure MountOnPlug und MountAuto und SwapOnPlug is off in Fedora
+
* place /etc/inittab with explaining blurb.
+* pam_securetty should honour console=
+
* procps, psmisc, sysvinit-tools, hostname â util-linux-ng
* nologin nach /var/run https://bugzilla.redhat.com/show_bug.cgi?id=624489
diff --git a/man/daemon.xml b/man/daemon.xml
index b8e9df4..fdc6a64 100644
--- a/man/daemon.xml
+++ b/man/daemon.xml
@@ -449,7 +449,7 @@
activation of daemons. However, the primary
advantage of this scheme is that all providers
and all consumers of the sockets can be
- started in parallel as soon als all sockets
+ started in parallel as soon as all sockets
are established. In addition to that daemons
can be restarted with losing only a minimal
number of client transactions or even any
diff --git a/man/telinit.xml b/man/telinit.xml
index bbf43bf..fec059a 100644
--- a/man/telinit.xml
+++ b/man/telinit.xml
@@ -124,9 +124,9 @@
<filename>runlevel2.target</filename>,
<filename>runlevel3.target</filename>,
... and is equivalent to
- <command>systemctl start
+ <command>systemctl isolate
runlevel2.target</command>,
- <command>systemctl start
+ <command>systemctl isolate
runlevel3.target</command>,
...</para></listitem>
</varlistentry>
commit 93a45c562a1989dfbb2dd08c65f8a21b02959934
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Aug 25 03:09:57 2010 +0200
serial: use seperate getty template for serial ttys
diff --git a/.gitignore b/.gitignore
index 1cee1b6..2c92ae0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,7 @@ systemd-kmsg-syslogd
systemd-remount-api-vfs
test-hostname
systemd-modules-load
-systemd-auto-console-getty
+systemd-auto-serial-getty
systemd-shutdownd
systemd-random-seed
systemd-update-utmp
diff --git a/Makefile.am b/Makefile.am
index aa2998d..859d332 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -73,7 +73,7 @@ rootlibexec_PROGRAMS = \
systemd-update-utmp \
systemd-random-seed \
systemd-shutdownd \
- systemd-auto-console-getty \
+ systemd-auto-serial-getty \
systemd-modules-load \
systemd-remount-api-vfs \
systemd-kmsg-syslogd
@@ -171,6 +171,7 @@ dist_systemunit_DATA = \
nodist_systemunit_DATA = \
units/sysinit.target \
units/getty at .service \
+ units/serial-getty at .service \
units/graphical.target \
units/remote-fs.target \
units/multi-user.target \
@@ -178,7 +179,7 @@ nodist_systemunit_DATA = \
units/systemd-logger.service \
units/systemd-shutdownd.service \
units/systemd-kmsg-syslogd.service \
- units/systemd-auto-console-getty.service \
+ units/systemd-auto-serial-getty.service \
units/systemd-modules-load.service \
units/systemd-remount-api-vfs.service \
units/systemd-update-utmp-runlevel.service \
@@ -197,6 +198,7 @@ nodist_sessionunit_DATA = \
EXTRA_DIST = \
units/sysinit.target.m4 \
units/getty at .service.m4 \
+ units/serial-getty at .service.m4 \
units/graphical.target.m4 \
units/multi-user.target.m4 \
units/remote-fs.target.m4 \
@@ -204,7 +206,7 @@ EXTRA_DIST = \
units/systemd-logger.service.in \
units/systemd-shutdownd.service.in \
units/systemd-kmsg-syslogd.service.in \
- units/systemd-auto-console-getty.service.in \
+ units/systemd-auto-serial-getty.service.in \
units/systemd-modules-load.service.in \
units/systemd-remount-api-vfs.service.in \
units/systemd-update-utmp-runlevel.service.in \
@@ -573,15 +575,15 @@ systemd_shutdownd_CFLAGS = \
systemd_shutdownd_LDADD = \
libsystemd-basic.la
-systemd_auto_console_getty_SOURCES = \
- src/auto-console-getty.c \
+systemd_auto_serial_getty_SOURCES = \
+ src/auto-serial-getty.c \
src/dbus-common.c
-systemd_auto_console_getty_CFLAGS = \
+systemd_auto_serial_getty_CFLAGS = \
$(AM_CFLAGS) \
$(DBUS_CFLAGS)
-systemd_auto_console_getty_LDADD = \
+systemd_auto_serial_getty_LDADD = \
libsystemd-basic.la \
$(DBUS_LIBS)
@@ -896,14 +898,14 @@ install-data-hook:
$(LN_S) $(systemunitdir)/reboot.target ctrl-alt-del.target && \
$(LN_S) $(systemunitdir)/rescue.target kbrequest.target )
( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \
- rm -f getty at tty1.service getty at tty2.service getty at tty3.service getty at tty4.service getty at tty5.service getty at tty6.service systemd-auto-console-getty.service && \
+ rm -f getty at tty1.service getty at tty2.service getty at tty3.service getty at tty4.service getty at tty5.service getty at tty6.service systemd-auto-serial-getty.service && \
$(LN_S) $(systemunitdir)/getty at .service getty at tty1.service && \
$(LN_S) $(systemunitdir)/getty at .service getty at tty2.service && \
$(LN_S) $(systemunitdir)/getty at .service getty at tty3.service && \
$(LN_S) $(systemunitdir)/getty at .service getty at tty4.service && \
$(LN_S) $(systemunitdir)/getty at .service getty at tty5.service && \
$(LN_S) $(systemunitdir)/getty at .service getty at tty6.service && \
- $(LN_S) $(systemunitdir)/systemd-auto-console-getty.service systemd-auto-console-getty.service )
+ $(LN_S) $(systemunitdir)/systemd-auto-serial-getty.service systemd-auto-serial-getty.service )
( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \
rm -f getty.target remote-fs.target && \
$(LN_S) $(systemunitdir)/getty.target getty.target && \
diff --git a/src/auto-console-getty.c b/src/auto-console-getty.c
deleted file mode 100644
index 44d2eff..0000000
--- a/src/auto-console-getty.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*-*- 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 <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <dbus/dbus.h>
-
-#include "util.h"
-#include "log.h"
-#include "dbus-common.h"
-
-static int spawn_getty(DBusConnection *bus, const char *console) {
- DBusMessage *m = NULL, *reply = NULL;
- DBusError error;
- const char *fail = "fail";
- char *name;
- int r = -EIO;
-
- dbus_error_init(&error);
-
- assert(bus);
- assert(console);
-
- /* FIXME: we probably should escape the tty name properly here */
- if (asprintf(&name, "getty@%s.service", console) < 0)
- return -ENOMEM;
-
- if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) {
- log_error("Could not allocate message.");
- goto finish;
- }
-
- if (!dbus_message_append_args(m,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_STRING, &fail,
- DBUS_TYPE_INVALID)) {
- log_error("Could not attach target and flag information to message.");
- goto finish;
- }
-
- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to start unit: %s", error.message);
- goto finish;
- }
-
- r = 0;
-
-finish:
- if (m)
- dbus_message_unref(m);
-
- if (reply)
- dbus_message_unref(reply);
-
- dbus_error_free(&error);
-
- free(name);
-
- return r;
-}
-
-static int parse_proc_cmdline_word(const char *word, char **console) {
- assert(word);
-
- if (startswith(word, "console=")) {
- const char *k;
- size_t l;
- char *w = NULL;
-
- k = word + 8;
- l = strcspn(k, ",");
-
- if (l < 4 ||
- !startswith(k, "tty") ||
- k[3+strspn(k+3, "0123456789")] != 0) {
-
- if (!(w = strndup(k, l)))
- return -ENOMEM;
-
- }
-
- free(*console);
- *console = w;
- }
-
- return 0;
-}
-
-static int parse_proc_cmdline(char **console) {
- char *line;
- int r;
- char *w;
- size_t l;
- char *state;
-
- assert(console);
-
- if ((r = read_one_line_file("/tmp/cmdline", &line)) < 0) {
- log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
- return 0;
- }
-
- FOREACH_WORD_QUOTED(w, l, line, state) {
- char *word;
-
- if (!(word = strndup(w, l))) {
- r = -ENOMEM;
- goto finish;
- }
-
- r = parse_proc_cmdline_word(word, console);
- free(word);
-
- if (r < 0)
- goto finish;
- }
-
- r = 0;
-
-finish:
- free(line);
- return r;
-}
-
-int main(int argc, char *argv[]) {
- DBusError error;
- int r = 1;
- char *console = NULL;
- DBusConnection *bus = NULL;
-
- dbus_error_init(&error);
-
- if (argc > 1) {
- log_error("This program does not take arguments.");
- return 1;
- }
-
- log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
- log_parse_environment();
- log_open();
-
- if (bus_connect(DBUS_BUS_SYSTEM, &bus, NULL, &error) < 0) {
- log_error("Failed to get D-Bus connection: %s", error.message);
- goto finish;
- }
-
- if (parse_proc_cmdline(&console) < 0)
- goto finish;
-
- if (console)
- if (spawn_getty(bus, console) < 0)
- goto finish;
-
- r = 0;
-
-finish:
- free(console);
-
- if (bus) {
- dbus_connection_close(bus);
- dbus_connection_unref(bus);
- }
-
- dbus_error_free(&error);
-
- dbus_shutdown();
-
- return r;
-}
diff --git a/src/auto-serial-getty.c b/src/auto-serial-getty.c
new file mode 100644
index 0000000..7bc2fba
--- /dev/null
+++ b/src/auto-serial-getty.c
@@ -0,0 +1,189 @@
+/*-*- 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 <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <dbus/dbus.h>
+
+#include "util.h"
+#include "log.h"
+#include "dbus-common.h"
+
+static int spawn_getty(DBusConnection *bus, const char *console) {
+ DBusMessage *m = NULL, *reply = NULL;
+ DBusError error;
+ const char *fail = "fail";
+ char *name;
+ int r = -EIO;
+
+ dbus_error_init(&error);
+
+ assert(bus);
+ assert(console);
+
+ /* FIXME: we probably should escape the tty name properly here */
+ if (asprintf(&name, "serial-getty@%s.service", console) < 0)
+ return -ENOMEM;
+
+ if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) {
+ log_error("Could not allocate message.");
+ goto finish;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &fail,
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not attach target and flag information to message.");
+ goto finish;
+ }
+
+ if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+ log_error("Failed to start unit: %s", error.message);
+ goto finish;
+ }
+
+ r = 0;
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ free(name);
+
+ return r;
+}
+
+static int parse_proc_cmdline_word(const char *word, char **console) {
+ assert(word);
+
+ if (startswith(word, "console=")) {
+ const char *k;
+ size_t l;
+ char *w = NULL;
+
+ k = word + 8;
+ l = strcspn(k, ",");
+
+ if (l < 4 ||
+ !startswith(k, "tty") ||
+ k[3+strspn(k+3, "0123456789")] != 0) {
+
+ if (!(w = strndup(k, l)))
+ return -ENOMEM;
+
+ }
+
+ free(*console);
+ *console = w;
+ }
+
+ return 0;
+}
+
+static int parse_proc_cmdline(char **console) {
+ char *line;
+ int r;
+ char *w;
+ size_t l;
+ char *state;
+
+ assert(console);
+
+ if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) {
+ log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+ return 0;
+ }
+
+ FOREACH_WORD_QUOTED(w, l, line, state) {
+ char *word;
+
+ if (!(word = strndup(w, l))) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ r = parse_proc_cmdline_word(word, console);
+ free(word);
+
+ if (r < 0)
+ goto finish;
+ }
+
+ r = 0;
+
+finish:
+ free(line);
+ return r;
+}
+
+int main(int argc, char *argv[]) {
+ DBusError error;
+ int r = 1;
+ char *console = NULL;
+ DBusConnection *bus = NULL;
+
+ dbus_error_init(&error);
+
+ if (argc > 1) {
+ log_error("This program does not take arguments.");
+ return 1;
+ }
+
+ log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
+ log_parse_environment();
+ log_open();
+
+ if (bus_connect(DBUS_BUS_SYSTEM, &bus, NULL, &error) < 0) {
+ log_error("Failed to get D-Bus connection: %s", error.message);
+ goto finish;
+ }
+
+ if (parse_proc_cmdline(&console) < 0)
+ goto finish;
+
+ if (console)
+ if (spawn_getty(bus, console) < 0)
+ goto finish;
+
+ r = 0;
+
+finish:
+ free(console);
+
+ if (bus) {
+ dbus_connection_close(bus);
+ dbus_connection_unref(bus);
+ }
+
+ dbus_error_free(&error);
+
+ dbus_shutdown();
+
+ return r;
+}
diff --git a/units/.gitignore b/units/.gitignore
index 82a2417..35f7908 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -1,3 +1,4 @@
+serial-getty at .service
systemd-kmsg-syslogd.service
systemd-modules-load.service
systemd-remount-api-vfs.service
diff --git a/units/getty at .service.m4 b/units/getty at .service.m4
index 01343c4..4b65d5b 100644
--- a/units/getty at .service.m4
+++ b/units/getty at .service.m4
@@ -30,7 +30,7 @@ Before=getty.target
[Service]
Environment=TERM=linux
-ExecStart=GETTY %I
+ExecStart=-GETTY %I
Restart=restart-always
RestartSec=0
KillMode=process-group
diff --git a/units/serial-getty at .service.m4 b/units/serial-getty at .service.m4
new file mode 100644
index 0000000..b91ed98
--- /dev/null
+++ b/units/serial-getty at .service.m4
@@ -0,0 +1,37 @@
+# This file is part of systemd.
+#
+# 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.
+
+[Unit]
+Description=Serial Getty on %I
+Requires=dev-%i.device
+After=dev-%i.device
+m4_ifdef(`TARGET_FEDORA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_ARCH',
+After=rc-local.service
+)m4_dnl
+
+# If additional gettys are spawned during boot (possibly by
+# systemd-auto-console-getty) then we should make sure that this is
+# synchronized before getty.target, even though getty.target didn't
+# actually pull it in.
+Before=getty.target
+
+[Service]
+Environment=TERM=vt100-nav
+m4_ifdef(`TARGET_FEDORA',
+ExecStartPre=-/sbin/securetty %I
+)m4_dnl
+ExecStart=-/sbin/agetty -s %I 115200,38400,9600
+Restart=restart-always
+RestartSec=0
+KillMode=process-group
+
+# Some login implementations ignore SIGTERM, so we send SIGHUP
+# instead, to ensure that login terminates cleanly.
+KillSignal=SIGHUP
diff --git a/units/systemd-auto-console-getty.service.in b/units/systemd-auto-console-getty.service.in
deleted file mode 100644
index 6542cab..0000000
--- a/units/systemd-auto-console-getty.service.in
+++ /dev/null
@@ -1,16 +0,0 @@
-# This file is part of systemd.
-#
-# 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.
-
-[Unit]
-Description=Automatically Spawn getty on Kernel Console
-
-[Service]
-Type=oneshot
-ExecStart=@rootlibexecdir@/systemd-auto-console-getty
-
-[Install]
-WantedBy=getty.target
diff --git a/units/systemd-auto-serial-getty.service b/units/systemd-auto-serial-getty.service
new file mode 100644
index 0000000..8051c74
--- /dev/null
+++ b/units/systemd-auto-serial-getty.service
@@ -0,0 +1,16 @@
+# This file is part of systemd.
+#
+# 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.
+
+[Unit]
+Description=Automatically Spawn getty on Serial Kernel Console
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-auto-serial-getty
+
+[Install]
+WantedBy=getty.target
commit addab137cd8d318e4f543ca56018ee23d51aaca9
Author: Lennart Poettering <lennart at poettering.net>
Date: Sat Aug 21 03:57:47 2010 +0200
syslog: add minimal syslog/kmsg bridge syslogd
diff --git a/.gitignore b/.gitignore
index 42d9c8c..1cee1b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+systemd-kmsg-syslogd
systemd-remount-api-vfs
test-hostname
systemd-modules-load
diff --git a/Makefile.am b/Makefile.am
index ca25baf..aa2998d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -75,7 +75,8 @@ rootlibexec_PROGRAMS = \
systemd-shutdownd \
systemd-auto-console-getty \
systemd-modules-load \
- systemd-remount-api-vfs
+ systemd-remount-api-vfs \
+ systemd-kmsg-syslogd
noinst_PROGRAMS = \
test-engine \
@@ -143,6 +144,7 @@ dist_systemunit_DATA = \
units/systemd-initctl.socket \
units/systemd-logger.socket \
units/systemd-shutdownd.socket \
+ units/systemd-kmsg-syslogd.socket \
units/dev-hugepages.automount \
units/dev-hugepages.mount \
units/dev-mqueue.automount \
@@ -175,6 +177,7 @@ nodist_systemunit_DATA = \
units/systemd-initctl.service \
units/systemd-logger.service \
units/systemd-shutdownd.service \
+ units/systemd-kmsg-syslogd.service \
units/systemd-auto-console-getty.service \
units/systemd-modules-load.service \
units/systemd-remount-api-vfs.service \
@@ -200,6 +203,7 @@ EXTRA_DIST = \
units/systemd-initctl.service.in \
units/systemd-logger.service.in \
units/systemd-shutdownd.service.in \
+ units/systemd-kmsg-syslogd.service.in \
units/systemd-auto-console-getty.service.in \
units/systemd-modules-load.service.in \
units/systemd-remount-api-vfs.service.in \
@@ -612,6 +616,17 @@ systemd_cgroups_agent_LDADD = \
libsystemd-basic.la \
$(DBUS_LIBS)
+systemd_kmsg_syslogd_SOURCES = \
+ src/kmsg-syslogd.c \
+ src/sd-daemon.c \
+ src/fdset.c
+
+systemd_kmsg_syslogd_CFLAGS = \
+ $(AM_CFLAGS)
+
+systemd_kmsg_syslogd_LDADD = \
+ libsystemd-basic.la
+
systemctl_SOURCES = \
src/systemctl.c \
src/utmp-wtmp.c \
diff --git a/src/fdset.c b/src/fdset.c
index b482f0b..29e75a0 100644
--- a/src/fdset.c
+++ b/src/fdset.c
@@ -49,7 +49,7 @@ void fdset_free(FDSet *s) {
* here, so that the EBADFD that valgrind will return
* us on close() doesn't influence us */
- log_warning("Closing left-over fd %i", PTR_TO_FD(p));
+ /* log_warning("Closing left-over fd %i", PTR_TO_FD(p)); */
close_nointr(PTR_TO_FD(p));
}
diff --git a/src/kmsg-syslogd.c b/src/kmsg-syslogd.c
new file mode 100644
index 0000000..f5c8e71
--- /dev/null
+++ b/src/kmsg-syslogd.c
@@ -0,0 +1,545 @@
+/*-*- 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 <sys/socket.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <time.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <sys/epoll.h>
+#include <sys/un.h>
+#include <fcntl.h>
+#include <sys/signalfd.h>
+
+#include "util.h"
+#include "log.h"
+#include "sd-daemon.h"
+#include "fdset.h"
+
+#define SERVER_FD_MAX 16
+#define TIMEOUT ((int) (10*MSEC_PER_SEC))
+
+typedef struct Stream Stream;
+
+typedef struct Server {
+ FDSet *syslog_fds;
+ int kmsg_fd;
+ int epoll_fd;
+ int signal_fd;
+} Server;
+
+static void server_done(Server *s) {
+ assert(s);
+
+ if (s->epoll_fd >= 0)
+ close_nointr_nofail(s->epoll_fd);
+
+ if (s->kmsg_fd >= 0)
+ close_nointr_nofail(s->kmsg_fd);
+
+ if (s->signal_fd >= 0)
+ close_nointr_nofail(s->signal_fd);
+
+ if (s->syslog_fds)
+ fdset_free(s->syslog_fds);
+}
+
+static int server_init(Server *s, unsigned n_sockets) {
+ int r;
+ unsigned i;
+ struct epoll_event ev;
+ sigset_t mask;
+
+ assert(s);
+ assert(n_sockets > 0);
+
+ zero(*s);
+
+ s->kmsg_fd = s->signal_fd = -1;
+
+ if ((s->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
+ r = -errno;
+ log_error("Failed to create epoll object: %s", strerror(errno));
+ goto fail;
+ }
+
+ if (!(s->syslog_fds = fdset_new())) {
+ r = -ENOMEM;
+ log_error("Failed to allocate file descriptor set: %s", strerror(errno));
+ goto fail;
+ }
+
+ for (i = 0; i < n_sockets; i++) {
+ int fd, one = 1;
+
+ fd = SD_LISTEN_FDS_START+i;
+
+ if ((r = sd_is_socket(fd, AF_UNSPEC, SOCK_DGRAM, -1)) < 0) {
+ log_error("Failed to determine file descriptor type: %s", strerror(-r));
+ goto fail;
+ }
+
+ if (!r) {
+ log_error("Wrong file descriptor type.");
+ r = -EINVAL;
+ goto fail;
+ }
+
+ if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
+ log_error("SO_PASSCRED failed: %m");
+
+ zero(ev);
+ ev.events = EPOLLIN;
+ ev.data.fd = fd;
+ if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
+ r = -errno;
+ log_error("Failed to add server fd to epoll object: %s", strerror(errno));
+ goto fail;
+ }
+
+ if ((r = fdset_put(s->syslog_fds, fd)) < 0) {
+ log_error("Failed to store file descriptor in set: %s", strerror(-r));
+ goto fail;
+ }
+ }
+
+ if ((s->kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) {
+ log_error("Failed to open /dev/kmsg for logging: %m");
+ return -errno;
+ }
+
+ assert_se(sigemptyset(&mask) == 0);
+ sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+ assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+ if ((s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
+ log_error("signalfd(): %m");
+ return -errno;
+ }
+
+ zero(ev);
+ ev.events = EPOLLIN;
+ ev.data.fd = s->signal_fd;
+
+ if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) {
+ log_error("epoll_ctl(): %m");
+ return -errno;
+ }
+
+ return 0;
+
+fail:
+ server_done(s);
+ return r;
+}
+
+static int read_priority(const char **buf) {
+ int priority;
+ size_t n;
+ const char *p;
+ int a, b, c;
+
+ assert(buf);
+ assert(*buf);
+
+ p = *buf;
+ n = strlen(p);
+
+ if (n < 3 || p[0] != '<')
+ goto fail;
+
+ if (p[2] == '>') {
+ a = b = 0;
+ c = undecchar(p[1]);
+ p += 3;
+ } else if (n >= 4 && p[3] == '>') {
+ a = 0;
+ b = undecchar(p[1]);
+ c = undecchar(p[2]);
+ p += 4;
+ } else if (n >= 5 && p[4] == '>') {
+ a = undecchar(p[1]);
+ b = undecchar(p[2]);
+ c = undecchar(p[3]);
+ p += 5;
+ } else
+ goto fail;
+
+ if (a < 0 || b < 0 || c < 0)
+ goto fail;
+
+ *buf = p;
+
+ priority = 100*a + 10*b + c;
+ return LOG_PRI(priority);
+
+fail:
+ return LOG_INFO;
+}
+
+static void skip_date(const char **buf) {
+ enum {
+ LETTER,
+ SPACE,
+ NUMBER,
+ SPACE_OR_NUMBER,
+ COLON
+ } sequence[] = {
+ LETTER, LETTER, LETTER,
+ SPACE,
+ SPACE_OR_NUMBER, NUMBER,
+ SPACE,
+ SPACE_OR_NUMBER, NUMBER,
+ COLON,
+ SPACE_OR_NUMBER, NUMBER,
+ COLON,
+ SPACE_OR_NUMBER, NUMBER,
+ SPACE
+ };
+
+ const char *p;
+ unsigned i;
+
+ assert(buf);
+ assert(*buf);
+
+ p = *buf;
+
+ for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
+
+ if (!*p)
+ return;
+
+ switch (sequence[i]) {
+
+ case SPACE:
+ if (*p != ' ')
+ return;
+ break;
+
+ case SPACE_OR_NUMBER:
+ if (*p == ' ')
+ break;
+
+ /* fall through */
+
+ case NUMBER:
+ if (*p < '0' || *p > '9')
+ return;
+
+ break;
+
+ case LETTER:
+ if (!(*p >= 'A' && *p <= 'Z') &&
+ !(*p >= 'a' && *p <= 'z'))
+ return;
+
+ break;
+
+ case COLON:
+ if (*p != ':')
+ return;
+ break;
+
+ }
+ }
+
+ *buf = p;
+}
+
+static int read_process(const char **buf, struct iovec *iovec) {
+ const char *p;
+ size_t l;
+
+ assert(buf);
+ assert(*buf);
+ assert(iovec);
+
+ p = *buf;
+
+ p += strspn(p, WHITESPACE);
+ l = strcspn(p, WHITESPACE);
+
+ if (l <= 0 ||
+ p[l-1] != ':')
+ return 0;
+
+ l--;
+
+ if (p[l-1] == ']') {
+ size_t k = l-1;
+
+ for (;;) {
+
+ if (p[k] == '[') {
+ l = k;
+ break;
+ }
+
+ if (k == 0)
+ break;
+
+ k--;
+ }
+ }
+
+ iovec->iov_base = (char*) p;
+ iovec->iov_len = l;
+ *buf = p + l;
+ return 1;
+}
+
+static void skip_pid(const char **buf) {
+ const char *p;
+
+ assert(buf);
+ assert(*buf);
+
+ p = *buf;
+
+ if (*p != '[')
+ return;
+
+ p++;
+ p += strspn(p, "0123456789");
+
+ if (*p != ']')
+ return;
+
+ p++;
+
+ *buf = p;
+}
+
+static int write_message(Server *s, const char *buf, struct ucred *ucred) {
+ ssize_t k;
+ char priority[4], pid[16];
+ struct iovec iovec[5];
+ unsigned i = 0;
+ char *process = NULL;
+ int r = 0;
+
+ assert(s);
+ assert(buf);
+
+ /* First, set priority field */
+ snprintf(priority, sizeof(priority), "<%i>", read_priority(&buf));
+ char_array_0(priority);
+ IOVEC_SET_STRING(iovec[i++], priority);
+
+ /* Second, skip date */
+ skip_date(&buf);
+
+ /* Then, add process if set */
+ if (read_process(&buf, &iovec[i]) > 0)
+ i++;
+ else if (ucred && get_process_name(ucred->pid, &process) >= 0)
+ IOVEC_SET_STRING(iovec[i++], process);
+
+ /* Skip the stored PID if we have a better one */
+ if (ucred) {
+ snprintf(pid, sizeof(pid), "[%lu]: ", (unsigned long) ucred->pid);
+ char_array_0(pid);
+ IOVEC_SET_STRING(iovec[i++], pid);
+
+ skip_pid(&buf);
+
+ if (*buf == ':')
+ buf++;
+
+ buf += strspn(buf, WHITESPACE);
+ }
+
+ /* Is the remaining message empty? */
+ if (*buf) {
+
+ /* And the rest is the message */
+ IOVEC_SET_STRING(iovec[i++], buf);
+ IOVEC_SET_STRING(iovec[i++], "\n");
+
+ if ((k = writev(s->kmsg_fd, iovec, i)) <= 0) {
+ log_error("Failed to write log message to kmsg: %s", k < 0 ? strerror(errno) : "short write");
+ r = k < 0 ? -errno : -EIO;
+ }
+ }
+
+ free(process);
+
+ return r;
+}
+
+static int process_event(Server *s, struct epoll_event *ev) {
+ assert(s);
+
+ if (ev->events != EPOLLIN) {
+ log_info("Got invalid event from epoll.");
+ return -EIO;
+ }
+
+ if (ev->data.fd == s->signal_fd) {
+ struct signalfd_siginfo sfsi;
+ ssize_t n;
+
+ if ((n = read(s->signal_fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
+
+ if (n >= 0)
+ return -EIO;
+
+ if (errno == EINTR || errno == EAGAIN)
+ return 0;
+
+ return -errno;
+ }
+
+ log_debug("Received SIG%s", strna(signal_to_string(sfsi.ssi_signo)));
+ return 0;
+
+ } else {
+ for (;;) {
+ char buf[LINE_MAX+1];
+ struct msghdr msghdr;
+ struct iovec iovec;
+ struct ucred *ucred;
+ union {
+ struct cmsghdr cmsghdr;
+ uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
+ } control;
+ ssize_t n;
+ int k;
+ char *e;
+
+ zero(iovec);
+ iovec.iov_base = buf;
+ iovec.iov_len = sizeof(buf)-1;
+
+ zero(control);
+ zero(msghdr);
+ msghdr.msg_iov = &iovec;
+ msghdr.msg_iovlen = 1;
+ msghdr.msg_control = &control;
+ msghdr.msg_controllen = sizeof(control);
+
+ if ((n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT)) < 0) {
+
+ if (errno == EINTR || errno == EAGAIN)
+ return 1;
+
+ log_error("recvmsg() failed: %m");
+ return -errno;
+ }
+
+ if (msghdr.msg_controllen >= CMSG_LEN(sizeof(struct ucred)) &&
+ control.cmsghdr.cmsg_level == SOL_SOCKET &&
+ control.cmsghdr.cmsg_type == SCM_CREDENTIALS &&
+ control.cmsghdr.cmsg_len == CMSG_LEN(sizeof(struct ucred)))
+ ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
+ else
+ ucred = NULL;
+
+ if ((e = memchr(buf, '\n', n)))
+ *e = 0;
+ else
+ buf[n] = 0;
+
+ if ((k = write_message(s, strstrip(buf), ucred)) < 0)
+ return k;
+ }
+ }
+
+ return 1;
+}
+
+int main(int argc, char *argv[]) {
+ Server server;
+ int r = 3, n;
+
+ if (getppid() != 1) {
+ log_error("This program should be invoked by init only.");
+ return 1;
+ }
+
+ if (argc > 1) {
+ log_error("This program does not take arguments.");
+ return 1;
+ }
+
+ log_set_target(LOG_TARGET_KMSG);
+ log_parse_environment();
+ log_open();
+
+ if ((n = sd_listen_fds(true)) < 0) {
+ log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
+ return 1;
+ }
+
+ if (n <= 0 || n > SERVER_FD_MAX) {
+ log_error("No or too many file descriptors passed.");
+ return 2;
+ }
+
+ if (server_init(&server, (unsigned) n) < 0)
+ return 3;
+
+ log_debug("systemd-kmsg-syslogd running as pid %lu", (unsigned long) getpid());
+
+ sd_notify(false,
+ "READY=1\n"
+ "STATUS=Processing messages...");
+
+ for (;;) {
+ struct epoll_event event;
+ int k;
+
+ if ((k = epoll_wait(server.epoll_fd, &event, 1, TIMEOUT)) < 0) {
+
+ if (errno == EINTR)
+ continue;
+
+ log_error("epoll_wait() failed: %m");
+ goto fail;
+ }
+
+ if (k <= 0)
+ break;
+
+ if ((k = process_event(&server, &event)) < 0)
+ goto fail;
+
+ if (k == 0)
+ break;
+ }
+
+ r = 0;
+
+ log_debug("systemd-kmsg-syslogd stopped as pid %lu", (unsigned long) getpid());
+
+fail:
+ sd_notify(false,
+ "STATUS=Shutting down...");
+
+ server_done(&server);
+
+ return r;
+}
diff --git a/src/log.c b/src/log.c
index 729b9ea..3c42e8e 100644
--- a/src/log.c
+++ b/src/log.c
@@ -32,7 +32,6 @@
#include "macro.h"
#define SYSLOG_TIMEOUT_USEC (5*USEC_PER_SEC)
-#define LOG_BUFFER_MAX 1024
static LogTarget log_target = LOG_TARGET_CONSOLE;
static int log_max_level = LOG_INFO;
@@ -417,7 +416,7 @@ int log_meta(
const char *func,
const char *format, ...) {
- char buffer[LOG_BUFFER_MAX];
+ char buffer[LINE_MAX];
int saved_errno, r;
va_list ap;
@@ -444,7 +443,7 @@ void log_assert(
const char *func,
const char *format, ...) {
- static char buffer[LOG_BUFFER_MAX];
+ static char buffer[LINE_MAX];
int saved_errno = errno;
va_list ap;
diff --git a/src/logger.c b/src/logger.c
index 95d58fc..5a28c21 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -38,7 +38,6 @@
#include "sd-daemon.h"
#include "tcpwrap.h"
-#define STREAM_BUFFER 2048
#define STREAMS_MAX 256
#define SERVER_FD_MAX 16
#define TIMEOUT ((int) (10*MSEC_PER_SEC))
@@ -85,7 +84,7 @@ struct Stream {
bool prefix;
- char buffer[STREAM_BUFFER];
+ char buffer[LINE_MAX];
size_t length;
LIST_FIELDS(Stream, stream);
@@ -297,7 +296,7 @@ static int stream_process(Stream *s, usec_t ts) {
int r;
assert(s);
- if ((l = read(s->fd, s->buffer+s->length, STREAM_BUFFER-s->length)) < 0) {
+ if ((l = read(s->fd, s->buffer+s->length, LINE_MAX-s->length)) < 0) {
if (errno == EAGAIN)
return 0;
@@ -617,7 +616,7 @@ int main(int argc, char *argv[]) {
r = 0;
- log_info("systemd-logger stopped as pid %lu", (unsigned long) getpid());
+ log_debug("systemd-logger stopped as pid %lu", (unsigned long) getpid());
fail:
sd_notify(false,
diff --git a/units/.gitignore b/units/.gitignore
index 801e9d6..82a2417 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -1,3 +1,4 @@
+systemd-kmsg-syslogd.service
systemd-modules-load.service
systemd-remount-api-vfs.service
systemd-auto-console-getty.service
diff --git a/units/systemd-kmsg-syslogd.service.in b/units/systemd-kmsg-syslogd.service.in
new file mode 100644
index 0000000..e2e0f55
--- /dev/null
+++ b/units/systemd-kmsg-syslogd.service.in
@@ -0,0 +1,16 @@
+# This file is part of systemd.
+#
+# 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.
+
+# See systemd.special(7) for details
+
+[Unit]
+Description=systemd Syslog Kernel Log Buffer Bridge
+DefaultDependencies=no
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-kmsg-syslogd
+NotifyAccess=all
diff --git a/units/systemd-kmsg-syslogd.socket b/units/systemd-kmsg-syslogd.socket
new file mode 100644
index 0000000..7487cd5
--- /dev/null
+++ b/units/systemd-kmsg-syslogd.socket
@@ -0,0 +1,20 @@
+# This file is part of systemd.
+#
+# 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.
+
+# See systemd.special(7) for details
+
+[Unit]
+Description=Syslog Socket
+DefaultDependencies=no
+Before=sockets.target
+
+[Socket]
+ListenDatagram=/dev/log
+SocketMode=0666
+
+[Install]
+WantedBy=sysinit.target
More information about the systemd-commits
mailing list