From cc5524ecc60a83fb88cac02fe02e21cde3951a25 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 02:51:45 +0100 Subject: [PATCH 001/200] mount: use /dev/.run as an early boot alias for /var/run During early boot, mount a tmpfs to /dev/.run and then bind mount it to /var/run as soon as /var is available. This makes it possible for programs involved in early boot to put runtime data in /dev/.run which later on will show up in /var/run like any other. This can be used to solve the early-boot D-Bus problem: D-Bus may start up with its socket bound to /dev/.run/dbus/system_bus_socket and after /var it will also be available under the traditional name /var/run/dbus/system_bus_socket. This also is intended to be used as a better place for systemd, mount, mdadm, blkid, plymouth, bootchart and dracut runtime data, which is currently stored in various places in /dev/.xxx. --- src/mount-setup.c | 1 + units/var-run.mount | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mount-setup.c b/src/mount-setup.c index 5cbaee6be..f08eeb162 100644 --- a/src/mount-setup.c +++ b/src/mount-setup.c @@ -54,6 +54,7 @@ static const MountPoint mount_table[] = { { "devtmpfs", "/dev", "devtmpfs", "mode=755", MS_NOSUID, true }, { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV, true }, { "devpts", "/dev/pts", "devpts", "mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, false }, + { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, }; diff --git a/units/var-run.mount b/units/var-run.mount index 8ccb4bb28..cd3889ebc 100644 --- a/units/var-run.mount +++ b/units/var-run.mount @@ -10,7 +10,7 @@ Description=Runtime Directory Before=local-fs.target [Mount] -What=tmpfs +What=/dev/.run Where=/var/run -Type=tmpfs -Options=mode=755,nosuid,nodev,noexec +Type=bind +Options=bind From 34df5a34e1d0ac4bba453fb5f52f18a2f5f260f9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 19:48:02 +0100 Subject: [PATCH 002/200] drop unnecessary suffix NULs as gcc adds them anyway --- TODO | 4 ++++ src/dbus-device.c | 3 +-- src/dbus-job.c | 3 +-- src/dbus-mount.c | 3 +-- src/dbus-service.c | 3 +-- src/dbus-socket.c | 4 ++-- src/dbus-swap.c | 3 +-- src/dbus-timer.c | 3 +-- src/dbus-unit.c | 3 +-- src/dbus.c | 1 + src/mount-setup.c | 3 +-- src/util.c | 6 ++---- 12 files changed, 17 insertions(+), 22 deletions(-) diff --git a/TODO b/TODO index ad844d5cd..237ba7b2a 100644 --- a/TODO +++ b/TODO @@ -22,6 +22,10 @@ F15: * drop SIGHUP handling from rsyslog.service upstream +* teach dbus to activate all services it finds in /etc/systemd/services/org-*.service + +* save/restore tool for SysV as requested by FPC + Features: * consider services with no [Install] section and stored in /lib enabled by "systemctl is-enabled" diff --git a/src/dbus-device.c b/src/dbus-device.c index aafe5d61f..9b2861de4 100644 --- a/src/dbus-device.c +++ b/src/dbus-device.c @@ -40,8 +40,7 @@ const char bus_device_interface[] _introspect_("Device") = BUS_DEVICE_INTERFACE; const char bus_device_invalidating_properties[] = - "SysFSPath\0" - "\0"; + "SysFSPath\0"; DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { diff --git a/src/dbus-job.c b/src/dbus-job.c index e90d585b6..95367c422 100644 --- a/src/dbus-job.c +++ b/src/dbus-job.c @@ -46,8 +46,7 @@ const char bus_job_interface[] _introspect_("Job") = BUS_JOB_INTERFACE; #define INVALIDATING_PROPERTIES \ - "State\0" \ - "\0" \ + "State\0" static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_state, job_state, JobState); static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_type, job_type, JobType); diff --git a/src/dbus-mount.c b/src/dbus-mount.c index fa319febd..e3a793d19 100644 --- a/src/dbus-mount.c +++ b/src/dbus-mount.c @@ -59,8 +59,7 @@ const char bus_mount_invalidating_properties[] = "ExecMount\0" "ExecUnmount\0" "ExecRemount\0" - "ControlPID\0" - "\0"; + "ControlPID\0"; static int bus_mount_append_what(Manager *n, DBusMessageIter *i, const char *property, void *data) { Mount *m = data; diff --git a/src/dbus-service.c b/src/dbus-service.c index 93fc2a3b6..1b6c7f47b 100644 --- a/src/dbus-service.c +++ b/src/dbus-service.c @@ -102,8 +102,7 @@ const char bus_service_invalidating_properties[] = "ExecMain\0" "MainPID\0" "ControlPID\0" - "StatusText\0" - "\0"; + "StatusText\0"; static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType); static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_restart, service_restart, ServiceRestart); diff --git a/src/dbus-socket.c b/src/dbus-socket.c index a9cb1c38f..3fda76db8 100644 --- a/src/dbus-socket.c +++ b/src/dbus-socket.c @@ -73,12 +73,12 @@ const char bus_socket_invalidating_properties[] = "ExecStopPost\0" "ControlPID\0" "NAccepted\0" - "NConnections\0" - "\0"; + "NConnections\0"; static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Socket", "BindIPv6Only", bus_socket_append_bind_ipv6_only, "s", &u->socket.bind_ipv6_only }, diff --git a/src/dbus-swap.c b/src/dbus-swap.c index 06acb22dc..723cd64a8 100644 --- a/src/dbus-swap.c +++ b/src/dbus-swap.c @@ -54,8 +54,7 @@ const char bus_swap_invalidating_properties[] = "Priority\0" "ExecActivate\0" "ExecDeactivate\0" - "ControlPID\0" - "\0"; + "ControlPID\0"; static int bus_swap_append_priority(Manager *m, DBusMessageIter *i, const char *property, void *data) { Swap *s = data; diff --git a/src/dbus-timer.c b/src/dbus-timer.c index f4c23e0ea..eed05e699 100644 --- a/src/dbus-timer.c +++ b/src/dbus-timer.c @@ -46,8 +46,7 @@ const char bus_timer_interface[] _introspect_("Timer") = BUS_TIMER_INTERFACE; const char bus_timer_invalidating_properties[] = "Timers\0" - "NextElapseUSec\0" - "\0"; + "NextElapseUSec\0"; static int bus_timer_append_timers(Manager *m, DBusMessageIter *i, const char *property, void *data) { Timer *p = data; diff --git a/src/dbus-unit.c b/src/dbus-unit.c index cd6ad843f..52e8599e7 100644 --- a/src/dbus-unit.c +++ b/src/dbus-unit.c @@ -37,8 +37,7 @@ const char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE; "ActiveExitTimestamp\0" \ "InactiveEnterTimestamp\0" \ "Job\0" \ - "NeedDaemonReload\0" \ - "\0" + "NeedDaemonReload\0" int bus_unit_append_names(Manager *m, DBusMessageIter *i, const char *property, void *data) { char *t; diff --git a/src/dbus.c b/src/dbus.c index 5a4750d6b..dae5f9ec4 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -1316,6 +1316,7 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set") && properties) { const char *interface, *property; DBusMessageIter iter; diff --git a/src/mount-setup.c b/src/mount-setup.c index f08eeb162..09ee07f82 100644 --- a/src/mount-setup.c +++ b/src/mount-setup.c @@ -228,8 +228,7 @@ int mount_setup(void) { "/proc/self/fd\0" "/dev/fd\0" "/proc/self/fd/0\0" "/dev/stdin\0" "/proc/self/fd/1\0" "/dev/stdout\0" - "/proc/self/fd/2\0" "/dev/stderr\0" - "\0"; + "/proc/self/fd/2\0" "/dev/stderr\0"; int r; unsigned i; diff --git a/src/util.c b/src/util.c index 96cf6605f..4acb3c305 100644 --- a/src/util.c +++ b/src/util.c @@ -3820,8 +3820,7 @@ int detect_vm(const char **id) { "Microsoft Corporation\0" "microsoft\0" "innotek GmbH\0" "oracle\0" "Xen\0" "xen\0" - "Bochs\0" "bochs\0" - "\0"; + "Bochs\0" "bochs\0"; static const char cpuid_vendor_table[] = "XenVMMXenVMM\0" "xen\0" @@ -3829,8 +3828,7 @@ int detect_vm(const char **id) { /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ "VMwareVMware\0" "vmware\0" /* http://msdn.microsoft.com/en-us/library/ff542428.aspx */ - "Microsoft Hv\0" "microsoft\0" - "\0"; + "Microsoft Hv\0" "microsoft\0"; uint32_t eax, ecx; union { From 05feefe0fb049bb0f7c59584058ee0350462920c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 20:01:53 +0100 Subject: [PATCH 003/200] dbus: properly generate UnknownInterface, UnknownProperty and PropertyReadOnly errors --- src/dbus-automount.c | 6 +++++- src/dbus-device.c | 6 +++++- src/dbus-job.c | 6 +++++- src/dbus-manager.c | 6 +++++- src/dbus-mount.c | 6 +++++- src/dbus-path.c | 6 +++++- src/dbus-service.c | 6 +++++- src/dbus-snapshot.c | 6 +++++- src/dbus-socket.c | 6 +++++- src/dbus-swap.c | 6 +++++- src/dbus-target.c | 6 +++++- src/dbus-timer.c | 6 +++++- src/dbus-unit.h | 4 ++++ src/dbus.c | 38 +++++++++++++++++++++++++++++++++++--- src/dbus.h | 15 ++++++++++++++- src/util.c | 13 +++++++++++++ src/util.h | 2 ++ 17 files changed, 128 insertions(+), 16 deletions(-) diff --git a/src/dbus-automount.c b/src/dbus-automount.c index af277af39..eccad37e8 100644 --- a/src/dbus-automount.c +++ b/src/dbus-automount.c @@ -38,6 +38,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Automount\0" + const char bus_automount_interface[] _introspect_("Automount") = BUS_AUTOMOUNT_INTERFACE; DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { @@ -48,5 +52,5 @@ DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBus { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-device.c b/src/dbus-device.c index 9b2861de4..b046eae9f 100644 --- a/src/dbus-device.c +++ b/src/dbus-device.c @@ -37,6 +37,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Device\0" + const char bus_device_interface[] _introspect_("Device") = BUS_DEVICE_INTERFACE; const char bus_device_invalidating_properties[] = @@ -49,5 +53,5 @@ DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMes { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-job.c b/src/dbus-job.c index 95367c422..b66d23604 100644 --- a/src/dbus-job.c +++ b/src/dbus-job.c @@ -45,6 +45,10 @@ const char bus_job_interface[] _introspect_("Job") = BUS_JOB_INTERFACE; +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Job\0" + #define INVALIDATING_PROPERTIES \ "State\0" @@ -99,7 +103,7 @@ static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connec job_finish_and_invalidate(j, JOB_CANCELED); } else - return bus_default_message_handler(j->manager, connection, message, INTROSPECTION, properties); + return bus_default_message_handler(j->manager, connection, message, INTROSPECTION, INTERFACES_LIST, properties); if (reply) { if (!dbus_connection_send(connection, reply, NULL)) diff --git a/src/dbus-manager.c b/src/dbus-manager.c index 7d4703b88..2edbc37b5 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -206,6 +206,10 @@ #define INTROSPECTION_END \ "\n" +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Manager\0" + const char bus_manager_interface[] _introspect_("Manager") = BUS_MANAGER_INTERFACE; static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_running_as, manager_running_as, ManagerRunningAs); @@ -1021,7 +1025,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, m->environment = e; } else - return bus_default_message_handler(m, connection, message, NULL, properties); + return bus_default_message_handler(m, connection, message, NULL, INTERFACES_LIST, properties); if (job_type != _JOB_TYPE_INVALID) { const char *name, *smode, *old_name = NULL; diff --git a/src/dbus-mount.c b/src/dbus-mount.c index e3a793d19..5fb9a3f07 100644 --- a/src/dbus-mount.c +++ b/src/dbus-mount.c @@ -50,6 +50,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Mount\0" + const char bus_mount_interface[] _introspect_("Mount") = BUS_MOUNT_INTERFACE; const char bus_mount_invalidating_properties[] = @@ -150,5 +154,5 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMess { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-path.c b/src/dbus-path.c index 6155792d0..cb1d4f09c 100644 --- a/src/dbus-path.c +++ b/src/dbus-path.c @@ -41,6 +41,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Path\0" + const char bus_path_interface[] _introspect_("Path") = BUS_PATH_INTERFACE; static int bus_path_append_paths(Manager *m, DBusMessageIter *i, const char *property, void *data) { @@ -94,5 +98,5 @@ DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessa { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-service.c b/src/dbus-service.c index 1b6c7f47b..6bb6a9d6e 100644 --- a/src/dbus-service.c +++ b/src/dbus-service.c @@ -90,6 +90,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Service\0" + const char bus_service_interface[] _introspect_("Service") = BUS_SERVICE_INTERFACE; const char bus_service_invalidating_properties[] = @@ -144,5 +148,5 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, connection, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, connection, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-snapshot.c b/src/dbus-snapshot.c index a9903ec48..cc12b1bd8 100644 --- a/src/dbus-snapshot.c +++ b/src/dbus-snapshot.c @@ -38,6 +38,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Snapshot\0" + const char bus_snapshot_interface[] _introspect_("Snapshot") = BUS_SNAPSHOT_INTERFACE; DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { @@ -60,7 +64,7 @@ DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusM goto oom; } else - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); if (reply) { if (!dbus_connection_send(c, reply, NULL)) diff --git a/src/dbus-socket.c b/src/dbus-socket.c index 3fda76db8..5b068b45f 100644 --- a/src/dbus-socket.c +++ b/src/dbus-socket.c @@ -64,6 +64,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Socket\0" + const char bus_socket_interface[] _introspect_("Socket") = BUS_SOCKET_INTERFACE; const char bus_socket_invalidating_properties[] = @@ -109,5 +113,5 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-swap.c b/src/dbus-swap.c index 723cd64a8..079912a53 100644 --- a/src/dbus-swap.c +++ b/src/dbus-swap.c @@ -47,6 +47,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Swap\0" + const char bus_swap_interface[] _introspect_("Swap") = BUS_SWAP_INTERFACE; const char bus_swap_invalidating_properties[] = @@ -92,5 +96,5 @@ DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessa { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-target.c b/src/dbus-target.c index 1eb3c249f..1cbeccb57 100644 --- a/src/dbus-target.c +++ b/src/dbus-target.c @@ -38,6 +38,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Target\0" + const char bus_target_interface[] _introspect_("Target") = BUS_TARGET_INTERFACE; DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { @@ -46,5 +50,5 @@ DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMes { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-timer.c b/src/dbus-timer.c index eed05e699..e44f4e2fe 100644 --- a/src/dbus-timer.c +++ b/src/dbus-timer.c @@ -42,6 +42,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Timer\0" + const char bus_timer_interface[] _introspect_("Timer") = BUS_TIMER_INTERFACE; const char bus_timer_invalidating_properties[] = @@ -118,5 +122,5 @@ DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMess { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-unit.h b/src/dbus-unit.h index b51fe4eb6..4e46fc482 100644 --- a/src/dbus-unit.h +++ b/src/dbus-unit.h @@ -104,6 +104,10 @@ " \n" \ " \n" +#define BUS_UNIT_INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Unit\0" + #define BUS_UNIT_PROPERTIES \ { "org.freedesktop.systemd1.Unit", "Id", bus_property_append_string, "s", u->meta.id }, \ { "org.freedesktop.systemd1.Unit", "Names", bus_unit_append_names, "as", u }, \ diff --git a/src/dbus.c b/src/dbus.c index dae5f9ec4..af03c5746 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -1213,12 +1213,20 @@ oom: return -ENOMEM; } -DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char*introspection, const BusProperty *properties) { +DBusHandlerResult bus_default_message_handler( + Manager *m, + DBusConnection *c, + DBusMessage *message, + const char *introspection, + const char *interfaces, + const BusProperty *properties) { + DBusError error; DBusMessage *reply = NULL; int r; assert(m); + assert(c); assert(message); dbus_error_init(&error); @@ -1269,6 +1277,13 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; + } else { + if (!nulstr_contains(interfaces, interface)) + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + else + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + + return bus_send_error_reply(m, c, message, &error, -EINVAL); } } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && properties) { @@ -1283,6 +1298,11 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu DBUS_TYPE_INVALID)) return bus_send_error_reply(m, c, message, &error, -EINVAL); + if (interface[0] && !nulstr_contains(interfaces, interface)) { + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + return bus_send_error_reply(m, c, message, &error, -EINVAL); + } + if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -1367,8 +1387,20 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu if (!(reply = dbus_message_new_method_return(message))) goto oom; - } else - return bus_send_error_reply(m, c, message, NULL, -EINVAL); + } else { + if (p->property) + dbus_set_error_const(&error, DBUS_ERROR_PROPERTY_READ_ONLY, "Property read-only"); + else if (!nulstr_contains(interfaces, interface)) + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + else + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + + return bus_send_error_reply(m, c, message, &error, -EINVAL); + } + + } else if (!nulstr_contains(interfaces, dbus_message_get_interface(message))) { + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + return bus_send_error_reply(m, c, message, &error, -EINVAL); } if (reply) { diff --git a/src/dbus.h b/src/dbus.h index 2aaeb4745..f93ad6203 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -32,6 +32,14 @@ #define DBUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface" #endif +#ifndef DBUS_ERROR_UNKNOWN_PROPERTY +#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty" +#endif + +#ifndef DBUS_ERROR_PROPERTY_READ_ONLY +#define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly" +#endif + #include "manager.h" typedef int (*BusPropertyCallback)(Manager *m, DBusMessageIter *iter, const char *property, void *data); @@ -84,6 +92,11 @@ typedef struct BusProperty { " \n" \ "\n" +#define BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.DBus.Properties\0" \ + "org.freedesktop.DBus.Introspectable\0" \ + "org.freedesktop.DBus.Peer\0" + int bus_init(Manager *m, bool try_bus_connect); void bus_done(Manager *m); @@ -94,7 +107,7 @@ void bus_timeout_event(Manager *m, Watch *w, int events); int bus_query_pid(Manager *m, const char *name); -DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char* introspection, const BusProperty *properties); +DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char* introspection, const char *interfaces, const BusProperty *properties); DBusHandlerResult bus_send_error_reply(Manager *m, DBusConnection *c, DBusMessage *message, DBusError *bus_error, int error); int bus_broadcast(Manager *m, DBusMessage *message); diff --git a/src/util.c b/src/util.c index 4acb3c305..c02b39e0a 100644 --- a/src/util.c +++ b/src/util.c @@ -4079,6 +4079,19 @@ int kill_and_sigcont(pid_t pid, int sig) { return r; } +bool nulstr_contains(const char*nulstr, const char *needle) { + const char *i; + + if (!nulstr) + return false; + + NULSTR_FOREACH(i, nulstr) + if (streq(i, needle)) + return true; + + return false; +} + 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 a2e3b9443..13e5f6203 100644 --- a/src/util.h +++ b/src/util.h @@ -386,6 +386,8 @@ void execute_directory(const char *directory, DIR *_d, char *argv[]); int kill_and_sigcont(pid_t pid, int sig); +bool nulstr_contains(const char*nulstr, const char *needle); + #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) From b8a021c9e276adc9bed5ebfa39c3cab0077113c6 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Wed, 9 Mar 2011 20:03:29 +0100 Subject: [PATCH 004/200] dbus: fix dbus assert due to uninitialized error Add missing dbus_error_init() in UNKNOWN_OBJECT case. Fixes assertion systemd[1]: Caught , dumped core as pid 6256. systemd[1]: Freezing execution. Core was generated by `/bin/systemd systemd.unit=graphical.target'. Program terminated with signal 6, Aborted. #0 0x00007f8966ec81db in raise () from /lib64/libpthread.so.0 (gdb) bt #0 0x00007f8966ec81db in raise () from /lib64/libpthread.so.0 #1 0x000000000040823b in crash (sig=6) at src/main.c:120 #2 #3 0x00007f896613c075 in raise () from /lib64/libc.so.6 #4 0x00007f896613d806 in abort () from /lib64/libc.so.6 #5 0x00007f89672ac8a5 in _dbus_abort () at dbus-sysdeps.c:94 #6 0x00007f89672a37b5 in _dbus_warn_check_failed ( format=0x7f89672b35d8 "arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\nThis is normally a bug in some application using the D-Bus library.\n") at dbus-internals.c:289 #7 0x0000000000441500 in bus_unit_message_handler (connection=0x21b6090, message=0x21b6760, data=0x1f3e870) at src/dbus-unit.c:572 #8 0x00007f8967299f11 in _dbus_object_tree_dispatch_and_unlock ( tree=0x219d660, message=0x21b6760) at dbus-object-tree.c:858 #9 0x00007f896728bca2 in dbus_connection_dispatch (connection=0x21b6090) at dbus-connection.c:4688 #10 0x000000000043befa in bus_dispatch (m=0x1f3e870) at src/dbus.c:547 #11 0x000000000041056d in manager_loop (m=0x1f3e870) at src/manager.c:2344 #12 0x0000000000409515 in main (argc=, argv=) at src/main.c:1229 --- src/dbus-job.c | 2 ++ src/dbus-unit.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/dbus-job.c b/src/dbus-job.c index b66d23604..908ddba53 100644 --- a/src/dbus-job.c +++ b/src/dbus-job.c @@ -198,6 +198,8 @@ static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBu if (r == -ENOENT) { DBusError e; + + dbus_error_init(&e); dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown job"); return bus_send_error_reply(m, connection, message, &e, r); } diff --git a/src/dbus-unit.c b/src/dbus-unit.c index 52e8599e7..563ef7079 100644 --- a/src/dbus-unit.c +++ b/src/dbus-unit.c @@ -568,6 +568,8 @@ static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DB if (r == -ENOENT) { DBusError e; + + dbus_error_init(&e); dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown unit"); return bus_send_error_reply(m, connection, message, &e, r); } From 2e60ecb2f760936552f9d6db32d6ecf828b3c322 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 20:12:30 +0100 Subject: [PATCH 005/200] selinux: bump up error level when in non-enforcing mode --- TODO | 6 ------ src/selinux-setup.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/TODO b/TODO index 237ba7b2a..8395d692b 100644 --- a/TODO +++ b/TODO @@ -6,8 +6,6 @@ F15: * isolate multi-user.target doesn't start a getty@tty1 if we run it from graphical.target -* finish syslog socket stuff - * NFS, networkmanager ordering issue * add fstab fields to add wait timeouts, change Wants to Requires by local-fs.target @@ -16,10 +14,6 @@ F15: * mount /dev/.run and /var/run as bind mounts -* Make use of UnknownInterface - -* support chkconfig without forwarding to systemctl to facilitate upgrades - * drop SIGHUP handling from rsyslog.service upstream * teach dbus to activate all services it finds in /etc/systemd/services/org-*.service diff --git a/src/selinux-setup.c b/src/selinux-setup.c index b2beb33d1..8bd938077 100644 --- a/src/selinux-setup.c +++ b/src/selinux-setup.c @@ -59,7 +59,7 @@ int selinux_setup(char *const argv[]) { return -errno; } else { - log_full(enforce > 0 ? LOG_ERR : LOG_DEBUG, "Failed to load SELinux policy."); + log_full(enforce > 0 ? LOG_ERR : LOG_WARNING, "Failed to load SELinux policy."); unlink("/dev/.systemd/relabel-devtmpfs"); From 607df95be184308b6bb7a5534f04109c67c039c3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 20:15:44 +0100 Subject: [PATCH 006/200] pkconfig: export full search path as .pc variable --- src/path-lookup.c | 2 ++ systemd.pc.in | 1 + 2 files changed, 3 insertions(+) diff --git a/src/path-lookup.c b/src/path-lookup.c index f094969ad..1a21ca078 100644 --- a/src/path-lookup.c +++ b/src/path-lookup.c @@ -181,6 +181,8 @@ int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as) { return -ENOMEM; } else if (!(p->unit_path = strv_new( + /* If you modify this you also want to modify + * systemdsystemunitpath= in systemd.pc.in! */ "/dev/.systemd/system", SYSTEM_CONFIG_UNIT_PATH, "/etc/systemd/system", diff --git a/systemd.pc.in b/systemd.pc.in index 204991309..e939293a4 100644 --- a/systemd.pc.in +++ b/systemd.pc.in @@ -11,6 +11,7 @@ systemdsystemunitdir=@systemunitdir@ systemduserunitdir=@pkgdatadir@/user systemdsystemconfdir=@pkgsysconfdir@/system systemduserconfdir=@pkgsysconfdir@/user +systemdsystemunitpath=/dev/.systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/share/systemd/system:/lib/systemd/system:${systemdsystemunitdir} Name: systemd Description: systemd System and Service Manager From 29d958ce2ba49794fa92dd77b2f9a9bdc941f493 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 22:13:24 +0100 Subject: [PATCH 007/200] machine-id: move machine-id-setup to /sbin --- Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 4caa2433b..f867624f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -105,7 +105,9 @@ rootbin_PROGRAMS = \ systemd-notify \ systemd-ask-password \ systemd-tty-ask-password-agent \ - systemd-tmpfiles \ + systemd-tmpfiles + +rootsbin_PROGRAMS = \ systemd-machine-id-setup bin_PROGRAMS = \ From b925e72633bf98438f56a140520e07ec8c959e46 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 22:45:47 +0100 Subject: [PATCH 008/200] dev: use /dev/.run/systemd as runtime directory, instead of /dev/.systemd --- TODO | 4 ++++ man/sd_readahead.xml | 2 +- src/ask-password-api.c | 6 +++--- src/fsck.c | 2 +- src/gnome-ask-password-agent.vala | 2 +- src/machine-id-setup.c | 14 +++++++------- src/main.c | 4 +--- src/manager.c | 18 ++++++++---------- src/mount-setup.c | 6 +++++- src/path-lookup.c | 2 +- src/quotacheck.c | 2 +- src/readahead-collect.c | 4 ++-- src/readahead-common.c | 14 +++++++------- src/readahead-replay.c | 2 +- src/sd-readahead.c | 10 +++++----- src/selinux-setup.c | 5 ++--- src/tty-ask-password-agent.c | 12 ++++++------ systemd.pc.in | 2 +- units/systemd-ask-password-console.path | 2 +- units/systemd-ask-password-plymouth.path | 2 +- units/systemd-ask-password-wall.path | 2 +- 21 files changed, 60 insertions(+), 57 deletions(-) diff --git a/TODO b/TODO index 8395d692b..a8b879780 100644 --- a/TODO +++ b/TODO @@ -20,10 +20,14 @@ F15: * save/restore tool for SysV as requested by FPC +* optionally create watched directories in .path units + Features: * consider services with no [Install] section and stored in /lib enabled by "systemctl is-enabled" +* store time when conditions where checked to inform admins about whether a unit was considered at all + * consider services with any kind of link in /etc/systemd/system enabled * show failure error string in "systemctl status" diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml index ac54dc48f..f5114e49a 100644 --- a/man/sd_readahead.xml +++ b/man/sd_readahead.xml @@ -123,7 +123,7 @@ reference implementation. Internally, this function creates a file in - /dev/.systemd/readahead/ which is + /dev/.run/systemd/readahead/ which is then used as flag file to notify the read-ahead subsystem. diff --git a/src/ask-password-api.c b/src/ask-password-api.c index af1b611f2..0b2e9ad84 100644 --- a/src/ask-password-api.c +++ b/src/ask-password-api.c @@ -223,7 +223,7 @@ static int create_socket(char **name) { zero(sa); sa.un.sun_family = AF_UNIX; - snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/dev/.systemd/ask-password/sck.%llu", random_ull()); + snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/dev/.run/systemd/ask-password/sck.%llu", random_ull()); if (bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { r = -errno; @@ -265,7 +265,7 @@ int ask_password_agent( _FD_MAX }; - char temp[] = "/dev/.systemd/ask-password/tmp.XXXXXX"; + char temp[] = "/dev/.run/systemd/ask-password/tmp.XXXXXX"; char final[sizeof(temp)] = ""; int fd = -1, r; FILE *f = NULL; @@ -276,7 +276,7 @@ int ask_password_agent( assert(_passphrases); - mkdir_p("/dev/.systemd/ask-password", 0755); + mkdir_p("/dev/.run/systemd/ask-password", 0755); if ((fd = mkostemp(temp, O_CLOEXEC|O_CREAT|O_WRONLY)) < 0) { log_error("Failed to create password file: %m"); diff --git a/src/fsck.c b/src/fsck.c index dbfb47517..b5d8764e0 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -262,7 +262,7 @@ int main(int argc, char *argv[]) { r = EXIT_SUCCESS; if (status.si_code == CLD_EXITED && (status.si_status & 1)) - touch("/dev/.systemd/quotacheck"); + touch("/dev/.run/systemd/quotacheck"); finish: if (udev_device) diff --git a/src/gnome-ask-password-agent.vala b/src/gnome-ask-password-agent.vala index 84f254973..1bc97f548 100644 --- a/src/gnome-ask-password-agent.vala +++ b/src/gnome-ask-password-agent.vala @@ -91,7 +91,7 @@ public class MyStatusIcon : StatusIcon { GLib.Object(icon_name : "dialog-password"); set_title("System Password"); - directory = File.new_for_path("/dev/.systemd/ask-password/"); + directory = File.new_for_path("/dev/.run/systemd/ask-password/"); file_monitor = directory.monitor_directory(0); file_monitor.changed.connect(file_monitor_changed); diff --git a/src/machine-id-setup.c b/src/machine-id-setup.c index 65792e9b8..59a14249e 100644 --- a/src/machine-id-setup.c +++ b/src/machine-id-setup.c @@ -142,20 +142,20 @@ int machine_id_setup(void) { fd = -1; /* Hmm, we couldn't write it? So let's write it to - * /dev/.systemd/machine-id as a replacement */ + * /dev/.run/systemd/machine-id as a replacement */ - mkdir_p("/dev/.systemd", 0755); + mkdir_p("/dev/.run/systemd", 0755); - if ((r = write_one_line_file("/dev/.systemd/machine-id", id)) < 0) { - log_error("Cannot write /dev/.systemd/machine-id: %s", strerror(-r)); + if ((r = write_one_line_file("/dev/.run/systemd/machine-id", id)) < 0) { + log_error("Cannot write /dev/.run/systemd/machine-id: %s", strerror(-r)); - unlink("/dev/.systemd/machine-id"); + unlink("/dev/.run/systemd/machine-id"); goto finish; } /* And now, let's mount it over */ - r = mount("/dev/.systemd/machine-id", "/etc/machine-id", "bind", MS_BIND|MS_RDONLY, NULL) < 0 ? -errno : 0; - unlink("/dev/.systemd/machine-id"); + r = mount("/dev/.run/systemd/machine-id", "/etc/machine-id", "bind", MS_BIND|MS_RDONLY, NULL) < 0 ? -errno : 0; + unlink("/dev/.run/systemd/machine-id"); if (r < 0) log_error("Failed to mount /etc/machine-id: %s", strerror(-r)); diff --git a/src/main.c b/src/main.c index a041a22ed..37768c67a 100644 --- a/src/main.c +++ b/src/main.c @@ -1044,7 +1044,7 @@ int main(int argc, char *argv[]) { /* If Plymouth is being run make sure we show the status, so * that there's something nice to see when people press Esc */ - if (access("/dev/.systemd/plymouth", F_OK) >= 0) + if (access("/dev/.run/systemd/plymouth", F_OK) >= 0) arg_show_status = true; if (arg_action == ACTION_HELP) { @@ -1131,8 +1131,6 @@ int main(int argc, char *argv[]) { machine_id_setup(); loopback_setup(); - mkdir_p("/dev/.systemd/ask-password/", 0755); - test_mtab(); test_usr(); } diff --git a/src/manager.c b/src/manager.c index 194ad66a0..8bbde7c38 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2550,22 +2550,20 @@ void manager_dispatch_bus_query_pid_done( } int manager_open_serialization(Manager *m, FILE **_f) { - char *path; + char *path = NULL; mode_t saved_umask; int fd; FILE *f; assert(_f); - if (m->running_as == MANAGER_SYSTEM) { - mkdir_p("/dev/.systemd", 0755); + if (m->running_as == MANAGER_SYSTEM) + asprintf(&path, "/dev/.run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid()); + else + asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid()); - if (asprintf(&path, "/dev/.systemd/dump-%lu-XXXXXX", (unsigned long) getpid()) < 0) - return -ENOMEM; - } else { - if (asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid()) < 0) - return -ENOMEM; - } + if (!path) + return -ENOMEM; saved_umask = umask(0077); fd = mkostemp(path, O_RDWR|O_CLOEXEC); @@ -2862,7 +2860,7 @@ void manager_run_generators(Manager *m) { if (!m->generator_unit_path) { char *p; - char system_path[] = "/dev/.systemd/generator-XXXXXX", + char system_path[] = "/dev/.run/systemd/generator-XXXXXX", user_path[] = "/tmp/systemd-generator-XXXXXX"; if (!(p = mkdtemp(m->running_as == MANAGER_SYSTEM ? system_path : user_path))) { diff --git a/src/mount-setup.c b/src/mount-setup.c index 09ee07f82..d740d4f35 100644 --- a/src/mount-setup.c +++ b/src/mount-setup.c @@ -242,7 +242,7 @@ int mount_setup(void) { * appropriate labels, after mounting. The other virtual API * file systems do not need. */ - if (unlink("/dev/.systemd/relabel-devtmpfs") >= 0) + 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 @@ -252,5 +252,9 @@ int mount_setup(void) { NULSTR_FOREACH_PAIR(j, k, symlinks) symlink_and_label(j, k); + /* Create a few directories we always want around */ + mkdir("/dev/.run/systemd", 0755); + mkdir("/dev/.run/systemd/ask-password", 0755); + return mount_cgroup_controllers(); } diff --git a/src/path-lookup.c b/src/path-lookup.c index 1a21ca078..922e722e1 100644 --- a/src/path-lookup.c +++ b/src/path-lookup.c @@ -183,7 +183,7 @@ int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as) { if (!(p->unit_path = strv_new( /* If you modify this you also want to modify * systemdsystemunitpath= in systemd.pc.in! */ - "/dev/.systemd/system", + "/dev/.run/systemd/system", SYSTEM_CONFIG_UNIT_PATH, "/etc/systemd/system", "/usr/local/share/systemd/system", diff --git a/src/quotacheck.c b/src/quotacheck.c index 5ced93318..55c2f0c6d 100644 --- a/src/quotacheck.c +++ b/src/quotacheck.c @@ -94,7 +94,7 @@ int main(int argc, char *argv[]) { if (arg_skip) return 0; - if (access("/dev/.systemd/quotacheck", F_OK) < 0) + if (access("/dev/.run/systemd/quotacheck", F_OK) < 0) return 0; } diff --git a/src/readahead-collect.c b/src/readahead-collect.c index 0970b5841..ca8227135 100644 --- a/src/readahead-collect.c +++ b/src/readahead-collect.c @@ -289,13 +289,13 @@ static int collect(const char *root) { log_debug("Collecting..."); - if (access("/dev/.systemd/readahead/cancel", F_OK) >= 0) { + if (access("/dev/.run/systemd/readahead/cancel", F_OK) >= 0) { log_debug("Collection canceled"); r = -ECANCELED; goto finish; } - if (access("/dev/.systemd/readahead/done", F_OK) >= 0) { + if (access("/dev/.run/systemd/readahead/done", F_OK) >= 0) { log_debug("Got termination request"); goto done; } diff --git a/src/readahead-common.c b/src/readahead-common.c index e991dfd05..990ffd4d0 100644 --- a/src/readahead-common.c +++ b/src/readahead-common.c @@ -167,11 +167,11 @@ int open_inotify(void) { return -errno; } - mkdir("/dev/.systemd", 0755); - mkdir("/dev/.systemd/readahead", 0755); + mkdir("/dev/.run/systemd", 0755); + mkdir("/dev/.run/systemd/readahead", 0755); - if (inotify_add_watch(fd, "/dev/.systemd/readahead", IN_CREATE) < 0) { - log_error("Failed to watch /dev/.systemd/readahead: %m"); + if (inotify_add_watch(fd, "/dev/.run/systemd/readahead", IN_CREATE) < 0) { + log_error("Failed to watch /dev/.run/systemd/readahead: %m"); close_nointr_nofail(fd); return -errno; } @@ -183,10 +183,10 @@ ReadaheadShared *shared_get(void) { int fd; ReadaheadShared *m = NULL; - mkdir("/dev/.systemd", 0755); - mkdir("/dev/.systemd/readahead", 0755); + mkdir("/dev/.run/systemd", 0755); + mkdir("/dev/.run/systemd/readahead", 0755); - if ((fd = open("/dev/.systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) { + if ((fd = open("/dev/.run/systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) { log_error("Failed to create shared memory segment: %m"); goto finish; } diff --git a/src/readahead-replay.c b/src/readahead-replay.c index 3bea9295f..d2de7ef28 100644 --- a/src/readahead-replay.c +++ b/src/readahead-replay.c @@ -192,7 +192,7 @@ static int replay(const char *root) { log_debug("Replaying..."); - if (access("/dev/.systemd/readahead/noreplay", F_OK) >= 0) { + if (access("/dev/.run/systemd/readahead/noreplay", F_OK) >= 0) { log_debug("Got termination request"); goto done; } diff --git a/src/sd-readahead.c b/src/sd-readahead.c index 41e6d3d20..0dfe4abab 100644 --- a/src/sd-readahead.c +++ b/src/sd-readahead.c @@ -42,8 +42,8 @@ static int touch(const char *path) { #if !defined(DISABLE_SYSTEMD) && defined(__linux__) int fd; - mkdir("/dev/.systemd", 0755); - mkdir("/dev/.systemd/readahead", 0755); + mkdir("/dev/.run/systemd", 0755); + mkdir("/dev/.run/systemd/readahead", 0755); if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666)) < 0) return -errno; @@ -66,11 +66,11 @@ int sd_readahead(const char *action) { return -EINVAL; if (strcmp(action, "cancel") == 0) - return touch("/dev/.systemd/readahead/cancel"); + return touch("/dev/.run/systemd/readahead/cancel"); else if (strcmp(action, "done") == 0) - return touch("/dev/.systemd/readahead/done"); + return touch("/dev/.run/systemd/readahead/done"); else if (strcmp(action, "noreplay") == 0) - return touch("/dev/.systemd/readahead/noreplay"); + return touch("/dev/.run/systemd/readahead/noreplay"); return -EINVAL; } diff --git a/src/selinux-setup.c b/src/selinux-setup.c index 8bd938077..e21ff6bb9 100644 --- a/src/selinux-setup.c +++ b/src/selinux-setup.c @@ -45,8 +45,7 @@ int selinux_setup(char *const argv[]) { /* 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"); + touch("/dev/.systemd-relabel-devtmpfs"); if (selinux_init_load_policy(&enforce) == 0) { log_debug("Successfully loaded SELinux policy, reexecuting."); @@ -61,7 +60,7 @@ int selinux_setup(char *const argv[]) { } else { log_full(enforce > 0 ? LOG_ERR : LOG_WARNING, "Failed to load SELinux policy."); - unlink("/dev/.systemd/relabel-devtmpfs"); + unlink("/dev/.systemd-relabel-devtmpfs"); if (enforce > 0) return -EIO; diff --git a/src/tty-ask-password-agent.c b/src/tty-ask-password-agent.c index 35e4d63a8..2c854fa8d 100644 --- a/src/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent.c @@ -431,7 +431,7 @@ static int wall_tty_block(void) { if ((r = get_ctty_devnr(&devnr)) < 0) return -r; - if (asprintf(&p, "/dev/.systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0) + if (asprintf(&p, "/dev/.run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0) return -ENOMEM; mkdir_parents(p, 0700); @@ -475,7 +475,7 @@ static bool wall_tty_match(const char *path) { * advantage that the block will automatically go away if the * process dies. */ - if (asprintf(&p, "/dev/.systemd/ask-password-block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0) + if (asprintf(&p, "/dev/.run/systemd/ask-password-block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0) return true; fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); @@ -494,7 +494,7 @@ static int show_passwords(void) { struct dirent *de; int r = 0; - if (!(d = opendir("/dev/.systemd/ask-password"))) { + if (!(d = opendir("/dev/.run/systemd/ask-password"))) { if (errno == ENOENT) return 0; @@ -519,7 +519,7 @@ static int show_passwords(void) { if (!startswith(de->d_name, "ask.")) continue; - if (!(p = strappend("/dev/.systemd/ask-password/", de->d_name))) { + if (!(p = strappend("/dev/.run/systemd/ask-password/", de->d_name))) { log_error("Out of memory"); r = -ENOMEM; goto finish; @@ -558,14 +558,14 @@ static int watch_passwords(void) { tty_block_fd = wall_tty_block(); - mkdir_p("/dev/.systemd/ask-password", 0755); + mkdir_p("/dev/.run/systemd/ask-password", 0755); if ((notify = inotify_init1(IN_CLOEXEC)) < 0) { r = -errno; goto finish; } - if (inotify_add_watch(notify, "/dev/.systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) { + if (inotify_add_watch(notify, "/dev/.run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) { r = -errno; goto finish; } diff --git a/systemd.pc.in b/systemd.pc.in index e939293a4..f962b58d9 100644 --- a/systemd.pc.in +++ b/systemd.pc.in @@ -11,7 +11,7 @@ systemdsystemunitdir=@systemunitdir@ systemduserunitdir=@pkgdatadir@/user systemdsystemconfdir=@pkgsysconfdir@/system systemduserconfdir=@pkgsysconfdir@/user -systemdsystemunitpath=/dev/.systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/share/systemd/system:/lib/systemd/system:${systemdsystemunitdir} +systemdsystemunitpath=/dev/.run/systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/share/systemd/system:/lib/systemd/system:${systemdsystemunitdir} Name: systemd Description: systemd System and Service Manager diff --git a/units/systemd-ask-password-console.path b/units/systemd-ask-password-console.path index 9d3d80d5a..ac76fc170 100644 --- a/units/systemd-ask-password-console.path +++ b/units/systemd-ask-password-console.path @@ -12,4 +12,4 @@ Conflicts=shutdown.target Before=basic.target shutdown.target [Path] -DirectoryNotEmpty=/dev/.systemd/ask-password +DirectoryNotEmpty=/dev/.run/systemd/ask-password diff --git a/units/systemd-ask-password-plymouth.path b/units/systemd-ask-password-plymouth.path index 1d09223f7..b339b5e26 100644 --- a/units/systemd-ask-password-plymouth.path +++ b/units/systemd-ask-password-plymouth.path @@ -12,4 +12,4 @@ Conflicts=shutdown.target systemd-ask-password-console.path systemd-ask-password Before=basic.target shutdown.target [Path] -DirectoryNotEmpty=/dev/.systemd/ask-password +DirectoryNotEmpty=/dev/.run/systemd/ask-password diff --git a/units/systemd-ask-password-wall.path b/units/systemd-ask-password-wall.path index 9c4b1d3d2..c277563b7 100644 --- a/units/systemd-ask-password-wall.path +++ b/units/systemd-ask-password-wall.path @@ -12,4 +12,4 @@ Conflicts=shutdown.target Before=basic.target shutdown.target [Path] -DirectoryNotEmpty=/dev/.systemd/ask-password +DirectoryNotEmpty=/dev/.run/systemd/ask-password From 90bbc9469ec29b6094dadf27aa88743d44ab56e7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 23:58:17 +0100 Subject: [PATCH 009/200] condition: take a timestamp and store last result of conditions --- TODO | 2 -- src/dbus-unit.h | 14 +++++++++----- src/systemctl.c | 17 +++++++++++++++++ src/unit.c | 11 ++++++++++- src/unit.h | 7 +++++++ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index a8b879780..935978216 100644 --- a/TODO +++ b/TODO @@ -26,8 +26,6 @@ Features: * consider services with no [Install] section and stored in /lib enabled by "systemctl is-enabled" -* store time when conditions where checked to inform admins about whether a unit was considered at all - * consider services with any kind of link in /etc/systemd/system enabled * show failure error string in "systemctl status" diff --git a/src/dbus-unit.h b/src/dbus-unit.h index 4e46fc482..efb61797f 100644 --- a/src/dbus-unit.h +++ b/src/dbus-unit.h @@ -102,6 +102,8 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ " \n" #define BUS_UNIT_INTERFACES_LIST \ @@ -132,10 +134,10 @@ { "org.freedesktop.systemd1.Unit", "ActiveState", bus_unit_append_active_state, "s", u }, \ { "org.freedesktop.systemd1.Unit", "SubState", bus_unit_append_sub_state, "s", u }, \ { "org.freedesktop.systemd1.Unit", "FragmentPath", bus_property_append_string, "s", u->meta.fragment_path }, \ - { "org.freedesktop.systemd1.Unit", "InactiveExitTimestamp",bus_property_append_uint64, "t", &u->meta.inactive_exit_timestamp.realtime }, \ - { "org.freedesktop.systemd1.Unit", "ActiveEnterTimestamp", bus_property_append_uint64, "t", &u->meta.active_enter_timestamp.realtime }, \ - { "org.freedesktop.systemd1.Unit", "ActiveExitTimestamp", bus_property_append_uint64, "t", &u->meta.active_exit_timestamp.realtime }, \ - { "org.freedesktop.systemd1.Unit", "InactiveEnterTimestamp",bus_property_append_uint64, "t", &u->meta.inactive_enter_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "InactiveExitTimestamp",bus_property_append_usec, "t", &u->meta.inactive_exit_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "ActiveEnterTimestamp", bus_property_append_usec, "t", &u->meta.active_enter_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "ActiveExitTimestamp", bus_property_append_usec, "t", &u->meta.active_exit_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "InactiveEnterTimestamp",bus_property_append_usec, "t", &u->meta.inactive_enter_timestamp.realtime }, \ { "org.freedesktop.systemd1.Unit", "CanStart", bus_unit_append_can_start, "b", u }, \ { "org.freedesktop.systemd1.Unit", "CanStop", bus_unit_append_can_stop, "b", u }, \ { "org.freedesktop.systemd1.Unit", "CanReload", bus_unit_append_can_reload, "b", u }, \ @@ -149,7 +151,9 @@ { "org.freedesktop.systemd1.Unit", "DefaultControlGroup", bus_unit_append_default_cgroup, "s", u }, \ { "org.freedesktop.systemd1.Unit", "ControlGroup", bus_unit_append_cgroups, "as", u }, \ { "org.freedesktop.systemd1.Unit", "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", u }, \ - { "org.freedesktop.systemd1.Unit", "JobTimeoutUSec", bus_property_append_usec, "t", &u->meta.job_timeout } + { "org.freedesktop.systemd1.Unit", "JobTimeoutUSec", bus_property_append_usec, "t", &u->meta.job_timeout }, \ + { "org.freedesktop.systemd1.Unit", "ConditionTimestamp", bus_property_append_usec, "t", &u->meta.condition_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "ConditionResult", bus_property_append_bool, "b", &u->meta.condition_result } int bus_unit_append_names(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_unit_append_following(Manager *m, DBusMessageIter *i, const char *property, void *data); diff --git a/src/systemctl.c b/src/systemctl.c index 63e74d904..5b205fec5 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -1831,6 +1831,9 @@ typedef struct UnitStatusInfo { int exit_code, exit_status; + usec_t condition_timestamp; + bool condition_result; + /* Socket */ unsigned n_accepted; unsigned n_connections; @@ -1922,6 +1925,16 @@ static void print_status_info(UnitStatusInfo *i) { else printf("\n"); + if (!i->condition_result && i->condition_timestamp > 0) { + s1 = format_timestamp_pretty(since1, sizeof(since1), i->condition_timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); + + if (s1) + printf("\t start condition failed at %s; %s\n", s2, s1); + else if (s2) + printf("\t start condition failed at %s\n", s2); + } + if (i->sysfs_path) printf("\t Device: %s\n", i->sysfs_path); if (i->where) @@ -2117,6 +2130,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->accept = b; else if (streq(name, "NeedDaemonReload")) i->need_daemon_reload = b; + else if (streq(name, "ConditionResult")) + i->condition_result = b; break; } @@ -2174,6 +2189,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->inactive_exit_timestamp = (usec_t) u; else if (streq(name, "ActiveExitTimestamp")) i->active_exit_timestamp = (usec_t) u; + else if (streq(name, "ConditionTimestamp")) + i->condition_timestamp = (usec_t) u; break; } diff --git a/src/unit.c b/src/unit.c index 450b190c0..117af4df4 100644 --- a/src/unit.c +++ b/src/unit.c @@ -825,6 +825,15 @@ fail: return r; } +bool unit_condition_test(Unit *u) { + assert(u); + + dual_timestamp_get(&u->meta.condition_timestamp); + u->meta.condition_result = condition_test_list(u->meta.conditions); + + return u->meta.condition_result; +} + /* Errors: * -EBADR: This unit type does not support starting. * -EALREADY: Unit is already started. @@ -849,7 +858,7 @@ int unit_start(Unit *u) { return -EALREADY; /* If the conditions failed, don't do anything at all */ - if (!condition_test_list(u->meta.conditions)) { + if (!unit_condition_test(u)) { log_debug("Starting of %s requested but condition failed. Ignoring.", u->meta.id); return -EALREADY; } diff --git a/src/unit.h b/src/unit.h index 5f55a89da..9b7eb5e85 100644 --- a/src/unit.h +++ b/src/unit.h @@ -160,6 +160,8 @@ struct Meta { /* Conditions to check */ LIST_HEAD(Condition, conditions); + dual_timestamp condition_timestamp; + dual_timestamp inactive_exit_timestamp; dual_timestamp active_enter_timestamp; dual_timestamp active_exit_timestamp; @@ -208,6 +210,9 @@ struct Meta { /* Allow isolation requests */ bool allow_isolate; + /* Did the last condition check suceed? */ + bool condition_result; + bool in_load_queue:1; bool in_dbus_queue:1; bool in_cleanup_queue:1; @@ -513,6 +518,8 @@ bool unit_name_is_valid(const char *n, bool template_ok); void unit_trigger_on_failure(Unit *u); +bool unit_condition_test(Unit *u); + const char *unit_load_state_to_string(UnitLoadState i); UnitLoadState unit_load_state_from_string(const char *s); From b0c8757b056c18863d2f9c07ca3ba21f64a47b54 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 23:59:07 +0100 Subject: [PATCH 010/200] main: don't check if /usr really is a mount point, since it is fine if it is passed pre-mounted to us from the initrd --- src/main.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index 37768c67a..769fc6772 100644 --- a/src/main.c +++ b/src/main.c @@ -942,25 +942,13 @@ static void test_mtab(void) { } static void test_usr(void) { - bool separate = false; /* Check that /usr is not a separate fs */ - if (path_is_mount_point("/usr") > 0) - separate = true; - /* This check won't work usually during boot, since /usr is - * probably not mounted yet, hence let's add a second - * check. We just check whether /usr is an empty directory. */ - if (dir_is_empty("/usr") > 0) - separate = true; - - if (!separate) - return; - - log_warning("/usr appears to be on a different file system than /. This is not supported anymore. " - "Some things will probably break (sometimes even silently) in mysterious ways. " - "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information."); + log_warning("/usr appears to be on a different file system than /. This is not supported anymore. " + "Some things will probably break (sometimes even silently) in mysterious ways. " + "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information."); } int main(int argc, char *argv[]) { From fe783b03419181bed69003ffdd73132426de246a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 23:59:27 +0100 Subject: [PATCH 011/200] main: refuse system to be started in a chroot --- src/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 769fc6772..6d1fd7d55 100644 --- a/src/main.c +++ b/src/main.c @@ -1030,9 +1030,16 @@ int main(int argc, char *argv[]) { goto finish; } + if (arg_running_as == MANAGER_SYSTEM && + arg_action == ACTION_RUN && + running_in_chroot() > 0) { + log_error("Cannot be run in a chroot() environment."); + goto finish; + } + /* If Plymouth is being run make sure we show the status, so * that there's something nice to see when people press Esc */ - if (access("/dev/.run/systemd/plymouth", F_OK) >= 0) + if (access("/dev/.systemd/plymouth", F_OK) >= 0) arg_show_status = true; if (arg_action == ACTION_HELP) { From 756a8d17bb106f9624736843377e7831b195fac7 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 10 Mar 2011 20:31:18 +0300 Subject: [PATCH 012/200] man: trivial typo in systemd(1) --- man/systemd.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd.xml b/man/systemd.xml index 2c42a0291..6b1a4c9d9 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -269,7 +269,7 @@ , , , - . If the + . If the argument is omitted it defaults to . From 90102b22ba0a9a6aa8ff1b9d32349e100902a8d7 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 10 Mar 2011 17:39:02 +0300 Subject: [PATCH 013/200] pam: do not leak file descriptor if flock fails If flock fails, fd is not returned to caller so it cannot clean up. --- src/pam-module.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pam-module.c b/src/pam-module.c index 7f9158470..e1a1a5001 100644 --- a/src/pam-module.c +++ b/src/pam-module.c @@ -198,8 +198,12 @@ static int open_file_and_lock(const char *fn) { * as the filesystems in question should be local, and only * locally accessible, and most likely even tmpfs. */ - if (flock(fd, LOCK_EX) < 0) - return -errno; + if (flock(fd, LOCK_EX) < 0) { + int r = -errno; + + close_nointr_nofail(fd); + return r; + } return fd; } From 099663ff8c117303af369a4d412dafed0c5614c2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 10 Mar 2011 23:01:42 +0100 Subject: [PATCH 014/200] main: properly handle -b boot option --- TODO | 8 +++++++- src/main.c | 24 ++++++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 935978216..f2e3be416 100644 --- a/TODO +++ b/TODO @@ -20,10 +20,16 @@ F15: * save/restore tool for SysV as requested by FPC -* optionally create watched directories in .path units +* bind mounts are ignored + +* SIGALRM in systemctl + +* 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown Features: +* optionally create watched directories in .path units + * consider services with no [Install] section and stored in /lib enabled by "systemctl is-enabled" * consider services with any kind of link in /etc/systemd/system enabled diff --git a/src/main.c b/src/main.c index 6d1fd7d55..5d37f804d 100644 --- a/src/main.c +++ b/src/main.c @@ -226,6 +226,8 @@ static int parse_proc_cmdline_word(const char *word) { static const char * const rlmap[] = { "emergency", SPECIAL_EMERGENCY_TARGET, + "-b", SPECIAL_EMERGENCY_TARGET, + "b", SPECIAL_EMERGENCY_TARGET, "single", SPECIAL_RESCUE_TARGET, "-s", SPECIAL_RESCUE_TARGET, "s", SPECIAL_RESCUE_TARGET, @@ -624,7 +626,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 1); assert(argv); - while ((c = getopt_long(argc, argv, "hD", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0) switch (c) { @@ -800,19 +802,29 @@ static int parse_argv(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); break; - case '?': - return -EINVAL; + case 'b': + case 's': + case 'z': + /* Just to eat away the sysvinit kernel + * cmdline args without getopt() error + * messages that we'll parse in + * parse_proc_cmdline_word() or ignore. */ + case '?': default: - log_error("Unknown option code %c", c); - return -EINVAL; + if (getpid() != 1) { + log_error("Unknown option code %c", c); + return -EINVAL; + } + + break; } /* PID 1 will get the kernel arguments as parameters, which we * ignore and unconditionally read from * /proc/cmdline. However, we need to ignore those arguments * here. */ - if (arg_running_as != MANAGER_SYSTEM && optind < argc) { + if (getpid() != 1 && optind < argc) { log_error("Excess arguments."); return -EINVAL; } From b997812119882f95a9456ce15667b0545be8e417 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Mar 2011 00:45:06 +0100 Subject: [PATCH 015/200] dbus: timeout connection setup --- src/dbus-common.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/dbus-common.c b/src/dbus-common.c index 69593cd18..80b2115e1 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -27,6 +27,7 @@ #include "log.h" #include "dbus-common.h" +#include "util.h" int bus_check_peercred(DBusConnection *c) { int fd; @@ -59,19 +60,54 @@ int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private, DBusError * assert(_bus); +#define TIMEOUT_USEC (60*USEC_PER_SEC) + /* If we are root, then let's not go via the bus */ if (geteuid() == 0 && t == DBUS_BUS_SYSTEM) { + usec_t begin, tstamp; if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", error))) return -EIO; if (bus_check_peercred(bus) < 0) { + dbus_connection_close(bus); dbus_connection_unref(bus); dbus_set_error_const(error, DBUS_ERROR_ACCESS_DENIED, "Failed to verify owner of bus."); return -EACCES; } + begin = tstamp = now(CLOCK_MONOTONIC); + for (;;) { + + if (tstamp > begin + TIMEOUT_USEC) + break; + + if (dbus_connection_get_is_authenticated(bus)) + break; + + if (!dbus_connection_read_write_dispatch(bus, ((begin + TIMEOUT_USEC - tstamp) + USEC_PER_MSEC - 1) / USEC_PER_MSEC)) + break; + + tstamp = now(CLOCK_MONOTONIC); + } + + if (!dbus_connection_get_is_connected(bus)) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_set_error_const(error, DBUS_ERROR_NO_SERVER, "Connection terminated during authentication."); + return -ECONNREFUSED; + } + + if (!dbus_connection_get_is_authenticated(bus)) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_set_error_const(error, DBUS_ERROR_TIMEOUT, "Failed to authenticate in time."); + return -EACCES; + } + if (private) *private = true; From 720ce21d444f6497299c4c99a76fda546b06716a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Mar 2011 00:52:13 +0100 Subject: [PATCH 016/200] util: close all fds before freezing execution --- TODO | 2 -- src/dbus-common.c | 3 +++ src/util.c | 18 ++++++++++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index f2e3be416..daa96773a 100644 --- a/TODO +++ b/TODO @@ -22,8 +22,6 @@ F15: * bind mounts are ignored -* SIGALRM in systemctl - * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown Features: diff --git a/src/dbus-common.c b/src/dbus-common.c index 80b2115e1..809ea0f67 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -77,6 +77,9 @@ int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private, DBusError * return -EACCES; } + /* This complexity should probably move into D-Bus itself: + * + * https://bugs.freedesktop.org/show_bug.cgi?id=35189 */ begin = tstamp = now(CLOCK_MONOTONIC); for (;;) { diff --git a/src/util.c b/src/util.c index c02b39e0a..c9366c4a3 100644 --- a/src/util.c +++ b/src/util.c @@ -1815,8 +1815,9 @@ int close_all_fds(const int except[], unsigned n_except) { if (ignore_file(de->d_name)) continue; - if ((r = safe_atoi(de->d_name, &fd)) < 0) - goto finish; + if (safe_atoi(de->d_name, &fd) < 0) + /* Let's better ignore this, just in case */ + continue; if (fd < 3) continue; @@ -1839,16 +1840,13 @@ int close_all_fds(const int except[], unsigned n_except) { continue; } - if ((r = close_nointr(fd)) < 0) { + if (close_nointr(fd) < 0) { /* Valgrind has its own FD and doesn't want to have it closed */ - if (errno != EBADF) - goto finish; + if (errno != EBADF && r == 0) + r = -errno; } } - r = 0; - -finish: closedir(d); return r; } @@ -3619,6 +3617,10 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid) { } void freeze(void) { + + /* Make sure nobody waits for us on a socket anymore */ + close_all_fds(NULL, 0); + sync(); for (;;) From 7d640cdf66a7c032c871ccfe0ee4ad56f7e3869b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Mar 2011 01:06:53 +0100 Subject: [PATCH 017/200] units: move the last flag files to /dev/.run --- TODO | 8 +++----- src/main.c | 2 +- units/fsck-root.service.in | 2 +- units/plymouth-start.service | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index daa96773a..64047191e 100644 --- a/TODO +++ b/TODO @@ -6,19 +6,17 @@ F15: * isolate multi-user.target doesn't start a getty@tty1 if we run it from graphical.target -* NFS, networkmanager ordering issue +* NFS, networkmanager ordering issue (PENDING) * add fstab fields to add wait timeouts, change Wants to Requires by local-fs.target * hook emergency.target into local-fs.target in some way as OnFailure with isolate -* mount /dev/.run and /var/run as bind mounts - -* drop SIGHUP handling from rsyslog.service upstream +* drop SIGHUP handling from rsyslog.service upstream (PENDING) * teach dbus to activate all services it finds in /etc/systemd/services/org-*.service -* save/restore tool for SysV as requested by FPC +* save/restore tool for SysV as requested by FPC (PENDING) * bind mounts are ignored diff --git a/src/main.c b/src/main.c index 5d37f804d..54ebb0b08 100644 --- a/src/main.c +++ b/src/main.c @@ -1051,7 +1051,7 @@ int main(int argc, char *argv[]) { /* If Plymouth is being run make sure we show the status, so * that there's something nice to see when people press Esc */ - if (access("/dev/.systemd/plymouth", F_OK) >= 0) + if (access("/dev/.run/initramfs/plymouth", F_OK) >= 0) arg_show_status = true; if (arg_action == ACTION_HELP) { diff --git a/units/fsck-root.service.in b/units/fsck-root.service.in index 290c8453c..ae6ea924a 100644 --- a/units/fsck-root.service.in +++ b/units/fsck-root.service.in @@ -12,7 +12,7 @@ After=systemd-readahead-collect.service systemd-readahead-replay.service Before=local-fs.target shutdown.target remount-rootfs.service quotacheck.service # Dracut informs us with this flag file if the root fsck was already run -ConditionPathExists=!/dev/.initramfs/fsck +ConditionPathExists=!/dev/.run/initramfs/root-fsck [Service] Type=oneshot diff --git a/units/plymouth-start.service b/units/plymouth-start.service index c3c101eb8..4ef2bcc02 100644 --- a/units/plymouth-start.service +++ b/units/plymouth-start.service @@ -13,7 +13,7 @@ After=systemd-vconsole-setup.service udev-settle.service Before=systemd-ask-password-plymouth.service # Dracut informs us with this flag file if plymouth is already running -ConditionPathExists=!/dev/.systemd/plymouth +ConditionPathExists=!/dev/.run/initramfs/plymouth [Service] ExecStart=/sbin/plymouthd --mode=boot From 820fa964859bab12bc8b6afea980399c71e34f5b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Mar 2011 01:51:45 +0100 Subject: [PATCH 018/200] gnome-ask-password-agent: fix path to watch --- src/gnome-ask-password-agent.vala | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/gnome-ask-password-agent.vala b/src/gnome-ask-password-agent.vala index 1bc97f548..75cfabfab 100644 --- a/src/gnome-ask-password-agent.vala +++ b/src/gnome-ask-password-agent.vala @@ -89,9 +89,9 @@ public class MyStatusIcon : StatusIcon { public MyStatusIcon() throws GLib.Error { GLib.Object(icon_name : "dialog-password"); - set_title("System Password"); + set_title("System Password Request"); - directory = File.new_for_path("/dev/.run/systemd/ask-password/"); + directory = File.new_for_path("/var/run/systemd/ask-password/"); file_monitor = directory.monitor_directory(0); file_monitor.changed.connect(file_monitor_changed); @@ -145,7 +145,6 @@ public class MyStatusIcon : StatusIcon { if (current == null) set_visible(false); - } bool load_password() throws GLib.Error { @@ -179,6 +178,7 @@ public class MyStatusIcon : StatusIcon { } catch (GLib.Error e) { message = "Please Enter System Password!"; } + set_tooltip_text(message); try { @@ -239,12 +239,7 @@ public class MyStatusIcon : StatusIcon { null); OutputStream stream = new UnixOutputStream(to_process, true); - -#if LIBNOTIFY07 stream.write(password.data, null); -#else - stream.write(password, password.length, null); -#endif } catch (Error e) { show_error(e.message); } From e8bf3c88e3a80b791cee3c6207a36e82a2ac1029 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 11 Mar 2011 14:09:10 +0100 Subject: [PATCH 019/200] gnome-ask-password-agent: restore removed libnotify0.6 support --- src/gnome-ask-password-agent.vala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gnome-ask-password-agent.vala b/src/gnome-ask-password-agent.vala index 75cfabfab..1d3b71566 100644 --- a/src/gnome-ask-password-agent.vala +++ b/src/gnome-ask-password-agent.vala @@ -239,7 +239,11 @@ public class MyStatusIcon : StatusIcon { null); OutputStream stream = new UnixOutputStream(to_process, true); +#if LIBNOTIFY07 stream.write(password.data, null); +#else + stream.write(password, password.length, null); +#endif } catch (Error e) { show_error(e.message); } From 202df05e0f01d79177dfeee6acf1748089f484a8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 11 Mar 2011 15:41:37 +0100 Subject: [PATCH 020/200] gnome-ask-password-agent: check for vala 0.10 instead of libnotify --- src/gnome-ask-password-agent.vala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gnome-ask-password-agent.vala b/src/gnome-ask-password-agent.vala index 1d3b71566..46813683a 100644 --- a/src/gnome-ask-password-agent.vala +++ b/src/gnome-ask-password-agent.vala @@ -239,10 +239,10 @@ public class MyStatusIcon : StatusIcon { null); OutputStream stream = new UnixOutputStream(to_process, true); -#if LIBNOTIFY07 - stream.write(password.data, null); -#else +#if VALA_0_10 stream.write(password, password.length, null); +#else + stream.write(password.data, null); #endif } catch (Error e) { show_error(e.message); From e75c058023a7e130599f5a3ae2981540d8e397c8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 11 Mar 2011 15:55:20 +0100 Subject: [PATCH 021/200] gnome-ask-password-agent.vala: check for VALA_0_12 VALA_0_X is defined up to and including the current version so VALA_0_10 is defined in 0.10 and 0.11 and 0.12 VALA_0_12 is defined in 0.11 and 0.12 (and later versions) reverse the branches and use VALA_0_12 as conditional juergbi: changing api but keep the defines? how do we support vala 0.14 then? you keep that model with the old defines? VALA_0_10 corresponds to valaversion >= 0.10 --- src/gnome-ask-password-agent.vala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gnome-ask-password-agent.vala b/src/gnome-ask-password-agent.vala index 46813683a..4f89a3e6d 100644 --- a/src/gnome-ask-password-agent.vala +++ b/src/gnome-ask-password-agent.vala @@ -239,10 +239,10 @@ public class MyStatusIcon : StatusIcon { null); OutputStream stream = new UnixOutputStream(to_process, true); -#if VALA_0_10 - stream.write(password, password.length, null); -#else +#if VALA_0_12 stream.write(password.data, null); +#else + stream.write(password, password.length, null); #endif } catch (Error e) { show_error(e.message); From a8f11321c209830a35edd0357e8def5d4437d854 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 12 Mar 2011 01:03:13 +0100 Subject: [PATCH 022/200] systemctl: support remote and privileged systemctl access via SSH and pkexec This adds support for executing systemctl operations remotely or as privileged user while still running systemctl itself unprivileged and locally. This currently requires a D-Bus patch to work properly. https://bugs.freedesktop.org/show_bug.cgi?id=35230 --- .gitignore | 1 + Makefile.am | 10 +- TODO | 2 + man/systemctl.xml | 21 ++ src/bridge.c | 367 ++++++++++++++++++++++++++++ src/dbus-common.c | 163 +++++++++--- src/dbus-common.h | 3 + src/org.freedesktop.systemd1.policy | 11 + src/systemctl.c | 76 ++++-- 9 files changed, 595 insertions(+), 59 deletions(-) create mode 100644 src/bridge.c diff --git a/.gitignore b/.gitignore index 0584d900d..ffc602a95 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +systemd-stdio-bridge systemd-machine-id-setup systemd-detect-virt systemd-sysctl diff --git a/Makefile.am b/Makefile.am index f867624f1..7120636d9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,6 +58,7 @@ AM_CPPFLAGS = \ -DSYSTEMD_SHUTDOWN_BINARY_PATH=\"$(rootlibexecdir)/systemd-shutdown\" \ -DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \ -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \ + -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ -DRUNTIME_DIR=\"$(localstatedir)/run\" \ -DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \ -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \ @@ -111,7 +112,8 @@ rootsbin_PROGRAMS = \ systemd-machine-id-setup bin_PROGRAMS = \ - systemd-cgls + systemd-cgls \ + systemd-stdio-bridge if HAVE_GTK bin_PROGRAMS += \ @@ -980,6 +982,12 @@ systemd_cgls_CFLAGS = \ systemd_cgls_LDADD = \ libsystemd-basic.la +systemd_stdio_bridge_SOURCES = \ + src/bridge.c + +systemd_stdio_bridge_LDADD = \ + libsystemd-basic.la + systemadm_SOURCES = \ src/systemadm.vala \ src/systemd-interfaces.vala diff --git a/TODO b/TODO index 64047191e..a36ca5e0f 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,8 @@ Features: * optionally create watched directories in .path units +* Support --test based on current system state + * consider services with no [Install] section and stored in /lib enabled by "systemctl is-enabled" * consider services with any kind of link in /etc/systemd/system enabled diff --git a/man/systemctl.xml b/man/systemctl.xml index d37a7d95d..d6e0a51f2 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -382,6 +382,27 @@ file that shall be disabled. + + + + + + Execute operation + remotely. Specifiy a hostname, or + username and hostname seperated by @, + to connect to. This will use SSH to + talk to the remote systemd + instance. + + + + + + + Acquire privileges via + PolicyKit before executing the + operation. + The following commands are understood: diff --git a/src/bridge.c b/src/bridge.c new file mode 100644 index 000000000..5ee058a37 --- /dev/null +++ b/src/bridge.c @@ -0,0 +1,367 @@ +/*-*- 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "socket-util.h" + +#define BUFFER_SIZE (64*1024) +#define EXTRA_SIZE 16 + +static bool initial_nul = false; +static bool auth_over = false; + +static void format_uid(char *buf, size_t l) { + char text[20 + 1]; /* enough space for a 64bit integer plus NUL */ + unsigned j; + + assert(l > 0); + + snprintf(text, sizeof(text)-1, "%llu", (unsigned long long) geteuid()); + text[sizeof(text)-1] = 0; + + memset(buf, 0, l); + + for (j = 0; text[j] && j*2+2 < l; j++) { + buf[j*2] = hexchar(text[j] >> 4); + buf[j*2+1] = hexchar(text[j] & 0xF); + } + + buf[j*2] = 0; +} + +static size_t patch_in_line(char *line, size_t l, size_t left) { + size_t r; + + if (line[0] == 0 && !initial_nul) { + initial_nul = true; + line += 1; + l -= 1; + r = 1; + } else + r = 0; + + if (l == 5 && strncmp(line, "BEGIN", 5) == 0) { + r += l; + auth_over = true; + + } else if (l == 17 && strncmp(line, "NEGOTIATE_UNIX_FD", 17) == 0) { + memmove(line + 13, line + 17, left); + memcpy(line, "NEGOTIATE_NOP", 13); + r += 13; + + } else if (l >= 14 && strncmp(line, "AUTH EXTERNAL ", 14) == 0) { + char uid[20*2 + 1]; + size_t len; + + format_uid(uid, sizeof(uid)); + len = strlen(uid); + assert(len <= EXTRA_SIZE); + + memmove(line + 14 + len, line + l, left); + memcpy(line + 14, uid, len); + + r += 14 + len; + } else + r += l; + + return r; +} + +static size_t patch_in_buffer(char* in_buffer, size_t *in_buffer_full) { + size_t i, good = 0; + + if (*in_buffer_full <= 0) + return *in_buffer_full; + + /* If authentication is done, we don't touch anything anymore */ + if (auth_over) + return *in_buffer_full; + + if (*in_buffer_full < 2) + return 0; + + for (i = 0; i <= *in_buffer_full - 2; i ++) { + + /* Fully lines can be send on */ + if (in_buffer[i] == '\r' && in_buffer[i+1] == '\n') { + if (i > good) { + size_t old_length, new_length; + + old_length = i - good; + new_length = patch_in_line(in_buffer+good, old_length, *in_buffer_full - i); + *in_buffer_full = *in_buffer_full + new_length - old_length; + + good += new_length + 2; + + } else + good = i+2; + } + + if (auth_over) + break; + } + + return good; +} + +int main(int argc, char *argv[]) { + int r = EXIT_FAILURE, fd = -1, ep = -1; + union sockaddr_union sa; + char in_buffer[BUFFER_SIZE+EXTRA_SIZE], out_buffer[BUFFER_SIZE+EXTRA_SIZE]; + size_t in_buffer_full = 0, out_buffer_full = 0; + struct epoll_event stdin_ev, stdout_ev, fd_ev; + bool stdin_readable = false, stdout_writable = false, fd_readable = false, fd_writable = false; + bool stdin_rhup = false, stdout_whup = false, fd_rhup = false, fd_whup = false; + + if (argc > 1) { + log_error("This program takes no argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); + log_parse_environment(); + log_open(); + + if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("Failed to create socket: %s", strerror(errno)); + goto finish; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(sa.un.sun_path)); + + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { + log_error("Failed to connect: %m"); + goto finish; + } + + fd_nonblock(STDIN_FILENO, 1); + fd_nonblock(STDOUT_FILENO, 1); + + if ((ep = epoll_create1(EPOLL_CLOEXEC)) < 0) { + log_error("Failed to create epoll: %m"); + goto finish; + } + + zero(stdin_ev); + stdin_ev.events = EPOLLIN|EPOLLET; + stdin_ev.data.fd = STDIN_FILENO; + + zero(stdout_ev); + stdout_ev.events = EPOLLOUT|EPOLLET; + stdout_ev.data.fd = STDOUT_FILENO; + + zero(fd_ev); + fd_ev.events = EPOLLIN|EPOLLOUT|EPOLLET; + fd_ev.data.fd = fd; + + if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, fd, &fd_ev) < 0) { + log_error("Failed to regiser fds in epoll: %m"); + goto finish; + } + + do { + struct epoll_event ev[16]; + ssize_t k; + int i, nfds; + + if ((nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1)) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll_wait(): %m"); + goto finish; + } + + assert(nfds >= 1); + + for (i = 0; i < nfds; i++) { + if (ev[i].data.fd == STDIN_FILENO) { + + if (!stdin_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + stdin_readable = true; + + } else if (ev[i].data.fd == STDOUT_FILENO) { + + if (ev[i].events & EPOLLHUP) { + stdout_writable = false; + stdout_whup = true; + } + + if (!stdout_whup && (ev[i].events & EPOLLOUT)) + stdout_writable = true; + + } else if (ev[i].data.fd == fd) { + + if (ev[i].events & EPOLLHUP) { + fd_writable = false; + fd_whup = true; + } + + if (!fd_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + fd_readable = true; + + if (!fd_whup && (ev[i].events & EPOLLOUT)) + fd_writable = true; + } + } + + while ((stdin_readable && in_buffer_full <= 0) || + (fd_writable && patch_in_buffer(in_buffer, &in_buffer_full) > 0) || + (fd_readable && out_buffer_full <= 0) || + (stdout_writable && out_buffer_full > 0)) { + + size_t in_buffer_good = 0; + + if (stdin_readable && in_buffer_full < BUFFER_SIZE) { + + if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) { + + if (errno == EAGAIN) + stdin_readable = false; + else if (errno == EPIPE || errno == ECONNRESET) + k = 0; + else { + log_error("read(): %m"); + goto finish; + } + } else + in_buffer_full += (size_t) k; + + if (k == 0) { + stdin_rhup = true; + stdin_readable = false; + shutdown(STDIN_FILENO, SHUT_RD); + close_nointr_nofail(STDIN_FILENO); + } + } + + in_buffer_good = patch_in_buffer(in_buffer, &in_buffer_full); + + if (fd_writable && in_buffer_good > 0) { + + if ((k = write(fd, in_buffer, in_buffer_good)) < 0) { + + if (errno == EAGAIN) + fd_writable = false; + else if (errno == EPIPE || errno == ECONNRESET) { + fd_whup = true; + fd_writable = false; + shutdown(fd, SHUT_WR); + } else { + log_error("write(): %m"); + goto finish; + } + + } else { + assert(in_buffer_full >= (size_t) k); + memmove(in_buffer, in_buffer + k, in_buffer_full - k); + in_buffer_full -= k; + } + } + + if (fd_readable && out_buffer_full < BUFFER_SIZE) { + + if ((k = read(fd, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) { + + if (errno == EAGAIN) + fd_readable = false; + else if (errno == EPIPE || errno == ECONNRESET) + k = 0; + else { + log_error("read(): %m"); + goto finish; + } + } else + out_buffer_full += (size_t) k; + + if (k == 0) { + fd_rhup = true; + fd_readable = false; + shutdown(fd, SHUT_RD); + } + } + + if (stdout_writable && out_buffer_full > 0) { + + if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) { + + if (errno == EAGAIN) + stdout_writable = false; + else if (errno == EPIPE || errno == ECONNRESET) { + stdout_whup = true; + stdout_writable = false; + shutdown(STDOUT_FILENO, SHUT_WR); + close_nointr(STDOUT_FILENO); + } else { + log_error("write(): %m"); + goto finish; + } + + } else { + assert(out_buffer_full >= (size_t) k); + memmove(out_buffer, out_buffer + k, out_buffer_full - k); + out_buffer_full -= k; + } + } + } + + if (stdin_rhup && in_buffer_full <= 0 && !fd_whup) { + fd_whup = true; + fd_writable = false; + shutdown(fd, SHUT_WR); + } + + if (fd_rhup && out_buffer_full <= 0 && !stdout_whup) { + stdout_whup = true; + stdout_writable = false; + shutdown(STDOUT_FILENO, SHUT_WR); + close_nointr(STDOUT_FILENO); + } + + } while (!stdout_whup || !fd_whup); + + r = EXIT_SUCCESS; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + if (ep >= 0) + close_nointr_nofail(ep); + + return r; +} diff --git a/src/dbus-common.c b/src/dbus-common.c index 809ea0f67..25b718ec0 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include "log.h" @@ -55,20 +57,58 @@ int bus_check_peercred(DBusConnection *c) { return 1; } +#define TIMEOUT_USEC (60*USEC_PER_SEC) + +static int sync_auth(DBusConnection *bus, DBusError *error) { + usec_t begin, tstamp; + + assert(bus); + + /* This complexity should probably move into D-Bus itself: + * + * https://bugs.freedesktop.org/show_bug.cgi?id=35189 */ + + begin = tstamp = now(CLOCK_MONOTONIC); + for (;;) { + + if (tstamp > begin + TIMEOUT_USEC) + break; + + if (dbus_connection_get_is_authenticated(bus)) + break; + + if (!dbus_connection_read_write_dispatch(bus, ((begin + TIMEOUT_USEC - tstamp) + USEC_PER_MSEC - 1) / USEC_PER_MSEC)) + break; + + tstamp = now(CLOCK_MONOTONIC); + } + + if (!dbus_connection_get_is_connected(bus)) { + dbus_set_error_const(error, DBUS_ERROR_NO_SERVER, "Connection terminated during authentication."); + return -ECONNREFUSED; + } + + if (!dbus_connection_get_is_authenticated(bus)) { + dbus_set_error_const(error, DBUS_ERROR_TIMEOUT, "Failed to authenticate in time."); + return -EACCES; + } + + return 0; +} + int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private, DBusError *error) { DBusConnection *bus; + int r; assert(_bus); -#define TIMEOUT_USEC (60*USEC_PER_SEC) - /* If we are root, then let's not go via the bus */ if (geteuid() == 0 && t == DBUS_BUS_SYSTEM) { - usec_t begin, tstamp; - if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", error))) return -EIO; + dbus_connection_set_exit_on_disconnect(bus, FALSE); + if (bus_check_peercred(bus) < 0) { dbus_connection_close(bus); dbus_connection_unref(bus); @@ -77,40 +117,6 @@ int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private, DBusError * return -EACCES; } - /* This complexity should probably move into D-Bus itself: - * - * https://bugs.freedesktop.org/show_bug.cgi?id=35189 */ - begin = tstamp = now(CLOCK_MONOTONIC); - for (;;) { - - if (tstamp > begin + TIMEOUT_USEC) - break; - - if (dbus_connection_get_is_authenticated(bus)) - break; - - if (!dbus_connection_read_write_dispatch(bus, ((begin + TIMEOUT_USEC - tstamp) + USEC_PER_MSEC - 1) / USEC_PER_MSEC)) - break; - - tstamp = now(CLOCK_MONOTONIC); - } - - if (!dbus_connection_get_is_connected(bus)) { - dbus_connection_close(bus); - dbus_connection_unref(bus); - - dbus_set_error_const(error, DBUS_ERROR_NO_SERVER, "Connection terminated during authentication."); - return -ECONNREFUSED; - } - - if (!dbus_connection_get_is_authenticated(bus)) { - dbus_connection_close(bus); - dbus_connection_unref(bus); - - dbus_set_error_const(error, DBUS_ERROR_TIMEOUT, "Failed to authenticate in time."); - return -EACCES; - } - if (private) *private = true; @@ -118,12 +124,93 @@ int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private, DBusError * if (!(bus = dbus_bus_get_private(t, error))) return -EIO; + dbus_connection_set_exit_on_disconnect(bus, FALSE); + if (private) *private = false; } + if ((r = sync_auth(bus, error)) < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + *_bus = bus; + return 0; +} + +int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error) { + DBusConnection *bus; + char *p = NULL; + int r; + + assert(_bus); + assert(user || host); + + if (user && host) + asprintf(&p, "exec:path=ssh,argv1=-xT,argv2=%s@%s,argv3=systemd-stdio-bridge", user, host); + else if (user) + asprintf(&p, "exec:path=ssh,argv1=-xT,argv2=%s@localhost,argv3=systemd-stdio-bridge", user); + else if (host) + asprintf(&p, "exec:path=ssh,argv1=-xT,argv2=%s,argv3=systemd-stdio-bridge", host); + + if (!p) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + return -ENOMEM; + } + + bus = dbus_connection_open_private(p, error); + free(p); + + if (!bus) + return -EIO; + dbus_connection_set_exit_on_disconnect(bus, FALSE); + if ((r = sync_auth(bus, error)) < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + if (!dbus_bus_register(bus, error)) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + *_bus = bus; + return 0; +} + +int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error) { + DBusConnection *bus; + int r; + + assert(_bus); + + /* Don't bother with PolicyKit if we are root */ + if (geteuid() == 0) + return bus_connect(DBUS_BUS_SYSTEM, _bus, NULL, error); + + if (!(bus = dbus_connection_open_private("exec:path=pkexec,argv1=" SYSTEMD_STDIO_BRIDGE_BINARY_PATH, error))) + return -EIO; + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if ((r = sync_auth(bus, error)) < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + if (!dbus_bus_register(bus, error)) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + *_bus = bus; return 0; } diff --git a/src/dbus-common.h b/src/dbus-common.h index 9a66b7874..76333cd4f 100644 --- a/src/dbus-common.h +++ b/src/dbus-common.h @@ -28,6 +28,9 @@ int bus_check_peercred(DBusConnection *c); int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private_bus, DBusError *error); +int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error); +int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error); + const char *bus_error_message(const DBusError *error); #endif diff --git a/src/org.freedesktop.systemd1.policy b/src/org.freedesktop.systemd1.policy index bb07b827f..a9958c2e3 100644 --- a/src/org.freedesktop.systemd1.policy +++ b/src/org.freedesktop.systemd1.policy @@ -27,4 +27,15 @@ /lib/systemd/systemd-reply-password + + Privileged system and service manager access + Authentication is required to access the system and service manager. + + no + no + auth_admin_keep + + /usr/bin/systemd-stdio-bridge + + diff --git a/src/systemctl.c b/src/systemctl.c index 5b205fec5..b8af654e0 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -108,6 +108,12 @@ static enum dot { DOT_ORDER, DOT_REQUIRE } arg_dot = DOT_ALL; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static const char *arg_host = NULL; static bool private_bus = false; @@ -2061,12 +2067,14 @@ static void print_status_info(UnitStatusInfo *i) { printf("\t CGroup: %s\n", i->default_control_group); - if ((c = columns()) > 18) - c -= 18; - else - c = 0; + if (arg_transport != TRANSPORT_SSH) { + if ((c = columns()) > 18) + c -= 18; + else + c = 0; - show_cgroup_by_path(i->default_control_group, "\t\t ", c); + show_cgroup_by_path(i->default_control_group, "\t\t ", c); + } } if (i->need_daemon_reload) @@ -4290,22 +4298,25 @@ static int systemctl_help(void) { " pending\n" " --ignore-dependencies\n" " When queueing a new job, ignore all its dependencies\n" - " -q --quiet Suppress output\n" - " --no-block Do not wait until operation finished\n" - " --no-pager Do not pipe output into a pager.\n" - " --system Connect to system manager\n" - " --user Connect to user service manager\n" - " --order When generating graph for dot, show only order\n" - " --require When generating graph for dot, show only requirement\n" - " --no-wall Don't send wall message before halt/power-off/reboot\n" - " --global Enable/disable unit files globally\n" - " --no-reload When enabling/disabling unit files, don't reload daemon\n" - " configuration\n" - " --no-ask-password\n" - " Do not ask for system passwords\n" " --kill-mode=MODE How to send signal\n" " --kill-who=WHO Who to send signal to\n" " -s --signal=SIGNAL Which signal to send\n" + " -H --host=[user@]host\n" + " Show information for remote host\n" + " -P --privileged Acquire privileges before execution\n" + " -q --quiet Suppress output\n" + " --no-block Do not wait until operation finished\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n" + " --no-reload When enabling/disabling unit files, don't reload daemon\n" + " configuration\n" + " --no-pager Do not pipe output into a pager.\n" + " --no-ask-password\n" + " Do not ask for system passwords\n" + " --order When generating graph for dot, show only order\n" + " --require When generating graph for dot, show only requirement\n" + " --system Connect to system manager\n" + " --user Connect to user service manager\n" + " --global Enable/disable unit files globally\n" " -f --force When enabling unit files, override existing symlinks\n" " When shutting down, execute action immediately\n" " --defaults When disabling unit files, remove default symlinks only\n\n" @@ -4472,6 +4483,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "kill-who", required_argument, NULL, ARG_KILL_WHO }, { "signal", required_argument, NULL, 's' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "host", required_argument, NULL, 'H' }, + { "privileged",no_argument, NULL, 'P' }, { NULL, 0, NULL, 0 } }; @@ -4483,7 +4496,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { /* Only when running as systemctl we ask for passwords */ arg_ask_password = true; - while ((c = getopt_long(argc, argv, "ht:p:aqfs:", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:P", options, NULL)) >= 0) { switch (c) { @@ -4605,6 +4618,15 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_ask_password = false; break; + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + case '?': return -EINVAL; @@ -4614,6 +4636,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) { } } + if (arg_transport != TRANSPORT_NORMAL && arg_user) { + log_error("Cannot access user instance remotely."); + return -EINVAL; + } + return 1; } @@ -5622,7 +5649,16 @@ int main(int argc, char*argv[]) { goto finish; } - bus_connect(arg_user ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error); + if (arg_transport == TRANSPORT_NORMAL) + bus_connect(arg_user ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error); + else if (arg_transport == TRANSPORT_POLKIT) { + bus_connect_system_polkit(&bus, &error); + private_bus = false; + } else if (arg_transport == TRANSPORT_SSH) { + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + private_bus = false; + } else + assert_not_reached("Uh, invalid transport..."); switch (arg_action) { From 25705583af79130d2692de297ac971f3cf165619 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 12 Mar 2011 01:15:30 +0100 Subject: [PATCH 023/200] polkit: autogenerate polkit policy with correct paths --- Makefile.am | 9 +++++++-- ...ystemd1.policy => org.freedesktop.systemd1.policy.in} | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) rename src/{org.freedesktop.systemd1.policy => org.freedesktop.systemd1.policy.in} (94%) diff --git a/Makefile.am b/Makefile.am index 7120636d9..bb6485792 100644 --- a/Makefile.am +++ b/Makefile.am @@ -339,7 +339,8 @@ EXTRA_DIST = \ units/fsck-root.service.in \ units/quotacheck.service.in \ systemd.pc.in \ - introspect.awk + introspect.awk \ + src/org.freedesktop.systemd1.policy.in if TARGET_FEDORA dist_systemunit_DATA += \ @@ -386,7 +387,7 @@ dist_doc_DATA = \ pkgconfigdata_DATA = \ systemd.pc -dist_polkitpolicy_DATA = \ +polkitpolicy_DATA = \ src/org.freedesktop.systemd1.policy noinst_LTLIBRARIES = \ @@ -1069,6 +1070,7 @@ SED_PROCESS = \ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ $(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \ -e 's,@rootbindir\@,$(rootbindir),g' \ + -e 's,@bindir\@,$(bindir),g' \ -e 's,@SPECIAL_SYSLOG_SERVICE\@,$(SPECIAL_SYSLOG_SERVICE),g' \ -e 's,@SYSTEMCTL\@,$(rootbindir)/systemctl,g' \ -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \ @@ -1090,6 +1092,9 @@ man/%: man/%.in Makefile %.pc: %.pc.in Makefile $(SED_PROCESS) +src/%.policy: src/%.policy.in Makefile + $(SED_PROCESS) + M4_PROCESS_SYSTEM = \ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ $(M4) -P $(M4_DISTRO_FLAG) -DFOR_SYSTEM=1 < $< > $@ || rm $@ diff --git a/src/org.freedesktop.systemd1.policy b/src/org.freedesktop.systemd1.policy.in similarity index 94% rename from src/org.freedesktop.systemd1.policy rename to src/org.freedesktop.systemd1.policy.in index a9958c2e3..b8b354726 100644 --- a/src/org.freedesktop.systemd1.policy +++ b/src/org.freedesktop.systemd1.policy.in @@ -24,7 +24,7 @@ no auth_admin_keep - /lib/systemd/systemd-reply-password + @rootlibexecdir@/systemd-reply-password @@ -35,7 +35,7 @@ no auth_admin_keep - /usr/bin/systemd-stdio-bridge + @bindir@/systemd-stdio-bridge From 3eb4d9a214a09883e50ce557b36c7903406d7ef8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 12 Mar 2011 14:31:44 +0100 Subject: [PATCH 024/200] build-sys: add org.freedesktop.systemd1.policy to CLEANFILES ERROR: files left in build directory after distclean: ./src/org.freedesktop.systemd1.policy make[1]: *** [distcleancheck] Error 1 --- Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index bb6485792..872bcc255 100644 --- a/Makefile.am +++ b/Makefile.am @@ -340,7 +340,7 @@ EXTRA_DIST = \ units/quotacheck.service.in \ systemd.pc.in \ introspect.awk \ - src/org.freedesktop.systemd1.policy.in + src/org.freedesktop.systemd1.policy.in if TARGET_FEDORA dist_systemunit_DATA += \ @@ -1114,7 +1114,8 @@ CLEANFILES = \ $(nodist_userunit_DATA) \ $(nodist_man_MANS) \ ${XML_IN_FILES:.xml.in=.html} \ - $(pkgconfigdata_DATA) + $(pkgconfigdata_DATA) \ + src/org.freedesktop.systemd1.policy if HAVE_VALAC CLEANFILES += \ From 46824d0e6b2aae8f503464368d02c1da992f56f1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 02:33:23 +0100 Subject: [PATCH 025/200] util: properly identify pty devices by their major --- src/util.c | 22 ++++++++++++++++++++-- src/util.h | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/util.c b/src/util.c index c9366c4a3..ee6217d64 100644 --- a/src/util.c +++ b/src/util.c @@ -2865,7 +2865,7 @@ int getttyname_harder(int fd, char **r) { if (streq(s, "tty")) { free(s); - return get_ctty(r); + return get_ctty(r, NULL); } *r = s; @@ -2907,7 +2907,7 @@ int get_ctty_devnr(dev_t *d) { return 0; } -int get_ctty(char **r) { +int get_ctty(char **r, dev_t *_devnr) { int k; char fn[128], *s, *b, *p; dev_t devnr; @@ -2925,6 +2925,18 @@ int get_ctty(char **r) { if (k != -ENOENT) return k; + /* This is an ugly hack */ + if (major(devnr) == 136) { + if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0) + return -ENOMEM; + + *r = b; + if (_devnr) + *_devnr = devnr; + + return 0; + } + /* Probably something like the ptys which have no * symlink in /dev/char. Let's return something * vaguely useful. */ @@ -2933,6 +2945,9 @@ int get_ctty(char **r) { return -ENOMEM; *r = b; + if (_devnr) + *_devnr = devnr; + return 0; } @@ -2950,6 +2965,9 @@ int get_ctty(char **r) { return -ENOMEM; *r = b; + if (_devnr) + *_devnr = devnr; + return 0; } diff --git a/src/util.h b/src/util.h index 13e5f6203..320bcd7c3 100644 --- a/src/util.h +++ b/src/util.h @@ -337,7 +337,7 @@ int getttyname_malloc(int fd, char **r); int getttyname_harder(int fd, char **r); int get_ctty_devnr(dev_t *d); -int get_ctty(char **r); +int get_ctty(char **r, dev_t *_devnr); int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); From 0a27cf3f32403f48059396cb43ad25d0a12ef64b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 02:33:51 +0100 Subject: [PATCH 026/200] util: return exit status in wait_for_terminate_and_warn() --- src/quotacheck.c | 2 +- src/util.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quotacheck.c b/src/quotacheck.c index 55c2f0c6d..da2da3b2e 100644 --- a/src/quotacheck.c +++ b/src/quotacheck.c @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) { _exit(1); /* Operational error */ } - r = wait_for_terminate_and_warn("quotacheck", pid) >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; + r = wait_for_terminate_and_warn("quotacheck", pid) == 0 ? EXIT_SUCCESS : EXIT_FAILURE; finish: return r; diff --git a/src/util.c b/src/util.c index ee6217d64..b2baa1ba2 100644 --- a/src/util.c +++ b/src/util.c @@ -3616,7 +3616,7 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid) { if (status.si_code == CLD_EXITED) { if (status.si_status != 0) { log_warning("%s failed with error code %i.", name, status.si_status); - return -EPROTO; + return status.si_status; } log_debug("%s succeeded.", name); From 224170db0a2215284964fd9cc218681651713271 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 02:34:18 +0100 Subject: [PATCH 027/200] git: ignore generated policy file --- src/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/src/.gitignore b/src/.gitignore index 9c01ae1fd..4c7d3c882 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +org.freedesktop.systemd1.policy gnome-ask-password-agent.c systemd-interfaces.c systemadm.c From f9b9232be9db82cc729a56a2e99ecb27be546aac Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 02:36:00 +0100 Subject: [PATCH 028/200] util: detect CLONE_NEWPID namespaces, and cache results --- TODO | 2 ++ src/util.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/TODO b/TODO index a36ca5e0f..986e06a60 100644 --- a/TODO +++ b/TODO @@ -22,6 +22,8 @@ F15: * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown +* capability_bounding_set_drop not used. + Features: * optionally create watched directories in .path units diff --git a/src/util.c b/src/util.c index b2baa1ba2..38d630e6a 100644 --- a/src/util.c +++ b/src/util.c @@ -3948,6 +3948,20 @@ int detect_vm(const char **id) { /* Returns a short identifier for the various VM/container implementations */ int detect_virtualization(const char **id) { int r; + static __thread const char *cached_id = NULL; + const char *_id; + FILE *f; + + if (cached_id) { + + if (cached_id == (const char*) -1) + return 0; + + if (id) + *id = cached_id; + + return 1; + } /* Unfortunately most of these operations require root access * in one way or another */ @@ -3955,24 +3969,60 @@ int detect_virtualization(const char **id) { return -EPERM; if ((r = running_in_chroot()) > 0) { - if (id) - *id = "chroot"; + _id = "chroot"; + r = 1; + goto finish; + } - return r; + if ((f = fopen("/proc/self/cgroup", "r"))) { + + for (;;) { + char line[LINE_MAX], *p; + + if (!fgets(line, sizeof(line), f)) + break; + + if (!(p = strchr(strstrip(line), ':'))) + continue; + + if (strncmp(p, ":ns:", 4)) + continue; + + if (!streq(p, ":ns:/")) { + fclose(f); + + r = 1; + _id = "ns"; + goto finish; + } + } + + fclose(f); } /* /proc/vz exists in container and outside of the container, * /proc/bc only outside of the container. */ if (access("/proc/vz", F_OK) >= 0 && access("/proc/bc", F_OK) < 0) { - - if (id) - *id = "openvz"; - - return 1; + _id = "openvz"; + r = 1; + goto finish; } - return detect_vm(id); + r = detect_vm(&_id); + +finish: + if (r < 0) + return r; + else if (r > 0) + cached_id = _id; + else + cached_id = (const char*) -1; + + if (id) + *id = _id; + + return r; } void execute_directory(const char *directory, DIR *d, char *argv[]) { From 88213476187cafc86bea2276199891873000588d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 02:40:36 +0100 Subject: [PATCH 029/200] nspawn: add simple chroot(1) like tool to execute commands in a namespace container --- .gitignore | 1 + Makefile.am | 12 ++ src/nspawn.c | 444 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 457 insertions(+) create mode 100644 src/nspawn.c diff --git a/.gitignore b/.gitignore index ffc602a95..d679f791e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +systemd-nspawn systemd-stdio-bridge systemd-machine-id-setup systemd-detect-virt diff --git a/Makefile.am b/Makefile.am index 872bcc255..7d6cfd12d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -115,6 +115,9 @@ bin_PROGRAMS = \ systemd-cgls \ systemd-stdio-bridge +sbin_PROGRAMS = \ + systemd-nspawn + if HAVE_GTK bin_PROGRAMS += \ systemadm \ @@ -983,6 +986,15 @@ systemd_cgls_CFLAGS = \ systemd_cgls_LDADD = \ libsystemd-basic.la +systemd_nspawn_SOURCES = \ + src/nspawn.c + +systemd_nspawn_CFLAGS = \ + $(AM_CFLAGS) + +systemd_nspawn_LDADD = \ + libsystemd-basic.la + systemd_stdio_bridge_SOURCES = \ src/bridge.c diff --git a/src/nspawn.c b/src/nspawn.c new file mode 100644 index 000000000..4e4d40ea6 --- /dev/null +++ b/src/nspawn.c @@ -0,0 +1,444 @@ +/*-*- 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" + +static char *arg_directory = NULL; + +static int help(void) { + + printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n" + "Spawn a minimal namespace container for debugging, testing and building.\n\n" + " -h --help Show this help\n" + " -D --directory=NAME Root directory for the container\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "directory", required_argument, NULL, 'D' }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "+hD:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case 'D': + free(arg_directory); + if (!(arg_directory = strdup(optarg))) { + log_error("Failed to duplicate root directory."); + return -ENOMEM; + } + + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +static int mount_all(const char *dest) { + + typedef struct MountPoint { + const char *what; + const char *where; + const char *type; + const char *options; + unsigned long flags; + } MountPoint; + + static const MountPoint mount_table[] = { + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, + { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND }, /* Bind mount first */ + { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT }, /* Then, make it r/o */ + { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY }, + { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID }, + { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND }, + { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV }, + }; + + unsigned k; + int r = 0; + + for (k = 0; k < ELEMENTSOF(mount_table); k++) { + char *where; + int t; + + if (asprintf(&where, "%s/%s", dest, mount_table[k].where) < 0) { + log_error("Out of memory"); + + if (r == 0) + r = -ENOMEM; + + break; + } + + if ((t = path_is_mount_point(where)) < 0) { + log_error("Failed to detect whether %s is a mount point: %s", where, strerror(-t)); + free(where); + + if (r == 0) + r = t; + + continue; + } + + mkdir_p(where, 0755); + + if (mount(mount_table[k].what, + where, + mount_table[k].type, + mount_table[k].flags, + mount_table[k].options) < 0) { + + log_error("mount(%s) failed: %m", where); + + if (r == 0) + r = -errno; + } + + free(where); + } + + return r; +} + +static int copy_devnodes(const char *dest) { + + static const char devnodes[] = + "null\0" + "zero\0" + "full\0" + "random\0" + "urandom\0" + "tty\0" + "ptmx\0" + "kmsg\0" + "rtc0\0"; + + const char *d; + int r = 0, k; + char *tty = NULL; + dev_t tty_devnum; + + NULSTR_FOREACH(d, devnodes) { + char *from = NULL, *to = NULL; + struct stat st; + + asprintf(&from, "/dev/%s", d); + asprintf(&to, "%s/dev/%s", dest, d); + + if (!from || !to) { + log_error("Failed to allocate devnode path"); + + free(from); + free(to); + + if (r == 0) + r = -ENOMEM; + + break; + } + + if (stat(from, &st) < 0) { + + if (errno != ENOENT) { + log_error("Failed to stat %s: %m", from); + + if (r == 0) + r = -errno; + } + + } else { + if (mknod(to, st.st_mode, st.st_rdev) < 0) { + log_error("mknod(%s) failed: %m", dest); + + if (r == 0) + r = -errno; + } + } + + free(from); + free(to); + } + + if ((k = get_ctty(&tty, &tty_devnum)) < 0) { + log_error("Failed to determine controlling tty: %s", strerror(-k)); + + if (r == 0) + r = k; + } else { + char *from = NULL, *to = NULL; + + asprintf(&from, "/dev/%s", tty); + asprintf(&to, "%s/dev/console", dest); + + if (!from || !to) { + log_error("Out of memory"); + + if (r == 0) + r = k; + } else { + /* We need to bind mount our own tty on + * /dev/console, since ptys cannot be used + * unless on a devpts file system. But to bind + * mount it we first have to create a device + * node where we can bind mount it on. This is + * kinda ugly since the TTY will very likely + * be owned by a user/group that does not + * exist in the container. */ + + if (mknod(to, S_IFCHR|0600, tty_devnum) < 0) { + log_error("mknod for /dev/console failed: %m"); + + if (r == 0) + r = -errno; + } + + if (mount(from, to, "bind", MS_BIND, NULL) < 0) { + log_error("bind mount for /dev/console failed: %m"); + + if (r == 0) + r = -errno; + } + } + + free(from); + free(to); + } + + free(tty); + + return r; +} + +static int drop_capabilities(void) { + static const unsigned long retain[] = { + CAP_CHOWN, + CAP_DAC_OVERRIDE, + CAP_DAC_READ_SEARCH, + CAP_FOWNER, + CAP_FSETID, + CAP_IPC_OWNER, + CAP_KILL, + CAP_LEASE, + CAP_LINUX_IMMUTABLE, + CAP_NET_BIND_SERVICE, + CAP_NET_BROADCAST, + CAP_NET_RAW, + CAP_SETGID, + CAP_SETFCAP, + CAP_SETPCAP, + CAP_SETUID, + CAP_SYS_ADMIN, + CAP_SYS_CHROOT, + CAP_SYS_NICE, + CAP_SYS_PTRACE, + CAP_SYS_TTY_CONFIG + }; + + unsigned long l; + + for (l = 0; l <= MAX(63LU, (unsigned long) CAP_LAST_CAP); l ++) { + unsigned i; + + for (i = 0; i < ELEMENTSOF(retain); i++) + if (retain[i] == l) + break; + + if (i < ELEMENTSOF(retain)) + continue; + + if (prctl(PR_CAPBSET_DROP, l) < 0) { + + /* If this capability is not known, EINVAL + * will be returned, let's ignore this. */ + if (errno == EINVAL) + continue; + + log_error("PR_CAPBSET_DROP failed: %m"); + return -errno; + } + } + + return 0; +} + +static int is_os_tree(const char *path) { + int r; + char *p; + /* We use /bin/sh as flag file if something is an OS */ + + if (asprintf(&p, "%s/bin/sh", path) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + return r < 0 ? 0 : 1; +} + + +int main(int argc, char *argv[]) { + pid_t pid = 0; + int r = EXIT_FAILURE; + + log_parse_environment(); + log_open(); + + if ((r = parse_argv(argc, argv)) <= 0) + goto finish; + + if (arg_directory) { + char *p; + + p = path_make_absolute_cwd(arg_directory); + free(arg_directory); + arg_directory = p; + } else + arg_directory = get_current_dir_name(); + + if (!arg_directory) { + log_error("Failed to determine path"); + goto finish; + } + + path_kill_slashes(arg_directory); + + if (geteuid() != 0) { + log_error("Need to be root."); + goto finish; + } + + if (path_equal(arg_directory, "/")) { + log_error("Spawning constainer on root directory not supported."); + goto finish; + } + + if (is_os_tree(arg_directory) <= 0) { + log_error("Directory %s doesn't look like an OS root directory. Refusing.", arg_directory); + goto finish; + } + + log_info("Spawning namespace container on %s.", arg_directory); + + if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|CLONE_NEWNET, NULL)) < 0) { + log_error("clone() failed: %m"); + goto finish; + } + + if (pid == 0) { + const char *hn; + + /* child */ + + if (mount_all(arg_directory) < 0) + goto child_fail; + + if (copy_devnodes(arg_directory) < 0) + goto child_fail; + + if (chdir(arg_directory) < 0) { + log_error("chdir(%s) failed: %m", arg_directory); + goto child_fail; + } + if (mount(arg_directory, "/", "bind", MS_BIND|MS_MOVE, NULL) < 0) { + log_error("mount(MS_MOVE) failed: %m"); + goto child_fail; + } + + if (chroot(".") < 0) { + log_error("chroot() failed: %m"); + goto child_fail; + } + + if (chdir("/") < 0) { + log_error("chdir() failed: %m"); + goto child_fail; + } + + if (drop_capabilities() < 0) + goto child_fail; + + if ((hn = file_name_from_path(arg_directory))) + sethostname(hn, strlen(hn)); + + if (argc > optind) + execvp(argv[optind], argv + optind); + else + execl("/bin/bash", "/bin/bash", NULL); + + log_error("execv() failed: %m"); + + child_fail: + _exit(EXIT_FAILURE); + } + + r = wait_for_terminate_and_warn("container", pid); + + if (r < 0) + r = EXIT_FAILURE; + +finish: + free(arg_directory); + + if (pid > 0) + kill(pid, SIGTERM); + + return r; +} From 91b22f21f3824c1766d34f622c5bbb70cbe881a8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 03:10:09 +0100 Subject: [PATCH 030/200] core: move abstract namespace sockets to /dev/.run Now that we have /dev/.run there's no need to use abstract namespace sockets. So, let's move things to /dev/.run, to make things more easily discoverable and improve compat with chroot() and fs namespacing. --- man/systemd.xml | 8 ++++---- src/cgroups-agent.c | 15 ++++++++++++--- src/dbus-common.c | 12 ++++++++++-- src/dbus.c | 2 +- src/execute.c | 4 ++-- src/execute.h | 2 +- src/manager.c | 15 +++++++++++---- src/service.c | 2 +- src/systemctl.c | 4 ++-- units/systemd-logger.socket | 2 +- units/systemd-shutdownd.socket | 2 +- 11 files changed, 46 insertions(+), 22 deletions(-) diff --git a/man/systemd.xml b/man/systemd.xml index 6b1a4c9d9..5a4c4ab9c 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -1024,7 +1024,7 @@ - @/org/freedesktop/systemd1/notify + /var/run/systemd/notify Daemon status notification socket. This is an AF_UNIX @@ -1037,7 +1037,7 @@ - @/org/freedesktop/systemd1/logger + /var/run/systemd/logger Used internally by the systemd-logger.service @@ -1050,7 +1050,7 @@ - @/org/freedesktop/systemd1/shutdown + /var/run/systemd/shutdownd Used internally by the shutdown8 @@ -1061,7 +1061,7 @@ - @/org/freedesktop/systemd1/private + /var/run/systemd/private Used internally as communication channel between diff --git a/src/cgroups-agent.c b/src/cgroups-agent.c index 7b4fca245..18612eca3 100644 --- a/src/cgroups-agent.c +++ b/src/cgroups-agent.c @@ -49,10 +49,19 @@ int main(int argc, char *argv[]) { * this to avoid an activation loop when we start dbus when we * are called when the dbus service is shut down. */ - if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", &error))) { - log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); - goto finish; + if (!(bus = dbus_connection_open_private("unix:path=/dev/.run/systemd/private", &error))) { +#ifndef LEGACY + dbus_error_free(&error); + + /* Retry with the pre v21 socket name, to ease upgrades */ + if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", &error))) { +#endif + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto finish; + } +#ifndef LEGACY } +#endif if (bus_check_peercred(bus) < 0) { log_error("Bus owner not root."); diff --git a/src/dbus-common.c b/src/dbus-common.c index 25b718ec0..bb9cf2e2a 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -104,8 +104,16 @@ int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private, DBusError * /* If we are root, then let's not go via the bus */ if (geteuid() == 0 && t == DBUS_BUS_SYSTEM) { - if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", error))) - return -EIO; + + if (!(bus = dbus_connection_open_private("unix:path=/dev/.run/systemd/private", error))) { +#ifndef LEGACY + dbus_error_free(error); + + /* Retry with the pre v21 socket name, to ease upgrades */ + if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", error))) +#endif + return -EIO; + } dbus_connection_set_exit_on_disconnect(bus, FALSE); diff --git a/src/dbus.c b/src/dbus.c index af03c5746..31e776fc3 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -955,7 +955,7 @@ static int bus_init_private(Manager *m) { if (getpid() != 1) return 0; - if (!(m->private_bus = dbus_server_listen("unix:abstract=/org/freedesktop/systemd1/private", &error))) { + if (!(m->private_bus = dbus_server_listen("unix:path=/dev/.run/systemd/private", &error))) { log_error("Failed to create private D-Bus server: %s", error.message); r = -EIO; goto fail; diff --git a/src/execute.c b/src/execute.c index ee05e9944..556ff9bda 100644 --- a/src/execute.c +++ b/src/execute.c @@ -173,9 +173,9 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons zero(sa); sa.sa.sa_family = AF_UNIX; - strncpy(sa.un.sun_path+1, LOGGER_SOCKET, sizeof(sa.un.sun_path)-1); + strncpy(sa.un.sun_path, LOGGER_SOCKET, sizeof(sa.un.sun_path)); - if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + sizeof(LOGGER_SOCKET) - 1) < 0) { + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + sizeof(LOGGER_SOCKET) - 1) < 0) { close_nointr_nofail(fd); return -errno; } diff --git a/src/execute.h b/src/execute.h index 2856d2f33..e77cdcf0b 100644 --- a/src/execute.h +++ b/src/execute.h @@ -40,7 +40,7 @@ struct CGroupBonding; #include "util.h" /* Abstract namespace! */ -#define LOGGER_SOCKET "/org/freedesktop/systemd1/logger" +#define LOGGER_SOCKET "/dev/.run/systemd/logger" /* This doesn't really belong here, but I couldn't find a better place to put this. */ #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT diff --git a/src/manager.c b/src/manager.c index 8bbde7c38..6ccb03fab 100644 --- a/src/manager.c +++ b/src/manager.c @@ -66,7 +66,8 @@ #define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC) /* Where clients shall send notification messages to */ -#define NOTIFY_SOCKET "/org/freedesktop/systemd1/notify" +#define NOTIFY_SOCKET_SYSTEM "/dev/.run/systemd/notify" +#define NOTIFY_SOCKET_USER "@/org/freedesktop/systemd1/notify" static int manager_setup_notify(Manager *m) { union { @@ -88,9 +89,12 @@ static int manager_setup_notify(Manager *m) { sa.sa.sa_family = AF_UNIX; if (getpid() != 1) - snprintf(sa.un.sun_path+1, sizeof(sa.un.sun_path)-1, NOTIFY_SOCKET "/%llu", random_ull()); + snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET_USER "/%llu", random_ull()); else - strncpy(sa.un.sun_path+1, NOTIFY_SOCKET, sizeof(sa.un.sun_path)-1); + strncpy(sa.un.sun_path, NOTIFY_SOCKET_SYSTEM, sizeof(sa.un.sun_path)); + + if (sa.un.sun_path[0] == '@') + sa.un.sun_path[0] = 0; if (bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { log_error("bind() failed: %m"); @@ -109,7 +113,10 @@ static int manager_setup_notify(Manager *m) { if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0) return -errno; - if (!(m->notify_socket = strdup(sa.un.sun_path+1))) + if (sa.un.sun_path[0] == 0) + sa.un.sun_path[0] = '@'; + + if (!(m->notify_socket = strdup(sa.un.sun_path))) return -ENOMEM; log_debug("Using notification socket %s", m->notify_socket); diff --git a/src/service.c b/src/service.c index 70999f354..e7a9e7c58 100644 --- a/src/service.c +++ b/src/service.c @@ -1659,7 +1659,7 @@ static int service_spawn( } if (set_notify_socket) - if (asprintf(our_env + n_env++, "NOTIFY_SOCKET=@%s", s->meta.manager->notify_socket) < 0) { + if (asprintf(our_env + n_env++, "NOTIFY_SOCKET=%s", s->meta.manager->notify_socket) < 0) { r = -ENOMEM; goto fail; } diff --git a/src/systemctl.c b/src/systemctl.c index b8af654e0..5db094fc1 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -5364,7 +5364,7 @@ static int send_shutdownd(usec_t t, char mode, bool warn, const char *message) { zero(sockaddr); sockaddr.sa.sa_family = AF_UNIX; sockaddr.un.sun_path[0] = 0; - strncpy(sockaddr.un.sun_path+1, "/org/freedesktop/systemd1/shutdownd", sizeof(sockaddr.un.sun_path)-1); + strncpy(sockaddr.un.sun_path, "/dev/.run/systemd/shutdownd", sizeof(sockaddr.un.sun_path)); zero(iovec); iovec.iov_base = (char*) &c; @@ -5372,7 +5372,7 @@ static int send_shutdownd(usec_t t, char mode, bool warn, const char *message) { zero(msghdr); msghdr.msg_name = &sockaddr; - msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + 1 + sizeof("/org/freedesktop/systemd1/shutdownd") - 1; + msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + sizeof("/dev/.run/systemd/shutdownd") - 1; msghdr.msg_iov = &iovec; msghdr.msg_iovlen = 1; diff --git a/units/systemd-logger.socket b/units/systemd-logger.socket index 57244a287..5cf6a9b0b 100644 --- a/units/systemd-logger.socket +++ b/units/systemd-logger.socket @@ -13,4 +13,4 @@ DefaultDependencies=no Before=sockets.target [Socket] -ListenStream=@/org/freedesktop/systemd1/logger +ListenStream=/dev/.run/systemd/logger diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket index 0df24cff7..6faf36f0e 100644 --- a/units/systemd-shutdownd.socket +++ b/units/systemd-shutdownd.socket @@ -13,4 +13,4 @@ DefaultDependencies=no Before=sockets.target [Socket] -ListenDatagram=@/org/freedesktop/systemd1/shutdownd +ListenDatagram=/dev/.run/systemd/shutdownd From 6df6b93910da6cf501325d861fcf2d7f8b8bf556 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 03:12:04 +0100 Subject: [PATCH 031/200] nspawn: improve exit warning --- src/nspawn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nspawn.c b/src/nspawn.c index 4e4d40ea6..fa70e86c4 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -366,7 +366,7 @@ int main(int argc, char *argv[]) { } if (path_equal(arg_directory, "/")) { - log_error("Spawning constainer on root directory not supported."); + log_error("Spawning container on root directory not supported."); goto finish; } @@ -429,7 +429,7 @@ int main(int argc, char *argv[]) { _exit(EXIT_FAILURE); } - r = wait_for_terminate_and_warn("container", pid); + r = wait_for_terminate_and_warn(argc > optind ? argv[optind] : "bash", pid); if (r < 0) r = EXIT_FAILURE; From 94d8298589f06de596fbc0a4bc9b50072a2a0536 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 03:27:28 +0100 Subject: [PATCH 032/200] nspawn: define MS_MOVE manually if needed --- src/missing.h | 4 ++++ src/nspawn.c | 1 + 2 files changed, 5 insertions(+) diff --git a/src/missing.h b/src/missing.h index ff5dcb409..c0cb3eaea 100644 --- a/src/missing.h +++ b/src/missing.h @@ -122,4 +122,8 @@ struct btrfs_ioctl_vol_args { #define BTRFS_SUPER_MAGIC 0x9123683E #endif +#ifndef MS_MOVE +#define MS_MOVE 8192 +#endif + #endif diff --git a/src/nspawn.c b/src/nspawn.c index fa70e86c4..bf4e6de2a 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -36,6 +36,7 @@ #include "log.h" #include "util.h" +#include "missing.h" static char *arg_directory = NULL; From 124640f177c118b096ed2c531a4617d52a283395 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 03:28:00 +0100 Subject: [PATCH 033/200] nspawn: reset umask if needed --- src/nspawn.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nspawn.c b/src/nspawn.c index bf4e6de2a..82b0ce4f1 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -176,6 +176,9 @@ static int copy_devnodes(const char *dest) { int r = 0, k; char *tty = NULL; dev_t tty_devnum; + mode_t u; + + u = umask(0000); NULSTR_FOREACH(d, devnodes) { char *from = NULL, *to = NULL; @@ -265,6 +268,8 @@ static int copy_devnodes(const char *dest) { free(tty); + umask(u); + return r; } From da5b3bad1cadb9d9062d01a17056ec085fb725f9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 03:28:16 +0100 Subject: [PATCH 034/200] nspawn: reset environment and load login shell --- src/nspawn.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/nspawn.c b/src/nspawn.c index 82b0ce4f1..297bb61f6 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -390,6 +390,11 @@ int main(int argc, char *argv[]) { if (pid == 0) { const char *hn; + const char *envp[] = { + "HOME=/root", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + NULL + }; /* child */ @@ -425,9 +430,11 @@ int main(int argc, char *argv[]) { sethostname(hn, strlen(hn)); if (argc > optind) - execvp(argv[optind], argv + optind); - else - execl("/bin/bash", "/bin/bash", NULL); + execvpe(argv[optind], argv + optind, (char**) envp); + else { + chdir("/root"); + execle("/bin/bash", "-bash", NULL, (char**) envp); + } log_error("execv() failed: %m"); From ef2df9f41541a62fb7876b98701ab072b41325e2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 04:07:52 +0100 Subject: [PATCH 035/200] util: add detect_container() --- src/util.c | 80 +++++++++++++++++++++++++++++++----------------------- src/util.h | 1 + 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/util.c b/src/util.c index 38d630e6a..eefd66e8c 100644 --- a/src/util.c +++ b/src/util.c @@ -3945,33 +3945,32 @@ int detect_vm(const char **id) { return 0; } -/* Returns a short identifier for the various VM/container implementations */ -int detect_virtualization(const char **id) { - int r; - static __thread const char *cached_id = NULL; - const char *_id; +int detect_container(const char **id) { FILE *f; - if (cached_id) { + /* Unfortunately many of these operations require root access + * in one way or another */ - if (cached_id == (const char*) -1) - return 0; + if (geteuid() != 0) + return -EPERM; + + if (running_in_chroot() > 0) { if (id) - *id = cached_id; + *id = "chroot"; return 1; } - /* Unfortunately most of these operations require root access - * in one way or another */ - if (geteuid() != 0) - return -EPERM; + /* /proc/vz exists in container and outside of the container, + * /proc/bc only outside of the container. */ + if (access("/proc/vz", F_OK) >= 0 && + access("/proc/bc", F_OK) < 0) { - if ((r = running_in_chroot()) > 0) { - _id = "chroot"; - r = 1; - goto finish; + if (id) + *id = "openvz"; + + return 1; } if ((f = fopen("/proc/self/cgroup", "r"))) { @@ -3991,36 +3990,49 @@ int detect_virtualization(const char **id) { if (!streq(p, ":ns:/")) { fclose(f); - r = 1; - _id = "ns"; - goto finish; + if (id) + *id = "ns"; + + return 1; } } fclose(f); } - /* /proc/vz exists in container and outside of the container, - * /proc/bc only outside of the container. */ - if (access("/proc/vz", F_OK) >= 0 && - access("/proc/bc", F_OK) < 0) { - _id = "openvz"; - r = 1; - goto finish; + return 0; +} + +/* Returns a short identifier for the various VM/container implementations */ +int detect_virtualization(const char **id) { + static __thread const char *cached_id = NULL; + const char *_id; + int r; + + if (cached_id) { + + if (cached_id == (const char*) -1) + return 0; + + if (id) + *id = cached_id; + + return 1; } + if ((r = detect_container(&_id)) != 0) + goto finish; + r = detect_vm(&_id); finish: - if (r < 0) - return r; - else if (r > 0) + if (r > 0) { cached_id = _id; - else - cached_id = (const char*) -1; - if (id) - *id = _id; + if (id) + *id = _id; + } else if (r == 0) + cached_id = (const char*) -1; return r; } diff --git a/src/util.h b/src/util.h index 320bcd7c3..192ebff1f 100644 --- a/src/util.h +++ b/src/util.h @@ -380,6 +380,7 @@ bool tty_is_vc(const char *tty); const char *default_term_for_tty(const char *tty); int detect_vm(const char **id); +int detect_container(const char **id); int detect_virtualization(const char **id); void execute_directory(const char *directory, DIR *_d, char *argv[]); From b770165a4f54fed39221bcf33e9d040c12d04fcc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 04:08:12 +0100 Subject: [PATCH 036/200] main: don't parse /proc/cmdline in containers --- src/main.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 54ebb0b08..313afcce1 100644 --- a/src/main.c +++ b/src/main.c @@ -546,6 +546,11 @@ static int parse_proc_cmdline(void) { int r; size_t l; + /* Don't read /proc/cmdline if we are in a container, since + * that is only relevant for the host system */ + if (detect_container(NULL) > 0) + return 0; + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); return 0; @@ -626,6 +631,9 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 1); assert(argv); + if (getpid() == 1) + opterr = 0; + while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0) switch (c) { @@ -820,13 +828,30 @@ static int parse_argv(int argc, char *argv[]) { break; } - /* PID 1 will get the kernel arguments as parameters, which we - * ignore and unconditionally read from - * /proc/cmdline. However, we need to ignore those arguments - * here. */ - if (getpid() != 1 && optind < argc) { - log_error("Excess arguments."); - return -EINVAL; + if (optind < argc) { + if (getpid() != 1) { + /* Hmm, when we aren't run as init system + * let's complain about excess arguments */ + + log_error("Excess arguments."); + return -EINVAL; + + } else if (detect_container(NULL) > 0) { + char **a; + + /* All /proc/cmdline arguments the kernel + * didn't understand it passed to us. We're + * note really interested in that usually + * since /proc/cmdline is more interesting and + * complete. With one exception: if we are run + * in a container /proc/cmdline is not + * relevant for us, hence we rely on argv[] + * instead. */ + + for (a = argv + optind; a < argv + argc; a++) + if ((r = parse_proc_cmdline_word(*a)) < 0) + return r; + } } return 0; @@ -1093,6 +1118,9 @@ int main(int argc, char *argv[]) { * kernel that don't really make sense for us. */ unsetenv("HOME"); unsetenv("TERM"); + + /* All other variables are left as is, so that clients + * can still read them via /proc/1/environ */ } /* Move out of the way, so that we won't block unmounts */ From 90df7e567f668b4d0e7761fd15fa8cebffc759a0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 04:48:14 +0100 Subject: [PATCH 037/200] main: log to the console in a container --- src/main.c | 2 +- src/nspawn.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 313afcce1..0c805c98a 100644 --- a/src/main.c +++ b/src/main.c @@ -1021,7 +1021,7 @@ int main(int argc, char *argv[]) { if (getpid() == 1) { arg_running_as = MANAGER_SYSTEM; - log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); + log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_SYSLOG_OR_KMSG); /* This might actually not return, but cause a * reexecution */ diff --git a/src/nspawn.c b/src/nspawn.c index 297bb61f6..f340805f3 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -254,7 +254,7 @@ static int copy_devnodes(const char *dest) { r = -errno; } - if (mount(from, to, "bind", MS_BIND, NULL) < 0) { + if (mount(from, to, "bind", MS_BIND|MS_RDONLY, NULL) < 0) { log_error("bind mount for /dev/console failed: %m"); if (r == 0) From 64af1b6207e4062e43f049a4f322ffa4de9dd87f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 05:36:43 +0100 Subject: [PATCH 038/200] nspawn: we don't want a network namespace --- src/nspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nspawn.c b/src/nspawn.c index f340805f3..7cefd3deb 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -383,7 +383,7 @@ int main(int argc, char *argv[]) { log_info("Spawning namespace container on %s.", arg_directory); - if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|CLONE_NEWNET, NULL)) < 0) { + if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS, NULL)) < 0) { log_error("clone() failed: %m"); goto finish; } From 973bcd30bfd8c5d6d28d40075ae9b2561f9d3e2a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 05:37:14 +0100 Subject: [PATCH 039/200] socket: use 777 as default mode for sockets --- src/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.c b/src/socket.c index 77bbe43ee..130f51c07 100644 --- a/src/socket.c +++ b/src/socket.c @@ -67,7 +67,7 @@ static void socket_init(Unit *u) { s->backlog = SOMAXCONN; s->timeout_usec = DEFAULT_TIMEOUT_USEC; s->directory_mode = 0755; - s->socket_mode = 0666; + s->socket_mode = 0777; s->max_connections = 64; From c4f8bd1aef96063ccc2121fe2429a933a0b2068d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 05:37:47 +0100 Subject: [PATCH 040/200] umount: assume that a non-existing /dev/loop device means it is already detached --- src/umount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umount.c b/src/umount.c index 4fd6b22ad..6fe0a26dd 100644 --- a/src/umount.c +++ b/src/umount.c @@ -355,7 +355,7 @@ static int delete_loopback(const char *device) { int fd, r; if ((fd = open(device, O_RDONLY|O_CLOEXEC)) < 0) - return -errno; + return errno == ENOENT ? 0 : -errno; r = ioctl(fd, LOOP_CLR_FD, 0); close_nointr_nofail(fd); From 40e85d00198c4d9305bbfc794b384f8174fae300 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 05:40:15 +0100 Subject: [PATCH 041/200] shutdown: just call exit() if we are in a container --- src/shutdown.c | 158 +++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 85 deletions(-) diff --git a/src/shutdown.c b/src/shutdown.c index 5c082cf4a..df2d850af 100644 --- a/src/shutdown.c +++ b/src/shutdown.c @@ -96,125 +96,107 @@ static int killall(int sign) { return n_processes; } -static int send_signal(int sign) { - sigset_t mask, oldmask; +static void wait_for_children(int n_processes, sigset_t *mask) { usec_t until; + + assert(mask); + + until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC; + for (;;) { + struct timespec ts; + int k; + usec_t n; + + for (;;) { + pid_t pid = waitpid(-1, NULL, WNOHANG); + + if (pid == 0) + break; + + if (pid < 0 && errno == ECHILD) + return; + + if (n_processes > 0) + if (--n_processes == 0) + return; + } + + n = now(CLOCK_MONOTONIC); + if (n >= until) + return; + + timespec_store(&ts, until - n); + + if ((k = sigtimedwait(mask, NULL, &ts)) != SIGCHLD) { + + if (k < 0 && errno != EAGAIN) { + log_error("sigtimedwait() failed: %m"); + return; + } + + if (k >= 0) + log_warning("sigtimedwait() returned unexpected signal."); + } + } +} + +static void send_signal(int sign) { + sigset_t mask, oldmask; int n_processes; - struct timespec ts; assert_se(sigemptyset(&mask) == 0); assert_se(sigaddset(&mask, SIGCHLD) == 0); - if (sigprocmask(SIG_BLOCK, &mask, &oldmask) != 0) - return -errno; + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); - if (kill(-1, SIGSTOP) < 0) + if (kill(-1, SIGSTOP) < 0 && errno != ESRCH) log_warning("kill(-1, SIGSTOP) failed: %m"); n_processes = killall(sign); - if (kill(-1, SIGCONT) < 0) + if (kill(-1, SIGCONT) < 0 && errno != ESRCH) log_warning("kill(-1, SIGCONT) failed: %m"); if (n_processes <= 0) goto finish; - until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC; - for (;;) { - int k; - usec_t n = now(CLOCK_MONOTONIC); - - for (;;) { - pid_t pid = waitpid(-1, NULL, WNOHANG); - - if (pid == 0) - break; - else if (pid < 0 && errno == ECHILD) { - n_processes = 0; - goto finish; - } - - if (--n_processes == 0) - goto finish; - } - - if (n >= until) - goto finish; - - timespec_store(&ts, until - n); - if ((k = sigtimedwait(&mask, NULL, &ts)) != SIGCHLD) { - if (k >= 0) - log_warning("sigtimedwait() returned unexpected signal."); - if (k < 0 && errno != EAGAIN) - log_warning("sigtimedwait() failed: %m"); - } - } + wait_for_children(n_processes, &mask); finish: sigprocmask(SIG_SETMASK, &oldmask, NULL); - - return n_processes; } -static int rescue_send_signal(int sign) { +static void ultimate_send_signal(int sign) { sigset_t mask, oldmask; - usec_t until; - struct timespec ts; int r; - sigemptyset(&mask); - sigaddset(&mask, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &mask, &oldmask) != 0) - return -errno; + assert_se(sigemptyset(&mask) == 0); + assert_se(sigaddset(&mask, SIGCHLD) == 0); + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); - if (kill(-1, SIGSTOP) < 0) + if (kill(-1, SIGSTOP) < 0 && errno != ESRCH) log_warning("kill(-1, SIGSTOP) failed: %m"); r = kill(-1, sign); - if (r < 0) - log_warning("kill(-1, %d) failed: %m", sign); + if (r < 0 && errno != ESRCH) + log_warning("kill(-1, %s) failed: %m", signal_to_string(sign)); - if (kill(-1, SIGCONT) < 0) + if (kill(-1, SIGCONT) < 0 && errno != ESRCH) log_warning("kill(-1, SIGCONT) failed: %m"); if (r < 0) goto finish; - until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC; - for (;;) { - int k; - usec_t n = now(CLOCK_MONOTONIC); - - for (;;) { - pid_t pid = waitpid(-1, NULL, WNOHANG); - if (pid == 0) - break; - else if (pid < 0 && errno == ECHILD) - goto finish; - } - - if (n >= until) - goto finish; - - timespec_store(&ts, until - n); - if ((k = sigtimedwait(&mask, NULL, &ts)) != SIGCHLD) { - if (k >= 0) - log_warning("sigtimedwait() returned unexpected signal."); - if (k < 0 && errno != EAGAIN) - log_warning("sigtimedwait() failed: %m"); - } - } + wait_for_children(0, &mask); finish: sigprocmask(SIG_SETMASK, &oldmask, NULL); - - return r; } int main(int argc, char *argv[]) { int cmd, r; unsigned retries; bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true; - bool killed_everbody = false; + bool killed_everbody = false, in_container; log_parse_environment(); log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */ @@ -232,6 +214,8 @@ int main(int argc, char *argv[]) { goto error; } + in_container = detect_container(NULL) > 0; + if (streq(argv[1], "reboot")) cmd = RB_AUTOBOOT; else if (streq(argv[1], "poweroff")) @@ -251,14 +235,13 @@ int main(int argc, char *argv[]) { log_warning("Cannot lock process memory: %m"); log_info("Sending SIGTERM to remaining processes..."); - r = send_signal(SIGTERM); - if (r < 0) - log_warning("Failed to send SIGTERM to remaining processes: %s", strerror(r)); + send_signal(SIGTERM); log_info("Sending SIGKILL to remaining processes..."); - r = send_signal(SIGKILL); - if (r < 0) - log_warning("Failed to send SIGKILL to remaining processes: %s", strerror(r)); + send_signal(SIGKILL); + + if (in_container) + need_swapoff = false; /* Unmount all mountpoints, swaps, and loopback devices */ for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) { @@ -325,8 +308,8 @@ int main(int argc, char *argv[]) { } log_warning("Cannot finalize remaining file systems and devices, trying to kill remaining processes."); - rescue_send_signal(SIGTERM); - rescue_send_signal(SIGKILL); + ultimate_send_signal(SIGTERM); + ultimate_send_signal(SIGKILL); killed_everbody = true; } @@ -338,6 +321,11 @@ int main(int argc, char *argv[]) { execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, NULL); + /* If we are in a container, just exit, this will kill our + * container for good. */ + if (in_container) + exit(0); + sync(); if (cmd == LINUX_REBOOT_CMD_KEXEC) { From 9b634ea5fb7cb5466f1f7873204bd67d02652981 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 15:33:23 +0100 Subject: [PATCH 042/200] nspawn: mount /selinux if needed --- src/nspawn.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/nspawn.c b/src/nspawn.c index 7cefd3deb..a053a4d55 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -104,13 +104,16 @@ static int mount_all(const char *dest) { } MountPoint; static const MountPoint mount_table[] = { - { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, - { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND }, /* Bind mount first */ - { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT }, /* Then, make it r/o */ - { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY }, - { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID }, - { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND }, - { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV }, + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, + { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND }, /* Bind mount first */ + { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT }, /* Then, make it r/o */ + { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY }, + { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID }, + { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND }, + { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV }, +#ifdef HAVE_SELINUX + { "selinux", "/selinux", "selinuxfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY }, +#endif }; unsigned k; From f41de9596627ef68fcb4c0dae4b9bd8033701230 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 15:33:39 +0100 Subject: [PATCH 043/200] shutdown: print a nice message when terminating a container --- src/shutdown.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shutdown.c b/src/shutdown.c index df2d850af..a2f3b539b 100644 --- a/src/shutdown.c +++ b/src/shutdown.c @@ -323,8 +323,10 @@ int main(int argc, char *argv[]) { /* If we are in a container, just exit, this will kill our * container for good. */ - if (in_container) + if (in_container) { + log_error("Exiting container."); exit(0); + } sync(); From 6f79c579ec9c188173dde41395bbfb86c547fdd3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 16:15:31 +0100 Subject: [PATCH 044/200] main: remove AF_UNIX sockets before binding --- src/dbus.c | 1 + src/manager.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dbus.c b/src/dbus.c index 31e776fc3..7afb0fb5e 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -955,6 +955,7 @@ static int bus_init_private(Manager *m) { if (getpid() != 1) return 0; + unlink("/dev/.run/systemd/private"); if (!(m->private_bus = dbus_server_listen("unix:path=/dev/.run/systemd/private", &error))) { log_error("Failed to create private D-Bus server: %s", error.message); r = -EIO; diff --git a/src/manager.c b/src/manager.c index 6ccb03fab..1ab4c94ee 100644 --- a/src/manager.c +++ b/src/manager.c @@ -90,8 +90,10 @@ static int manager_setup_notify(Manager *m) { if (getpid() != 1) snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET_USER "/%llu", random_ull()); - else + else { + unlink(NOTIFY_SOCKET_SYSTEM); strncpy(sa.un.sun_path, NOTIFY_SOCKET_SYSTEM, sizeof(sa.un.sun_path)); + } if (sa.un.sun_path[0] == '@') sa.un.sun_path[0] = 0; From 3bd66c05d5d775a82768e0772c83a7300baee366 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 17:44:03 +0100 Subject: [PATCH 045/200] nspawn: don't require selinux on if it is compiled in --- src/nspawn.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/nspawn.c b/src/nspawn.c index a053a4d55..451d53962 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -101,18 +101,19 @@ static int mount_all(const char *dest) { const char *type; const char *options; unsigned long flags; + bool fatal; } MountPoint; static const MountPoint mount_table[] = { - { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, - { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND }, /* Bind mount first */ - { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT }, /* Then, make it r/o */ - { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY }, - { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID }, - { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND }, - { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV }, + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND, true }, /* Bind mount first */ + { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */ + { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true }, + { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID, true }, + { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND, true }, + { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, #ifdef HAVE_SELINUX - { "selinux", "/selinux", "selinuxfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY }, + { "selinux", "/selinux", "selinuxfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false }, #endif }; @@ -148,7 +149,8 @@ static int mount_all(const char *dest) { where, mount_table[k].type, mount_table[k].flags, - mount_table[k].options) < 0) { + mount_table[k].options) < 0 && + mount_table[k].fatal) { log_error("mount(%s) failed: %m", where); From 391ade86065cb56e9f4bec0c21f2e22ec7880369 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 17:48:34 +0100 Subject: [PATCH 046/200] audit: give up sending auditing messages when it failed due to EPERM --- src/manager.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/manager.c b/src/manager.c index 1ab4c94ee..cee434466 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2448,8 +2448,19 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) { return; } - if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) - log_error("Failed to send audit message: %m"); + if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) { + log_warning("Failed to send audit message: %m"); + + if (errno == EPERM) { + /* We aren't allowed to send audit messages? + * Then let's not retry again, to avoid + * spamming the user with the same and same + * messages over and over. */ + + audit_close(m->audit_fd); + m->audit_fd = -1; + } + } free(p); #endif From 9bec0b1e8d4a0cf971c113fe880deba2f9feae24 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 18:05:52 +0100 Subject: [PATCH 047/200] hostname: don't override the hostname with localhost if it is already set and /etc/hostname unset --- src/hostname-setup.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/hostname-setup.c b/src/hostname-setup.c index ef68d7839..e9869bb4d 100644 --- a/src/hostname-setup.c +++ b/src/hostname-setup.c @@ -174,16 +174,36 @@ int hostname_setup(void) { else log_warning("Failed to read configured hostname: %s", strerror(-r)); - hn = "localhost"; + hn = NULL; } else hn = b; + if (!hn) { + /* Don't override the hostname if it is unset and not + * explicitly configured */ + + char *old_hostname = NULL; + + if ((old_hostname = gethostname_malloc())) { + bool already_set; + + already_set = old_hostname[0] != 0; + free(old_hostname); + + if (already_set) + goto finish; + } + + hn = "localhost"; + } + if (sethostname(hn, strlen(hn)) < 0) { log_warning("Failed to set hostname to <%s>: %m", hn); r = -errno; } else log_info("Set hostname to <%s>.", hn); +finish: free(b); return r; From a5f9be457957731f6bd21bf60dd182fb2a6278cf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 18:17:28 +0100 Subject: [PATCH 048/200] build-sys: move remaining tools from sbin/ to bin/ since they might eventually be useful for user execution --- Makefile.am | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7d6cfd12d..a2e40c3fd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -106,16 +106,12 @@ rootbin_PROGRAMS = \ systemd-notify \ systemd-ask-password \ systemd-tty-ask-password-agent \ - systemd-tmpfiles - -rootsbin_PROGRAMS = \ + systemd-tmpfiles \ systemd-machine-id-setup bin_PROGRAMS = \ systemd-cgls \ - systemd-stdio-bridge - -sbin_PROGRAMS = \ + systemd-stdio-bridge \ systemd-nspawn if HAVE_GTK From 1063dc3a525a87c0285e071794317f71724492fe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 21:00:53 +0100 Subject: [PATCH 049/200] units: add console-shell.service which can be used insted of the gettys to get a shell on /dev/console --- Makefile.am | 2 ++ TODO | 2 ++ units/.gitignore | 1 + units/console-shell.service.m4 | 41 ++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 units/console-shell.service.m4 diff --git a/Makefile.am b/Makefile.am index a2e40c3fd..97c8be35e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -260,6 +260,7 @@ dist_systemunit_DATA = \ nodist_systemunit_DATA = \ units/getty@.service \ units/serial-getty@.service \ + units/console-shell.service \ units/graphical.target \ units/remote-fs.target \ units/multi-user.target \ @@ -304,6 +305,7 @@ nodist_userunit_DATA = \ EXTRA_DIST = \ units/getty@.service.m4 \ units/serial-getty@.service.m4 \ + units/console-shell.service.m4 \ units/graphical.target.m4 \ units/multi-user.target.m4 \ units/remote-fs.target.m4 \ diff --git a/TODO b/TODO index 986e06a60..4fc728ffc 100644 --- a/TODO +++ b/TODO @@ -24,6 +24,8 @@ F15: * capability_bounding_set_drop not used. +* remove getty magic, move it into a generator + Features: * optionally create watched directories in .path units diff --git a/units/.gitignore b/units/.gitignore index 008446d4b..a64cac13e 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -1,3 +1,4 @@ +console-shell.service systemd-sysctl.service systemd-ask-password-console.service rescue.service diff --git a/units/console-shell.service.m4 b/units/console-shell.service.m4 new file mode 100644 index 000000000..c98a08fcc --- /dev/null +++ b/units/console-shell.service.m4 @@ -0,0 +1,41 @@ +# 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=Console Shell +After=systemd-user-sessions.service plymouth-quit-wait.service +m4_ifdef(`TARGET_FEDORA', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_ARCH', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_FRUGALWARE', +After=local.service +)m4_dnl +m4_ifdef(`TARGET_ALTLINUX', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_MANDRIVA', +After=rc-local.service +)m4_dnl +Before=getty.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStart=-/sbin/sulogin +ExecStopPost=-/bin/systemctl poweroff +StandardInput=tty-force +KillMode=process-group + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP + +[Install] +WantedBy=getty.target From 72fe22f93059ec6bbc9c9da0171e3be9d8b1c9ce Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 21:27:39 +0100 Subject: [PATCH 050/200] manager: show who killed us --- src/manager.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/manager.c b/src/manager.c index cee434466..919560b05 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2057,6 +2057,8 @@ static int manager_process_signal_fd(Manager *m) { assert(m); for (;;) { + char *p = NULL; + if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) { if (n >= 0) @@ -2068,7 +2070,11 @@ static int manager_process_signal_fd(Manager *m) { return -errno; } - log_debug("Received SIG%s", strna(signal_to_string(sfsi.ssi_signo))); + get_process_name(sfsi.ssi_pid, &p); + log_debug("Received SIG%s from PID %lu (%s)", + strna(signal_to_string(sfsi.ssi_signo)), + (unsigned long) sfsi.ssi_pid, strna(p)); + free(p); switch (sfsi.ssi_signo) { From e03ae6615a1fe9a2aee854d00c3fc7397a06983d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 21:47:41 +0100 Subject: [PATCH 051/200] manager: don't show kernel boot-up time for containers --- TODO | 2 ++ src/manager.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 4fc728ffc..522ef5929 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,8 @@ F15: * remove getty magic, move it into a generator +* recreate private socket on SIGUSR2 + Features: * optionally create watched directories in .path units diff --git a/src/manager.c b/src/manager.c index 919560b05..df75eca8c 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2841,7 +2841,8 @@ void manager_check_finished(Manager *m) { dual_timestamp_get(&m->finish_timestamp); - if (m->running_as == MANAGER_SYSTEM) { + if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) { + 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), From 04d391dabcd860e2d0542ece1d1c7e0a9d9cd0ac Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 22:33:31 +0100 Subject: [PATCH 052/200] nspawn: move container into its own name=systemd cgroup --- Makefile.am | 6 ++++-- src/nspawn.c | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 97c8be35e..6104c809d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -985,13 +985,15 @@ systemd_cgls_LDADD = \ libsystemd-basic.la systemd_nspawn_SOURCES = \ - src/nspawn.c + src/nspawn.c \ + src/cgroup-util.c systemd_nspawn_CFLAGS = \ $(AM_CFLAGS) systemd_nspawn_LDADD = \ - libsystemd-basic.la + libsystemd-basic.la \ + libsystemd-daemon.la systemd_stdio_bridge_SOURCES = \ src/bridge.c diff --git a/src/nspawn.c b/src/nspawn.c index 451d53962..94e03b58d 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -37,6 +37,8 @@ #include "log.h" #include "util.h" #include "missing.h" +#include "cgroup-util.h" +#include "sd-daemon.h" static char *arg_directory = NULL; @@ -347,7 +349,8 @@ static int is_os_tree(const char *path) { int main(int argc, char *argv[]) { pid_t pid = 0; - int r = EXIT_FAILURE; + int r = EXIT_FAILURE, k; + char *oldcg = NULL, *newcg = NULL; log_parse_environment(); log_open(); @@ -376,6 +379,11 @@ int main(int argc, char *argv[]) { goto finish; } + if (sd_booted() <= 0) { + log_error("Not running on a systemd system."); + goto finish; + } + if (path_equal(arg_directory, "/")) { log_error("Spawning container on root directory not supported."); goto finish; @@ -388,6 +396,21 @@ int main(int argc, char *argv[]) { log_info("Spawning namespace container on %s.", arg_directory); + if ((k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg)) < 0) { + log_error("Failed to determine current cgroup: %s", strerror(-k)); + goto finish; + } + + if (asprintf(&newcg, "%s/nspawn-%lu", oldcg, (unsigned long) getpid()) < 0) { + log_error("Failed to allocate cgroup path."); + goto finish; + } + + if ((k = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, newcg, 0)) < 0) { + log_error("Failed to create cgroup: %s", strerror(-k)); + goto finish; + } + if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS, NULL)) < 0) { log_error("clone() failed: %m"); goto finish; @@ -453,10 +476,15 @@ int main(int argc, char *argv[]) { r = EXIT_FAILURE; finish: - free(arg_directory); + if (oldcg) + cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0); - if (pid > 0) - kill(pid, SIGTERM); + if (newcg) + cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true); + + free(arg_directory); + free(oldcg); + free(newcg); return r; } From 1f73f0f163eeb8a889e3799c0c63bcb437e531ac Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 23:13:57 +0100 Subject: [PATCH 053/200] pam: determine user cgroup tree from cgroup of PID 1 --- src/cgroup-util.c | 28 ++++++++++++++++++++++++++++ src/cgroup-util.h | 2 ++ src/pam-module.c | 37 +++++++++++++++++++++++++++---------- src/user-sessions.c | 17 ++++++++++++++--- 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/cgroup-util.c b/src/cgroup-util.c index 055c90610..bbadc789a 100644 --- a/src/cgroup-util.c +++ b/src/cgroup-util.c @@ -967,3 +967,31 @@ int cg_fix_path(const char *path, char **result) { return r; } + +int cg_get_user_path(char **path) { + char *root, *p; + + assert(path); + + /* Figure out the place to put user cgroups below. We use the + * same as PID 1 has but with the "/system" suffix replaced by + * "/user" */ + + if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root) < 0) + p = strdup("/user"); + else { + if (endswith(root, "/system")) + root[strlen(root) - 7] = 0; + else if (streq(root, "/")) + root[0] = 0; + + p = strappend(root, "/user"); + free(root); + } + + if (!p) + return -ENOMEM; + + *path = p; + return 0; +} diff --git a/src/cgroup-util.h b/src/cgroup-util.h index 73df9697e..1eccbc9fd 100644 --- a/src/cgroup-util.h +++ b/src/cgroup-util.h @@ -68,4 +68,6 @@ int cg_install_release_agent(const char *controller, const char *agent); int cg_is_empty(const char *controller, const char *path, bool ignore_self); int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self); +int cg_get_user_path(char **path); + #endif diff --git a/src/pam-module.c b/src/pam-module.c index e1a1a5001..3a5404db4 100644 --- a/src/pam-module.c +++ b/src/pam-module.c @@ -199,10 +199,8 @@ static int open_file_and_lock(const char *fn) { * locally accessible, and most likely even tmpfs. */ if (flock(fd, LOCK_EX) < 0) { - int r = -errno; - close_nointr_nofail(fd); - return r; + return -errno; } return fd; @@ -275,6 +273,7 @@ static uint64_t get_session_id(int *mode) { /* Last attempt, pick a random value */ return (uint64_t) random_ull(); } + static int get_user_data( pam_handle_t *handle, const char **ret_username, @@ -398,6 +397,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( int lock_fd = -1; bool create_session = true; char **controllers = NULL, **reset_controllers = NULL, **c; + char *cgroup_user_tree = NULL; assert(handle); @@ -417,6 +417,12 @@ _public_ PAM_EXTERN int pam_sm_open_session( if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS) goto finish; + if ((r = cg_get_user_path(&cgroup_user_tree)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to determine user cgroup tree: %s", strerror(-r)); + r = PAM_SYSTEM_ERR; + goto finish; + } + if (safe_mkdir(RUNTIME_DIR "/user", 0755, 0, 0) < 0) { pam_syslog(handle, LOG_ERR, "Failed to create runtime directory: %m"); r = PAM_SYSTEM_ERR; @@ -480,9 +486,9 @@ _public_ PAM_EXTERN int pam_sm_open_session( } } - r = asprintf(&buf, "/user/%s/%s", username, id); + r = asprintf(&buf, "%s/%s/%s", cgroup_user_tree, username, id); } else - r = asprintf(&buf, "/user/%s/master", username); + r = asprintf(&buf, "%s/%s/master", cgroup_user_tree, username); if (r < 0) { r = PAM_BUF_ERR; @@ -513,6 +519,8 @@ finish: strv_free(controllers); strv_free(reset_controllers); + free(cgroup_user_tree); + return r; } @@ -604,6 +612,7 @@ _public_ PAM_EXTERN int pam_sm_close_session( struct passwd *pw; const void *created = NULL; char **controllers = NULL, **c, **kill_only_users = NULL, **kill_exclude_users = NULL; + char *cgroup_user_tree = NULL; assert(handle); @@ -621,6 +630,12 @@ _public_ PAM_EXTERN int pam_sm_close_session( if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS) goto finish; + if ((r = cg_get_user_path(&cgroup_user_tree)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to determine user cgroup tree: %s", strerror(-r)); + r = PAM_SYSTEM_ERR; + goto finish; + } + if ((lock_fd = open_file_and_lock(RUNTIME_DIR "/user/.pam-systemd-lock")) < 0) { pam_syslog(handle, LOG_ERR, "Failed to lock runtime directory: %m"); r = PAM_SYSTEM_ERR; @@ -628,14 +643,14 @@ _public_ PAM_EXTERN int pam_sm_close_session( } /* We are probably still in some session/user dir. Move ourselves out of the way as first step */ - if ((r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, "/user", 0)) < 0) + if ((r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, cgroup_user_tree, 0)) < 0) pam_syslog(handle, LOG_ERR, "Failed to move us away: %s", strerror(-r)); STRV_FOREACH(c, controllers) - if ((r = cg_attach(*c, "/user", 0)) < 0) + if ((r = cg_attach(*c, cgroup_user_tree, 0)) < 0) pam_syslog(handle, LOG_ERR, "Failed to move us away in %s hierarchy: %s", *c, strerror(-r)); - if (asprintf(&user_path, "/user/%s", username) < 0) { + if (asprintf(&user_path, "%s/%s", cgroup_user_tree, username) < 0) { r = PAM_BUF_ERR; goto finish; } @@ -644,8 +659,8 @@ _public_ PAM_EXTERN int pam_sm_close_session( if ((id = pam_getenv(handle, "XDG_SESSION_ID")) && created) { - if (asprintf(&session_path, "/user/%s/%s", username, id) < 0 || - asprintf(&nosession_path, "/user/%s/master", username) < 0) { + if (asprintf(&session_path, "%s/%s/%s", cgroup_user_tree, username, id) < 0 || + asprintf(&nosession_path, "%s/%s/master", cgroup_user_tree, username) < 0) { r = PAM_BUF_ERR; goto finish; } @@ -731,5 +746,7 @@ finish: strv_free(kill_exclude_users); strv_free(kill_only_users); + free(cgroup_user_tree); + return r; } diff --git a/src/user-sessions.c b/src/user-sessions.c index 802696156..d3faad0cd 100644 --- a/src/user-sessions.c +++ b/src/user-sessions.c @@ -57,14 +57,25 @@ int main(int argc, char*argv[]) { } else if (streq(argv[1], "stop")) { int r, q; + char *cgroup_user_tree = NULL; if ((r = write_one_line_file("/var/run/nologin", "System is going down.")) < 0) log_error("Failed to create /var/run/nologin: %s", strerror(-r)); - if ((q = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, "/user", true)) < 0) - log_error("Failed to kill sessions: %s", strerror(-q)); + if ((q = cg_get_user_path(&cgroup_user_tree)) < 0) { + log_error("Failed to determine use path: %s", strerror(-q)); + goto finish; + } - if (r < 0 || q < 0) + q = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup_user_tree, true); + free(cgroup_user_tree); + + if (q < 0) { + log_error("Failed to kill sessions: %s", strerror(-q)); + goto finish; + } + + if (r < 0) goto finish; } else { From 1f16b4a6c496288aa62dc2ac973f88ca6c801b5d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 23:40:41 +0100 Subject: [PATCH 054/200] cgls: by default start with group of PID 1 --- src/cgls.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/cgls.c b/src/cgls.c index 93617ddc2..6f083015e 100644 --- a/src/cgls.c +++ b/src/cgls.c @@ -106,8 +106,18 @@ int main(int argc, char *argv[]) { if (path_startswith(p, "/sys/fs/cgroup")) { printf("Working Directory %s:\n", p); r = show_cgroup_by_path(p, NULL, 0); - } else - r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, "/", NULL, 0); + } else { + char *root = NULL; + const char *t = NULL; + + if ((r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root)) < 0) + t = "/"; + else + t = root; + + r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, t, NULL, 0); + free(root); + } free(p); } From 2fc9784656900c4dc3715db506096ddc23fdd87c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Mar 2011 23:41:47 +0100 Subject: [PATCH 055/200] container: skip a few things when we are run in a container such as accessing /proc/cmdline --- src/condition.c | 3 +++ src/fsck.c | 3 +++ src/locale-setup.c | 39 ++++++++++++++++++++------------------- src/quotacheck.c | 3 +++ src/target.c | 3 +++ src/vconsole-setup.c | 25 +++++++++++++------------ 6 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/condition.c b/src/condition.c index 1d6cf12ad..1dce276c0 100644 --- a/src/condition.c +++ b/src/condition.c @@ -67,6 +67,9 @@ static bool test_kernel_command_line(const char *parameter) { assert(parameter); + if (detect_virtualization(NULL) > 0) + return false; + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); return false; diff --git a/src/fsck.c b/src/fsck.c index b5d8764e0..a3c83c3c2 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -106,6 +106,9 @@ static int parse_proc_cmdline(void) { int r; size_t l; + if (detect_virtualization(NULL) > 0) + return 0; + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); return 0; diff --git a/src/locale-setup.c b/src/locale-setup.c index 7684681cc..055c1fa3f 100644 --- a/src/locale-setup.c +++ b/src/locale-setup.c @@ -69,28 +69,29 @@ int locale_setup(void) { zero(variables); - if ((r = parse_env_file("/proc/cmdline", WHITESPACE, + if (detect_virtualization(NULL) <= 0) + if ((r = parse_env_file("/proc/cmdline", WHITESPACE, #ifdef TARGET_FEDORA - "LANG", &variables[VARIABLE_LANG], + "LANG", &variables[VARIABLE_LANG], #endif - "locale.LANG", &variables[VARIABLE_LANG], - "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], - "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], - "locale.LC_TIME", &variables[VARIABLE_LC_TIME], - "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], - "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], - "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], - "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], - "locale.LC_NAME", &variables[VARIABLE_LC_NAME], - "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], - "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], - "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], - "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], - NULL)) < 0) { + "locale.LANG", &variables[VARIABLE_LANG], + "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "locale.LC_TIME", &variables[VARIABLE_LC_TIME], + "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], + "locale.LC_NAME", &variables[VARIABLE_LC_NAME], + "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], + NULL)) < 0) { - if (r != -ENOENT) - log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); - } + if (r != -ENOENT) + log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); + } /* Hmm, nothing set on the kernel cmd line? Then let's * try /etc/locale.conf */ diff --git a/src/quotacheck.c b/src/quotacheck.c index da2da3b2e..057d8617c 100644 --- a/src/quotacheck.c +++ b/src/quotacheck.c @@ -35,6 +35,9 @@ static int parse_proc_cmdline(void) { int r; size_t l; + if (detect_virtualization(NULL) > 0) + return 0; + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); return 0; diff --git a/src/target.c b/src/target.c index e61255c12..b8d4a01b6 100644 --- a/src/target.c +++ b/src/target.c @@ -92,6 +92,9 @@ static int target_add_getty_dependencies(Target *t) { if (!unit_has_name(UNIT(t), SPECIAL_GETTY_TARGET)) return 0; + if (detect_container(NULL) > 0) + return 1; + if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { const char *tty; diff --git a/src/vconsole-setup.c b/src/vconsole-setup.c index 5b977126f..29ce7be77 100644 --- a/src/vconsole-setup.c +++ b/src/vconsole-setup.c @@ -176,21 +176,22 @@ int main(int argc, char **argv) { utf8 = is_locale_utf8(); - if ((r = parse_env_file("/proc/cmdline", WHITESPACE, + if (detect_virtualization(NULL) <= 0) + if ((r = parse_env_file("/proc/cmdline", WHITESPACE, #ifdef TARGET_FEDORA - "SYSFONT", &vc_font, - "KEYTABLE", &vc_keymap, + "SYSFONT", &vc_font, + "KEYTABLE", &vc_keymap, #endif - "vconsole.keymap", &vc_keymap, - "vconsole.keymap.toggle", &vc_keymap_toggle, - "vconsole.font", &vc_font, - "vconsole.font.map", &vc_font_map, - "vconsole.font.unimap", &vc_font_unimap, - NULL)) < 0) { + "vconsole.keymap", &vc_keymap, + "vconsole.keymap.toggle", &vc_keymap_toggle, + "vconsole.font", &vc_font, + "vconsole.font.map", &vc_font_map, + "vconsole.font.unimap", &vc_font_unimap, + NULL)) < 0) { - if (r != -ENOENT) - log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); - } + if (r != -ENOENT) + log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); + } /* Hmm, nothing set on the kernel cmd line? Then let's * try /etc/vconsole.conf */ From 2a796654b9a1f84962e5dafbcf171dcc22742c99 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 15 Mar 2011 00:44:13 +0100 Subject: [PATCH 056/200] getty: move automatic serial getty logic into generator --- .gitignore | 1 + Makefile.am | 15 ++++- TODO | 2 - src/cryptsetup-generator.c | 3 +- src/getty-generator.c | 127 +++++++++++++++++++++++++++++++++++++ src/special.h | 2 - src/target.c | 67 ------------------- 7 files changed, 144 insertions(+), 73 deletions(-) create mode 100644 src/getty-generator.c diff --git a/.gitignore b/.gitignore index d679f791e..7213a8ba9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +systemd-getty-generator systemd-nspawn systemd-stdio-bridge systemd-machine-id-setup diff --git a/Makefile.am b/Makefile.am index 6104c809d..52a8c475e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -143,11 +143,14 @@ rootlibexec_PROGRAMS = \ systemd-detect-virt \ systemd-sysctl +systemgenerator_PROGRAMS = \ + systemd-getty-generator + if HAVE_LIBCRYPTSETUP rootlibexec_PROGRAMS += \ systemd-cryptsetup -systemgenerator_PROGRAMS = \ +systemgenerator_PROGRAMS += \ systemd-cryptsetup-generator endif @@ -856,6 +859,16 @@ systemd_cryptsetup_generator_CFLAGS = \ systemd_cryptsetup_generator_LDADD = \ libsystemd-basic.la +systemd_getty_generator_SOURCES = \ + src/getty-generator.c \ + src/unit-name.c + +systemd_getty_generator_CFLAGS = \ + $(AM_CFLAGS) + +systemd_getty_generator_LDADD = \ + libsystemd-basic.la + systemd_user_sessions_SOURCES = \ src/user-sessions.c \ src/cgroup-util.c diff --git a/TODO b/TODO index 522ef5929..d377bc314 100644 --- a/TODO +++ b/TODO @@ -24,8 +24,6 @@ F15: * capability_bounding_set_drop not used. -* remove getty magic, move it into a generator - * recreate private socket on SIGUSR2 Features: diff --git a/src/cryptsetup-generator.c b/src/cryptsetup-generator.c index 00120f67a..00f48009e 100644 --- a/src/cryptsetup-generator.c +++ b/src/cryptsetup-generator.c @@ -222,7 +222,8 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - arg_dest = argv[1]; + if (argc > 1) + arg_dest = argv[1]; log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); log_parse_environment(); diff --git a/src/getty-generator.c b/src/getty-generator.c new file mode 100644 index 000000000..f49f9eae9 --- /dev/null +++ b/src/getty-generator.c @@ -0,0 +1,127 @@ +/*-*- 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 . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "unit-name.h" + +const char *arg_dest = "/tmp"; + +static int add_symlink(const char *fservice, const char *tservice) { + char *from = NULL, *to = NULL; + int r; + + asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", fservice); + asprintf(&to, "%s/getty.target.wants/%s", arg_dest, tservice); + + if (!from || !to) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + mkdir_parents(to, 0755); + + if ((r = symlink(from, to)) < 0) { + log_error("Failed to create symlink from %s to %s: %m", from, to); + r = -errno; + } + +finish: + + free(from); + free(to); + + return r; +} + +int main(int argc, char *argv[]) { + int r = EXIT_SUCCESS; + char *active; + + if (argc > 2) { + log_error("This program takes one or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[1]; + + log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); + log_parse_environment(); + log_open(); + + if (detect_container(NULL) > 0) { + log_debug("Automatic adding console shell."); + + if (add_symlink("console-shell.service", "console-shell.service") < 0) + r = EXIT_FAILURE; + + /* Don't add any further magic if we are in a container */ + goto finish; + } + + if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { + const char *tty; + + truncate_nl(active); + if ((tty = strrchr(active, ' '))) + tty ++; + else + tty = active; + + /* Automatically add in a serial getty on the kernel + * console */ + if (!tty_is_vc(tty)) { + char *n; + + /* We assume that gettys on virtual terminals are + * started via manual configuration and do this magic + * only for non-VC terminals. */ + + log_debug("Automatically adding serial getty for /dev/%s.", tty); + + if (!(n = unit_name_replace_instance("serial-getty@.service", tty)) || + add_symlink("serial-getty@.service", n) < 0) + r = EXIT_FAILURE; + + free(n); + } + + free(active); + } + + /* Automatically add in a serial getty on the first + * virtualizer console */ + if (access("/sys/class/tty/hvc0", F_OK) == 0) { + log_debug("Automatic adding serial getty for hvc0."); + + if (add_symlink("serial-getty@.service", "serial-getty@hvc0.service") < 0) + r = EXIT_FAILURE; + } + +finish: + return r; +} diff --git a/src/special.h b/src/special.h index df1e1fa41..2f2d9e7b2 100644 --- a/src/special.h +++ b/src/special.h @@ -63,8 +63,6 @@ #define SPECIAL_KEXEC_TARGET "kexec.target" #define SPECIAL_DBUS_SERVICE "dbus.service" #define SPECIAL_DBUS_SOCKET "dbus.socket" -#define SPECIAL_GETTY_TARGET "getty.target" -#define SPECIAL_SERIAL_GETTY_SERVICE "serial-getty@.service" #define SPECIAL_REMOUNT_ROOTFS_SERVICE "remount-rootfs.service" #ifndef SPECIAL_SYSLOG_SERVICE diff --git a/src/target.c b/src/target.c index b8d4a01b6..54c34daa0 100644 --- a/src/target.c +++ b/src/target.c @@ -83,70 +83,6 @@ static int target_add_default_dependencies(Target *t) { return unit_add_dependency_by_name(UNIT(t), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); } -static int target_add_getty_dependencies(Target *t) { - char *n, *active; - int r; - - assert(t); - - if (!unit_has_name(UNIT(t), SPECIAL_GETTY_TARGET)) - return 0; - - if (detect_container(NULL) > 0) - return 1; - - if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { - const char *tty; - - truncate_nl(active); - if ((tty = strrchr(active, ' '))) - tty ++; - else - tty = active; - - /* Automatically add in a serial getty on the kernel - * console */ - if (!tty_is_vc(tty)) { - - /* We assume that gettys on virtual terminals are - * started via manual configuration and do this magic - * only for non-VC terminals. */ - - log_debug("Automatically adding serial getty for /dev/%s", tty); - if (!(n = unit_name_replace_instance(SPECIAL_SERIAL_GETTY_SERVICE, tty))) { - free(active); - return -ENOMEM; - } - - r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_WANTS, n, NULL, true); - free(n); - - if (r < 0) { - free(active); - return r; - } - } - - free(active); - } - - /* Automatically add in a serial getty on the first - * virtualizer console */ - if (access("/sys/class/tty/hvc0", F_OK) == 0) { - log_debug("Automatic adding serial getty for hvc0"); - if (!(n = unit_name_replace_instance(SPECIAL_SERIAL_GETTY_SERVICE, "hvc0"))) - return -ENOMEM; - - r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_WANTS, n, NULL, true); - free(n); - - if (r < 0) - return r; - } - - return 0; -} - static int target_load(Unit *u) { Target *t = TARGET(u); int r; @@ -161,9 +97,6 @@ static int target_load(Unit *u) { if (u->meta.default_dependencies) if ((r = target_add_default_dependencies(t)) < 0) return r; - - if ((r = target_add_getty_dependencies(t)) < 0) - return r; } return 0; From f3accc08d36c3937f6bc2e696679610dd36fbfaf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 15 Mar 2011 02:41:11 +0100 Subject: [PATCH 057/200] umount: don't try to remount bind mounts ro during shutdown --- src/umount.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/umount.c b/src/umount.c index 6fe0a26dd..96ce61da8 100644 --- a/src/umount.c +++ b/src/umount.c @@ -37,6 +37,7 @@ typedef struct MountPoint { char *path; dev_t devnum; + bool skip_ro; LIST_FIELDS (struct MountPoint, mount_point); } MountPoint; @@ -71,6 +72,8 @@ static int mount_points_list_get(MountPoint **head) { for (i = 1;; i++) { int k; MountPoint *m; + char *root; + bool skip_ro; path = p = NULL; @@ -78,7 +81,7 @@ static int mount_points_list_get(MountPoint **head) { "%*s " /* (1) mount id */ "%*s " /* (2) parent id */ "%*s " /* (3) major:minor */ - "%*s " /* (4) root */ + "%ms " /* (4) root */ "%ms " /* (5) mount point */ "%*s" /* (6) mount options */ "%*[^-]" /* (7) optional fields */ @@ -87,7 +90,8 @@ static int mount_points_list_get(MountPoint **head) { "%*s" /* (10) mount source */ "%*s" /* (11) mount options 2 */ "%*[^\n]", /* some rubbish at the end */ - &path)) != 1) { + &root, + &path)) != 2) { if (k == EOF) break; @@ -97,6 +101,13 @@ static int mount_points_list_get(MountPoint **head) { continue; } + /* If we encounter a bind mount, don't try to remount + * the source dir too early */ + if (!streq(root, "/")) + skip_ro = true; + + free(root); + p = cunescape(path); free(path); @@ -117,6 +128,7 @@ static int mount_points_list_get(MountPoint **head) { } m->path = p; + m->skip_ro = skip_ro; LIST_PREPEND(MountPoint, mount_point, *head, m); } @@ -428,6 +440,11 @@ static int mount_points_list_remount_read_only(MountPoint **head, bool *changed) LIST_FOREACH_SAFE(mount_point, m, n, *head) { + if (m->skip_ro) { + n_failed++; + continue; + } + /* Trying to remount read-only */ if (mount(NULL, m->path, NULL, MS_MGC_VAL|MS_REMOUNT|MS_RDONLY, NULL) == 0) { if (changed) From b9a8e638ed520bc9b528a1e8539ca4b9026861b4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 15 Mar 2011 18:43:47 +0100 Subject: [PATCH 058/200] cgls: don't strip user processes and kernel threads from default output --- src/cgls.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cgls.c b/src/cgls.c index 6f083015e..2bde743ac 100644 --- a/src/cgls.c +++ b/src/cgls.c @@ -112,8 +112,12 @@ int main(int argc, char *argv[]) { if ((r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root)) < 0) t = "/"; - else - t = root; + else { + if (endswith(root, "/system")) + root[strlen(root)-7] = 0; + + t = root[0] ? root : "/"; + } r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, t, NULL, 0); free(root); From 8f7a3c1402a8de36b2c63935358a53510d2fe7c1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 15 Mar 2011 20:51:41 +0100 Subject: [PATCH 059/200] man: document systemd-nspawn --- Makefile.am | 1 + man/systemd-nspawn.xml | 190 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 man/systemd-nspawn.xml diff --git a/Makefile.am b/Makefile.am index 52a8c475e..f7b7053d8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -519,6 +519,7 @@ MANPAGES = \ man/systemctl.1 \ man/systemadm.1 \ man/systemd-cgls.1 \ + man/systemd-nspawn.1 \ man/systemd-tmpfiles.8 \ man/systemd-notify.1 \ man/sd_notify.3 \ diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml new file mode 100644 index 000000000..70ebf94e0 --- /dev/null +++ b/man/systemd-nspawn.xml @@ -0,0 +1,190 @@ + + + + + + + + + systemd-nspawn + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-nspawn + 1 + + + + systemd-nspawn + Spawn a namespace container for debugging, testing and building + + + + + systemd-nspawn OPTIONS COMMAND ARGS + + + + + Description + + systemd-nspawn may be used to + run a command or OS in a light-weight namespace + container. In many ways it is similar to + chroot1, + but more powerful since it fully virtualizes the file + system hierachy, as well as the process tree, the + various IPC subsystems and the host and domain + name. + + systemd-nspawn limits access + to various kernel interfaces in the container to + read-only, such as /sys, + /proc/sys or + /selinux. Network interfaces and + the system clock may not be changed from within the + container. Device nodes may not be created. The host + system cannot be rebooted and kernel modules may not + be loaded from within the container. + + Note that even though these security precautions + are taken systemd-nspawn is not + suitable for secure container setups. Many of the + security features may be circumvented and are hence + primarily useful to avoid accidental changes to the + host system from the container. The intended use of + this program is debugging and testing as well as + building of packages, distributions and software + involved with boot and systems management. + + In contrast to + chroot1 + systemd-nspawn may be used to boot + full Linux-based operating systems in a + container. + + Use a tool like + debootstrap8 or mock1 + to set up an OS directory tree suitable as file system + hierarchy for systemd-nspawn containers. + + Note that systemd-nspawn will + mount file systems private to the container to + /dev, + /dev/.run and similar. These will + not be visible outside of the container, and their + contents will be lost when the container exits. + + Note that running two + systemd-nspawn containers from the + same directory tree will not make processes in them + see each other. The PID namespace seperation of the + two containers is complete and the containers will + share very few runtime objects except for the + underlying file system. + + + + Options + + If no arguments are passed the container is set + up and a shell started in it, otherwise the passed + command and arguments are executed in it. The + following options are understood: + + + + + + Prints a short help + text and exits. + + + + + + + Directory to use as + file system root for the namespace + container. If omitted the current + directory will be + used. + + + + + + + + Example 1 + + # debootstrap --arch=amd64 unstable debian-tree/ +# systemd-nspawn -D debian-tree/ + + This installs a minimal Debian unstable + distribution into the directory + debian-tree/ and then spawns a + shell in a namespace container in it. + + + + + Example 2 + + # mock --init +# systemd-nspawn -D /var/lib/mock/fedora-rawhide-x86_64/root/ /bin/systemd systemd.log_level=debug + + This installs a minimal Fedora distribution into + a subdirectory of /var/lib/mock/ + and then boots an OS in a namespace container in it, + with systemd as init system, configured for debug + logging. + + + + + Exit status + + The exit code of the program executed in the + container is returned. + + + + See Also + + systemd1, + chroot1, + debootstrap8 + mock1 + + + + From 0ac10822732008aa2c0af7a0499c838446ac0a82 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 15 Mar 2011 21:21:38 +0100 Subject: [PATCH 060/200] cgroup: don't recheck all the time whether the systemd hierarchy is mounted, to make strace outputs nicer and save a few stat()s --- src/cgroup-util.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/cgroup-util.c b/src/cgroup-util.c index bbadc789a..090573bd3 100644 --- a/src/cgroup-util.c +++ b/src/cgroup-util.c @@ -484,6 +484,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch const char *p; char *mp; int r; + static __thread bool good = false; assert(controller); assert(fs); @@ -504,9 +505,14 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch if (asprintf(&mp, "/sys/fs/cgroup/%s", p) < 0) return -ENOMEM; - if ((r = path_is_mount_point(mp)) <= 0) { - free(mp); - return r < 0 ? r : -ENOENT; + if (!good) { + if ((r = path_is_mount_point(mp)) <= 0) { + free(mp); + return r < 0 ? r : -ENOENT; + } + + /* Cache this to save a few stat()s */ + good = true; } if (path && suffix) From f9b72cd804f99222cf999c63eb3610a7f54bbf2c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 02:55:27 +0100 Subject: [PATCH 061/200] ask-password: reset signal mask after we are done --- TODO | 2 ++ src/ask-password-api.c | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index d377bc314..307d023c3 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,8 @@ F15: * recreate private socket on SIGUSR2 +* serialize condition execution information + Features: * optionally create watched directories in .path units diff --git a/src/ask-password-api.c b/src/ask-password-api.c index 0b2e9ad84..9c3dad965 100644 --- a/src/ask-password-api.c +++ b/src/ask-password-api.c @@ -271,11 +271,15 @@ int ask_password_agent( FILE *f = NULL; char *socket_name = NULL; int socket_fd = -1, signal_fd = -1; - sigset_t mask; + sigset_t mask, oldmask; struct pollfd pollfd[_FD_MAX]; assert(_passphrases); + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, -1); + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); + mkdir_p("/dev/.run/systemd/ask-password", 0755); if ((fd = mkostemp(temp, O_CLOEXEC|O_CREAT|O_WRONLY)) < 0) { @@ -294,10 +298,6 @@ int ask_password_agent( fd = -1; - assert_se(sigemptyset(&mask) == 0); - sigset_add_many(&mask, SIGINT, SIGTERM, -1); - assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); - if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { log_error("signalfd(): %m"); r = -errno; @@ -493,6 +493,8 @@ finish: if (final[0]) unlink(final); + assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0); + return r; } From dfa7f7e139e465c7685fd530d61a52c41184bcde Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 02:55:55 +0100 Subject: [PATCH 062/200] main: check if we have a valid PID before getting the name of it --- src/kmsg-syslogd.c | 4 +++- src/manager.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/kmsg-syslogd.c b/src/kmsg-syslogd.c index 4edb16136..c78011fe2 100644 --- a/src/kmsg-syslogd.c +++ b/src/kmsg-syslogd.c @@ -354,7 +354,9 @@ static int write_message(Server *s, const char *buf, struct ucred *ucred) { /* Then, add process if set */ if (read_process(&buf, &iovec[i]) > 0) i++; - else if (ucred && get_process_name(ucred->pid, &process) >= 0) + else if (ucred && + ucred->pid > 0 && + get_process_name(ucred->pid, &process) >= 0) IOVEC_SET_STRING(iovec[i++], process); /* Skip the stored PID if we have a better one */ diff --git a/src/manager.c b/src/manager.c index df75eca8c..9edb8f09b 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2070,7 +2070,9 @@ static int manager_process_signal_fd(Manager *m) { return -errno; } - get_process_name(sfsi.ssi_pid, &p); + if (sfsi.ssi_pid > 0) + get_process_name(sfsi.ssi_pid, &p); + log_debug("Received SIG%s from PID %lu (%s)", strna(signal_to_string(sfsi.ssi_signo)), (unsigned long) sfsi.ssi_pid, strna(p)); From 6ef1b05339248b07270ac3d315458bc6c79a770d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 02:56:30 +0100 Subject: [PATCH 063/200] main: parse the whole arv[] as kernel command line --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 0c805c98a..5b75ecca8 100644 --- a/src/main.c +++ b/src/main.c @@ -848,7 +848,7 @@ static int parse_argv(int argc, char *argv[]) { * relevant for us, hence we rely on argv[] * instead. */ - for (a = argv + optind; a < argv + argc; a++) + for (a = argv; a < argv + argc; a++) if ((r = parse_proc_cmdline_word(*a)) < 0) return r; } From a258bf2648fa5e3005b96203c60b9751807bacf0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 02:57:52 +0100 Subject: [PATCH 064/200] nspawn: allocate a new pty instead of passing ours through to avoid terminal settings chaos --- src/nspawn.c | 462 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 405 insertions(+), 57 deletions(-) diff --git a/src/nspawn.c b/src/nspawn.c index 94e03b58d..f8a190097 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -33,12 +33,16 @@ #include #include #include +#include +#include +#include #include "log.h" #include "util.h" #include "missing.h" #include "cgroup-util.h" #include "sd-daemon.h" +#include "strv.h" static char *arg_directory = NULL; @@ -166,7 +170,7 @@ static int mount_all(const char *dest) { return r; } -static int copy_devnodes(const char *dest) { +static int copy_devnodes(const char *dest, const char *console) { static const char devnodes[] = "null\0" @@ -181,15 +185,17 @@ static int copy_devnodes(const char *dest) { const char *d; int r = 0, k; - char *tty = NULL; - dev_t tty_devnum; mode_t u; + struct stat st; + char *from = NULL, *to = NULL; + + assert(dest); + assert(console); u = umask(0000); NULSTR_FOREACH(d, devnodes) { - char *from = NULL, *to = NULL; - struct stat st; + from = to = NULL; asprintf(&from, "/dev/%s", d); asprintf(&to, "%s/dev/%s", dest, d); @@ -200,6 +206,8 @@ static int copy_devnodes(const char *dest) { free(from); free(to); + from = to = NULL; + if (r == 0) r = -ENOMEM; @@ -210,70 +218,80 @@ static int copy_devnodes(const char *dest) { if (errno != ENOENT) { log_error("Failed to stat %s: %m", from); - if (r == 0) r = -errno; } - } else { - if (mknod(to, st.st_mode, st.st_rdev) < 0) { - log_error("mknod(%s) failed: %m", dest); + } else if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { - if (r == 0) - r = -errno; - } + log_error("%s is not a char or block device, cannot copy.", from); + if (r == 0) + r = -EIO; + + } else if (mknod(to, st.st_mode, st.st_rdev) < 0) { + + log_error("mknod(%s) failed: %m", dest); + if (r == 0) + r = -errno; } free(from); free(to); } - if ((k = get_ctty(&tty, &tty_devnum)) < 0) { - log_error("Failed to determine controlling tty: %s", strerror(-k)); + if (stat(console, &st) < 0) { + + log_error("Failed to stat %s: %m", console); + if (r == 0) + r = -errno; + + goto finish; + + } else if (!S_ISCHR(st.st_mode)) { + + log_error("/dev/console is not a char device."); + if (r == 0) + r = -EIO; + + goto finish; + } + + if (asprintf(&to, "%s/dev/console", dest) < 0) { + + log_error("Out of memory"); + if (r == 0) + r = -ENOMEM; + + goto finish; + } + + /* We need to bind mount the right tty to /dev/console since + * ptys can only exist on pts file systems. To have something + * to bind mount things on we create a device node first, that + * has the right major/minor (note that the major minor + * doesn't actually matter here, since we mount it over + * anyway). */ + + if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) + log_error("mknod for /dev/console failed: %m"); + + if (mount(console, to, "bind", MS_BIND, NULL) < 0) { + log_error("bind mount for /dev/console failed: %m"); + + if (r == 0) + r = -errno; + } + + free(to); + + if ((k = chmod_and_chown(console, 0600, 0, 0)) < 0) { + log_error("Failed to correct access mode for TTY: %s", strerror(-k)); if (r == 0) r = k; - } else { - char *from = NULL, *to = NULL; - - asprintf(&from, "/dev/%s", tty); - asprintf(&to, "%s/dev/console", dest); - - if (!from || !to) { - log_error("Out of memory"); - - if (r == 0) - r = k; - } else { - /* We need to bind mount our own tty on - * /dev/console, since ptys cannot be used - * unless on a devpts file system. But to bind - * mount it we first have to create a device - * node where we can bind mount it on. This is - * kinda ugly since the TTY will very likely - * be owned by a user/group that does not - * exist in the container. */ - - if (mknod(to, S_IFCHR|0600, tty_devnum) < 0) { - log_error("mknod for /dev/console failed: %m"); - - if (r == 0) - r = -errno; - } - - if (mount(from, to, "bind", MS_BIND|MS_RDONLY, NULL) < 0) { - log_error("bind mount for /dev/console failed: %m"); - - if (r == 0) - r = -errno; - } - } - - free(from); - free(to); } - free(tty); +finish: umask(u); @@ -346,11 +364,259 @@ static int is_os_tree(const char *path) { return r < 0 ? 0 : 1; } +#define BUFFER_SIZE 1024 + +static int process_pty(int master, sigset_t *mask) { + char in_buffer[BUFFER_SIZE], out_buffer[BUFFER_SIZE]; + size_t in_buffer_full = 0, out_buffer_full = 0; + struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev; + bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false; + bool stdin_rhup = false, stdout_whup = false, master_rhup = false, master_whup = false; + int ep = -1, signal_fd = -1, r; + + fd_nonblock(STDIN_FILENO, 1); + fd_nonblock(STDOUT_FILENO, 1); + fd_nonblock(master, 1); + + if ((signal_fd = signalfd(-1, mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + if ((ep = epoll_create1(EPOLL_CLOEXEC)) < 0) { + log_error("Failed to create epoll: %m"); + r = -errno; + goto finish; + } + + zero(stdin_ev); + stdin_ev.events = EPOLLIN|EPOLLET; + stdin_ev.data.fd = STDIN_FILENO; + + zero(stdout_ev); + stdout_ev.events = EPOLLOUT|EPOLLET; + stdout_ev.data.fd = STDOUT_FILENO; + + zero(master_ev); + master_ev.events = EPOLLIN|EPOLLOUT|EPOLLET; + master_ev.data.fd = master; + + zero(signal_ev); + signal_ev.events = EPOLLIN; + signal_ev.data.fd = signal_fd; + + if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, signal_fd, &signal_ev) < 0) { + log_error("Failed to regiser fds in epoll: %m"); + r = -errno; + goto finish; + } + + do { + struct epoll_event ev[16]; + ssize_t k; + int i, nfds; + + if ((nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1)) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll_wait(): %m"); + r = -errno; + goto finish; + } + + assert(nfds >= 1); + + for (i = 0; i < nfds; i++) { + if (ev[i].data.fd == STDIN_FILENO) { + + if (!stdin_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + stdin_readable = true; + + } else if (ev[i].data.fd == STDOUT_FILENO) { + + if (ev[i].events & EPOLLHUP) { + stdout_writable = false; + stdout_whup = true; + } + + if (!stdout_whup && (ev[i].events & EPOLLOUT)) + stdout_writable = true; + + } else if (ev[i].data.fd == master) { + + /* We don't connect EPOLLHUP to + * master_whup here, since EPOLLHUP + * can happen when noone has opened + * the other side */ + + if (!master_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + master_readable = true; + + if (!master_whup && (ev[i].events & EPOLLOUT)) + master_writable = true; + + } else if (ev[i].data.fd == signal_fd) { + struct signalfd_siginfo sfsi; + ssize_t n; + + if ((n = read(signal_fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) { + + if (n >= 0) { + r = -EIO; + goto finish; + } + + if (errno != EINTR && errno != EAGAIN) { + r = -errno; + goto finish; + } + } else { + + if (sfsi.ssi_signo == SIGWINCH) { + struct winsize ws; + + /* The window size changed, let's forward that. */ + + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) + ioctl(master, TIOCSWINSZ, &ws); + } else { + r = -EINTR; + goto finish; + } + } + } + } + + while ((stdin_readable && in_buffer_full <= 0) || + (master_writable && in_buffer_full > 0) || + (master_readable && out_buffer_full <= 0) || + (stdout_writable && out_buffer_full > 0)) { + + if (stdin_readable && in_buffer_full < BUFFER_SIZE) { + + if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) { + + if (errno == EAGAIN) + stdin_readable = false; + else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) + k = 0; + else { + log_error("read(): %m"); + goto finish; + } + } else + in_buffer_full += (size_t) k; + + if (k == 0) { + stdin_rhup = true; + stdin_readable = false; + shutdown(STDIN_FILENO, SHUT_RD); + } + } + + if (master_writable && in_buffer_full > 0) { + + if ((k = write(master, in_buffer, in_buffer_full)) < 0) { + + if (errno == EAGAIN) + master_writable = false; + else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) { + master_whup = true; + master_writable = false; + } else { + log_error("write(): %m"); + goto finish; + } + + } else { + assert(in_buffer_full >= (size_t) k); + memmove(in_buffer, in_buffer + k, in_buffer_full - k); + in_buffer_full -= k; + } + } + + if (master_readable && out_buffer_full < BUFFER_SIZE) { + + if ((k = read(master, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) { + + if (errno == EAGAIN) + master_readable = false; + else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) + k = 0; + else { + log_error("read(): %m"); + goto finish; + } + } else + out_buffer_full += (size_t) k; + + if (k == 0) { + master_rhup = true; + master_readable = false; + } + } + + if (stdout_writable && out_buffer_full > 0) { + + if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) { + + if (errno == EAGAIN) + stdout_writable = false; + else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) { + stdout_whup = true; + stdout_writable = false; + } else { + log_error("write(): %m"); + goto finish; + } + + } else { + assert(out_buffer_full >= (size_t) k); + memmove(out_buffer, out_buffer + k, out_buffer_full - k); + out_buffer_full -= k; + } + } + } + + if (stdin_rhup && in_buffer_full <= 0 && !master_whup) { + master_whup = true; + master_writable = false; + } + + if (master_rhup && out_buffer_full <= 0 && !stdout_whup) { + stdout_whup = true; + stdout_writable = false; + shutdown(STDOUT_FILENO, SHUT_WR); + } + + } while (!stdout_whup || !master_whup); + +finish: + if (ep >= 0) + close_nointr_nofail(ep); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + return r; +} int main(int argc, char *argv[]) { pid_t pid = 0; int r = EXIT_FAILURE, k; char *oldcg = NULL, *newcg = NULL; + int master = -1; + const char *console = NULL; + struct termios saved_attr, raw_attr; + sigset_t mask; + bool saved_attr_valid = false; + struct winsize ws; log_parse_environment(); log_open(); @@ -394,8 +660,6 @@ int main(int argc, char *argv[]) { goto finish; } - log_info("Spawning namespace container on %s.", arg_directory); - if ((k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg)) < 0) { log_error("Failed to determine current cgroup: %s", strerror(-k)); goto finish; @@ -411,31 +675,99 @@ int main(int argc, char *argv[]) { goto finish; } + if ((master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY)) < 0) { + log_error("Failed to acquire pseudo tty: %m"); + goto finish; + } + + if (!(console = ptsname(master))) { + log_error("Failed to determine tty name: %m"); + goto finish; + } + + log_info("Spawning namespace container on %s (console is %s).", arg_directory, console); + + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) + ioctl(master, TIOCSWINSZ, &ws); + + if (unlockpt(master) < 0) { + log_error("Failed to unlock tty: %m"); + goto finish; + } + + if (tcgetattr(STDIN_FILENO, &saved_attr) < 0) { + log_error("Failed to get terminal attributes: %m"); + goto finish; + } + + saved_attr_valid = true; + + raw_attr = saved_attr; + cfmakeraw(&raw_attr); + raw_attr.c_lflag &= ~ECHO; + + if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) { + log_error("Failed to set terminal attributes: %m"); + goto finish; + } + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1); + assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0); + if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS, NULL)) < 0) { log_error("clone() failed: %m"); goto finish; } if (pid == 0) { + /* child */ + const char *hn; const char *envp[] = { "HOME=/root", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + NULL, NULL }; - /* child */ + envp[2] = strv_find_prefix(environ, "TERM="); + + close_nointr_nofail(master); + + close_nointr(STDIN_FILENO); + close_nointr(STDOUT_FILENO); + close_nointr(STDERR_FILENO); + + close_all_fds(NULL, 0); + + reset_all_signal_handlers(); + + assert_se(sigemptyset(&mask) == 0); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + if (setsid() < 0) + goto child_fail; + + if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) + goto child_fail; if (mount_all(arg_directory) < 0) goto child_fail; - if (copy_devnodes(arg_directory) < 0) + if (copy_devnodes(arg_directory, console) < 0) goto child_fail; if (chdir(arg_directory) < 0) { log_error("chdir(%s) failed: %m", arg_directory); goto child_fail; } + + if (open_terminal("dev/console", O_RDWR) != STDIN_FILENO || + dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO || + dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) + goto child_fail; + if (mount(arg_directory, "/", "bind", MS_BIND|MS_MOVE, NULL) < 0) { log_error("mount(MS_MOVE) failed: %m"); goto child_fail; @@ -451,6 +783,8 @@ int main(int argc, char *argv[]) { goto child_fail; } + umask(0002); + if (drop_capabilities() < 0) goto child_fail; @@ -470,12 +804,26 @@ int main(int argc, char *argv[]) { _exit(EXIT_FAILURE); } + if (process_pty(master, &mask) < 0) + goto finish; + + if (saved_attr_valid) { + tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr); + saved_attr_valid = false; + } + r = wait_for_terminate_and_warn(argc > optind ? argv[optind] : "bash", pid); if (r < 0) r = EXIT_FAILURE; finish: + if (saved_attr_valid) + tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr); + + if (master >= 0) + close_nointr_nofail(master); + if (oldcg) cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0); From 14f3c8252b4dd73bff778b5af9f872e929bd566c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 02:58:05 +0100 Subject: [PATCH 065/200] util: make touched files non-writable by default --- src/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.c b/src/util.c index eefd66e8c..c9c88927b 100644 --- a/src/util.c +++ b/src/util.c @@ -3524,7 +3524,7 @@ int touch(const char *path) { assert(path); - if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666)) < 0) + if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644)) < 0) return -errno; close_nointr_nofail(fd); From fd14078a3ab2110cd10e5eb55cdaeecfa51a189c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 03:18:23 +0100 Subject: [PATCH 066/200] nspawn: make tty code more robust against closed/reopened /dev/console --- src/nspawn.c | 69 +++++++++------------------------------------------- 1 file changed, 12 insertions(+), 57 deletions(-) diff --git a/src/nspawn.c b/src/nspawn.c index f8a190097..cd528deb7 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -371,7 +371,6 @@ static int process_pty(int master, sigset_t *mask) { size_t in_buffer_full = 0, out_buffer_full = 0; struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev; bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false; - bool stdin_rhup = false, stdout_whup = false, master_rhup = false, master_whup = false; int ep = -1, signal_fd = -1, r; fd_nonblock(STDIN_FILENO, 1); @@ -415,7 +414,7 @@ static int process_pty(int master, sigset_t *mask) { goto finish; } - do { + for (;;) { struct epoll_event ev[16]; ssize_t k; int i, nfds; @@ -435,30 +434,20 @@ static int process_pty(int master, sigset_t *mask) { for (i = 0; i < nfds; i++) { if (ev[i].data.fd == STDIN_FILENO) { - if (!stdin_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + if (ev[i].events & (EPOLLIN|EPOLLHUP)) stdin_readable = true; } else if (ev[i].data.fd == STDOUT_FILENO) { - if (ev[i].events & EPOLLHUP) { - stdout_writable = false; - stdout_whup = true; - } - - if (!stdout_whup && (ev[i].events & EPOLLOUT)) + if (ev[i].events & (EPOLLOUT|EPOLLHUP)) stdout_writable = true; } else if (ev[i].data.fd == master) { - /* We don't connect EPOLLHUP to - * master_whup here, since EPOLLHUP - * can happen when noone has opened - * the other side */ - - if (!master_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + if (ev[i].events & (EPOLLIN|EPOLLHUP)) master_readable = true; - if (!master_whup && (ev[i].events & EPOLLOUT)) + if (ev[i].events & (EPOLLOUT|EPOLLHUP)) master_writable = true; } else if (ev[i].data.fd == signal_fd) { @@ -482,7 +471,6 @@ static int process_pty(int master, sigset_t *mask) { struct winsize ws; /* The window size changed, let's forward that. */ - if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) ioctl(master, TIOCSWINSZ, &ws); } else { @@ -502,34 +490,23 @@ static int process_pty(int master, sigset_t *mask) { if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) { - if (errno == EAGAIN) + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) stdin_readable = false; - else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) - k = 0; else { log_error("read(): %m"); goto finish; } } else in_buffer_full += (size_t) k; - - if (k == 0) { - stdin_rhup = true; - stdin_readable = false; - shutdown(STDIN_FILENO, SHUT_RD); - } } if (master_writable && in_buffer_full > 0) { if ((k = write(master, in_buffer, in_buffer_full)) < 0) { - if (errno == EAGAIN) + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) master_writable = false; - else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) { - master_whup = true; - master_writable = false; - } else { + else { log_error("write(): %m"); goto finish; } @@ -545,33 +522,23 @@ static int process_pty(int master, sigset_t *mask) { if ((k = read(master, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) { - if (errno == EAGAIN) + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) master_readable = false; - else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) - k = 0; else { log_error("read(): %m"); goto finish; } } else out_buffer_full += (size_t) k; - - if (k == 0) { - master_rhup = true; - master_readable = false; - } } if (stdout_writable && out_buffer_full > 0) { if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) { - if (errno == EAGAIN) + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) stdout_writable = false; - else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) { - stdout_whup = true; - stdout_writable = false; - } else { + else { log_error("write(): %m"); goto finish; } @@ -583,19 +550,7 @@ static int process_pty(int master, sigset_t *mask) { } } } - - if (stdin_rhup && in_buffer_full <= 0 && !master_whup) { - master_whup = true; - master_writable = false; - } - - if (master_rhup && out_buffer_full <= 0 && !stdout_whup) { - stdout_whup = true; - stdout_writable = false; - shutdown(STDOUT_FILENO, SHUT_WR); - } - - } while (!stdout_whup || !master_whup); + } finish: if (ep >= 0) From 715ac17a84f7d721dec613d86d83e671704fafcc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 03:27:02 +0100 Subject: [PATCH 067/200] nspawn: bind mount /etc/localtime --- src/nspawn.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/nspawn.c b/src/nspawn.c index cd528deb7..aaa5d1f9d 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -125,9 +125,9 @@ static int mount_all(const char *dest) { unsigned k; int r = 0; + char *where; for (k = 0; k < ELEMENTSOF(mount_table); k++) { - char *where; int t; if (asprintf(&where, "%s/%s", dest, mount_table[k].where) < 0) { @@ -167,6 +167,13 @@ static int mount_all(const char *dest) { free(where); } + /* Fix the timezone, if possible */ + if (asprintf(&where, "%s/%s", dest, "/etc/localtime") >= 0) { + mount("/etc/localtime", where, "bind", MS_BIND, NULL); + mount("/etc/localtime", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL); + free(where); + } + return r; } From a2c422cbbe0c420fcfdb7adf1e2ace9c40065cee Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 03:35:38 +0100 Subject: [PATCH 068/200] loopback: downgrade an error to warning --- src/loopback-setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loopback-setup.c b/src/loopback-setup.c index a579060d8..b6359def7 100644 --- a/src/loopback-setup.c +++ b/src/loopback-setup.c @@ -265,7 +265,7 @@ int loopback_setup(void) { finish: if (r < 0) - log_error("Failed to configure loopback device: %s", strerror(-r)); + log_warning("Failed to configure loopback device: %s", strerror(-r)); if (fd >= 0) close_nointr_nofail(fd); From d821e6d69a84e0fafde0228f9b8f8837216eafa7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 03:35:59 +0100 Subject: [PATCH 069/200] main: interpret all argv[] arguments unconditionally when run in a container --- src/main.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/main.c b/src/main.c index 5b75ecca8..1d6ac42e9 100644 --- a/src/main.c +++ b/src/main.c @@ -828,30 +828,28 @@ static int parse_argv(int argc, char *argv[]) { break; } - if (optind < argc) { - if (getpid() != 1) { - /* Hmm, when we aren't run as init system - * let's complain about excess arguments */ + if (optind < argc && getpid() != 1) { + /* Hmm, when we aren't run as init system + * let's complain about excess arguments */ - log_error("Excess arguments."); - return -EINVAL; + log_error("Excess arguments."); + return -EINVAL; + } - } else if (detect_container(NULL) > 0) { - char **a; + if (detect_container(NULL) > 0) { + char **a; - /* All /proc/cmdline arguments the kernel - * didn't understand it passed to us. We're - * note really interested in that usually - * since /proc/cmdline is more interesting and - * complete. With one exception: if we are run - * in a container /proc/cmdline is not - * relevant for us, hence we rely on argv[] - * instead. */ + /* All /proc/cmdline arguments the kernel didn't + * understand it passed to us. We're not really + * interested in that usually since /proc/cmdline is + * more interesting and complete. With one exception: + * if we are run in a container /proc/cmdline is not + * relevant for the container, hence we rely on argv[] + * instead. */ - for (a = argv; a < argv + argc; a++) - if ((r = parse_proc_cmdline_word(*a)) < 0) - return r; - } + for (a = argv; a < argv + argc; a++) + if ((r = parse_proc_cmdline_word(*a)) < 0) + return r; } return 0; From bba6cb45a501916f0e99d5b25c45f40ba6088649 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 16 Mar 2011 03:50:39 +0100 Subject: [PATCH 070/200] main: revert recognition of "b" argument Commit 099663ff8c117303af369a4d412dafed0c5614c2 added "b" as a recognized argument, however, B is not a runlevel like S. (B appears as a pseudo runlevel in openSUSE's init.d scripts only for the sake of insserv being able to manage /etc/init.d/boot.d like the other dirs). --- src/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.c b/src/main.c index 1d6ac42e9..5154b575f 100644 --- a/src/main.c +++ b/src/main.c @@ -227,7 +227,6 @@ static int parse_proc_cmdline_word(const char *word) { static const char * const rlmap[] = { "emergency", SPECIAL_EMERGENCY_TARGET, "-b", SPECIAL_EMERGENCY_TARGET, - "b", SPECIAL_EMERGENCY_TARGET, "single", SPECIAL_RESCUE_TARGET, "-s", SPECIAL_RESCUE_TARGET, "s", SPECIAL_RESCUE_TARGET, From 196e3fa74a88a04b0ecec7d3af648287dd088f8a Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 9 Mar 2011 00:49:47 +0100 Subject: [PATCH 071/200] Add Frugalware display-manager service --- Makefile.am | 5 +++++ units/frugalware/display-manager.service | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 units/frugalware/display-manager.service diff --git a/Makefile.am b/Makefile.am index f7b7053d8..3bac47849 100644 --- a/Makefile.am +++ b/Makefile.am @@ -360,6 +360,11 @@ dist_systemunit_DATA += \ units/fedora/halt-local.service endif +if TARGET_FRUGALWARE +dist_systemunit_DATA += \ + units/frugalware/display-manager.service +endif + if HAVE_PLYMOUTH dist_systemunit_DATA += \ units/plymouth-start.service \ diff --git a/units/frugalware/display-manager.service b/units/frugalware/display-manager.service new file mode 100644 index 000000000..a092c56de --- /dev/null +++ b/units/frugalware/display-manager.service @@ -0,0 +1,19 @@ +# 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=Display Manager +After=syslog.target local.service systemd-user-sessions.service + +Conflicts=splashy-quit.service +After=splashy-quit.service + +[Service] +EnvironmentFile=/etc/sysconfig/desktop +ExecStart=/bin/bash -c "exec ${desktop}" +Restart=always +RestartSec=0 From f1f8cfd0a2654069cb3f792556320d8e214fd930 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Fri, 11 Mar 2011 20:51:48 +0300 Subject: [PATCH 072/200] man: fix systemctl try-restart description It is no more error when service is not running. --- man/systemctl.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index d6e0a51f2..535f9bd13 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -468,9 +468,9 @@ Restart one or more units specified on the command - line. If the units are not running yet - the operation will - fail. Note that for compatibility + line if the units are running. Do + nothing if units are not running. + Note that for compatibility with Red Hat init scripts condrestart is equivalent to this command. From d72238fcb34abc81aca97c5fb15888708ee937d3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Mar 2011 22:30:00 +0100 Subject: [PATCH 073/200] umount: make sure skip_ro is always correctly initialized --- src/umount.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/umount.c b/src/umount.c index 96ce61da8..3d328e0da 100644 --- a/src/umount.c +++ b/src/umount.c @@ -103,9 +103,7 @@ static int mount_points_list_get(MountPoint **head) { /* If we encounter a bind mount, don't try to remount * the source dir too early */ - if (!streq(root, "/")) - skip_ro = true; - + skip_ro = !streq(root, "/"); free(root); p = cunescape(path); From e677657e8dddb33d1f1e32eda0ebc126e08a538d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Mar 2011 03:41:29 +0100 Subject: [PATCH 074/200] dbus: allow LoadUnit to unprivileged users --- TODO | 12 ++++++++++++ src/org.freedesktop.systemd1.conf | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/TODO b/TODO index 307d023c3..1a373cc10 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,18 @@ F15: * serialize condition execution information +* rework syslog.service being up logic in PID 1 + +* rsyslog.service should hook itself into syslog.target? + +* syslog.target should be pulled in by multi-user.target + +* don't strip facility from kmsg log messages as soon as that is possible. + +* pull in .service from meta .targers AND vice versa too. i.e. syslog.target ←→ rsyslog.service, rpcbind similarly + +* drop Names= option? + Features: * optionally create watched directories in .path units diff --git a/src/org.freedesktop.systemd1.conf b/src/org.freedesktop.systemd1.conf index 6db71e2c8..8008f0f4b 100644 --- a/src/org.freedesktop.systemd1.conf +++ b/src/org.freedesktop.systemd1.conf @@ -50,6 +50,10 @@ send_interface="org.freedesktop.systemd1.Manager" send_member="GetUnitByPID"/> + + From a76f7be2b02416ff430625766619f4443f2141cf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Mar 2011 03:41:51 +0100 Subject: [PATCH 075/200] systemctl: accept condstop as alias for stop --- src/systemctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/systemctl.c b/src/systemctl.c index 5db094fc1..87ecf0341 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -1420,7 +1420,8 @@ static int start_unit(DBusConnection *bus, char **args, unsigned n) { if (arg_action == ACTION_SYSTEMCTL) { method = - streq(args[0], "stop") ? "StopUnit" : + streq(args[0], "stop") || + streq(args[0], "condstop") ? "StopUnit" : streq(args[0], "reload") ? "ReloadUnit" : streq(args[0], "restart") ? "RestartUnit" : @@ -5235,6 +5236,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "cancel", MORE, 2, cancel_job }, { "start", MORE, 2, start_unit }, { "stop", MORE, 2, start_unit }, + { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ { "reload", MORE, 2, start_unit }, { "restart", MORE, 2, start_unit }, { "try-restart", MORE, 2, start_unit }, From b74949bcdc65982a5eaca64c836f4d2a3b8a8d0c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Mar 2011 03:42:25 +0100 Subject: [PATCH 076/200] chkconfig: check against runlevel 5 instead of 3, since it is a superset of the latter --- src/systemctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systemctl.c b/src/systemctl.c index 87ecf0341..5e34d0394 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -4098,7 +4098,7 @@ static int install_info_apply(const char *verb, LookupPaths *paths, InstallInfo argv[1] = file_name_from_path(sysv); argv[2] = streq(verb, "enable") ? "on" : - streq(verb, "disable") ? "off" : "--level=3"; + streq(verb, "disable") ? "off" : "--level=5"; log_info("Executing %s %s %s", argv[0], argv[1], strempty(argv[2])); From f6a6225e414858ff222d2b175369cc42459abf9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Mar 2011 04:02:35 +0100 Subject: [PATCH 077/200] def: centralize definition of default timeout in one place --- Makefile.am | 1 + src/cgroup-util.h | 3 +-- src/cryptsetup.c | 3 ++- src/dbus-common.c | 7 +++---- src/def.h | 35 +++++++++++++++++++++++++++++++++++ src/device.c | 1 + src/execute.c | 1 + src/execute.h | 4 ---- src/main.c | 1 + src/mount.c | 1 + src/service.c | 7 +++---- src/socket.c | 1 + src/swap.c | 1 + src/unit.h | 3 --- 14 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 src/def.h diff --git a/Makefile.am b/Makefile.am index 3bac47849..8d2343038 100644 --- a/Makefile.am +++ b/Makefile.am @@ -501,6 +501,7 @@ EXTRA_DIST += \ ${libsystemd_core_la_SOURCES:.c=.h} \ ${libsystemd_daemon_la_SOURCES:.c=.h} \ src/macro.h \ + src/def.h \ src/ioprio.h \ src/missing.h \ src/list.h \ diff --git a/src/cgroup-util.h b/src/cgroup-util.h index 1eccbc9fd..d142af34b 100644 --- a/src/cgroup-util.h +++ b/src/cgroup-util.h @@ -27,8 +27,7 @@ #include #include "set.h" - -#define SYSTEMD_CGROUP_CONTROLLER "name=systemd" +#include "def.h" int cg_enumerate_processes(const char *controller, const char *path, FILE **_f); int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f); diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 989734be1..3aa822a1d 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -31,6 +31,7 @@ #include "util.h" #include "strv.h" #include "ask-password-api.h" +#include "def.h" static const char *opt_type = NULL; /* LUKS1 or PLAIN */ static char *opt_cipher = NULL; @@ -308,7 +309,7 @@ int main(int argc, char *argv[]) { if (opt_readonly) flags |= CRYPT_ACTIVATE_READONLY; - until = now(CLOCK_MONOTONIC) + (opt_timeout > 0 ? opt_timeout : 60 * USEC_PER_SEC); + until = now(CLOCK_MONOTONIC) + (opt_timeout > 0 ? opt_timeout : DEFAULT_TIMEOUT_USEC); opt_tries = opt_tries > 0 ? opt_tries : 3; opt_key_size = (opt_key_size > 0 ? opt_key_size : 256); diff --git a/src/dbus-common.c b/src/dbus-common.c index bb9cf2e2a..e352b8cf9 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -30,6 +30,7 @@ #include "log.h" #include "dbus-common.h" #include "util.h" +#include "def.h" int bus_check_peercred(DBusConnection *c) { int fd; @@ -57,8 +58,6 @@ int bus_check_peercred(DBusConnection *c) { return 1; } -#define TIMEOUT_USEC (60*USEC_PER_SEC) - static int sync_auth(DBusConnection *bus, DBusError *error) { usec_t begin, tstamp; @@ -71,13 +70,13 @@ static int sync_auth(DBusConnection *bus, DBusError *error) { begin = tstamp = now(CLOCK_MONOTONIC); for (;;) { - if (tstamp > begin + TIMEOUT_USEC) + if (tstamp > begin + DEFAULT_TIMEOUT_USEC) break; if (dbus_connection_get_is_authenticated(bus)) break; - if (!dbus_connection_read_write_dispatch(bus, ((begin + TIMEOUT_USEC - tstamp) + USEC_PER_MSEC - 1) / USEC_PER_MSEC)) + if (!dbus_connection_read_write_dispatch(bus, ((begin + DEFAULT_TIMEOUT_USEC - tstamp) + USEC_PER_MSEC - 1) / USEC_PER_MSEC)) break; tstamp = now(CLOCK_MONOTONIC); diff --git a/src/def.h b/src/def.h new file mode 100644 index 000000000..c23cd33d8 --- /dev/null +++ b/src/def.h @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodefhfoo +#define foodefhfoo + +/*** + 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 . +***/ + +#include "util.h" + +#define DEFAULT_TIMEOUT_USEC (3*USEC_PER_MINUTE) +#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC) + +#define SYSTEMD_CGROUP_CONTROLLER "name=systemd" + +#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT +#define SIGNALS_IGNORE SIGKILL,SIGPIPE + +#endif diff --git a/src/device.c b/src/device.c index ccf2935a9..41c96cef0 100644 --- a/src/device.c +++ b/src/device.c @@ -29,6 +29,7 @@ #include "log.h" #include "unit-name.h" #include "dbus-device.h" +#include "def.h" static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = { [DEVICE_DEAD] = UNIT_INACTIVE, diff --git a/src/execute.c b/src/execute.c index 556ff9bda..c1edf61fb 100644 --- a/src/execute.c +++ b/src/execute.c @@ -55,6 +55,7 @@ #include "exit-status.h" #include "missing.h" #include "utmp-wtmp.h" +#include "def.h" /* This assumes there is a 'tty' group */ #define TTY_MODE 0620 diff --git a/src/execute.h b/src/execute.h index e77cdcf0b..755dea35a 100644 --- a/src/execute.h +++ b/src/execute.h @@ -42,10 +42,6 @@ struct CGroupBonding; /* Abstract namespace! */ #define LOGGER_SOCKET "/dev/.run/systemd/logger" -/* This doesn't really belong here, but I couldn't find a better place to put this. */ -#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT -#define SIGNALS_IGNORE SIGKILL,SIGPIPE - typedef enum KillMode { KILL_CONTROL_GROUP = 0, KILL_PROCESS_GROUP, diff --git a/src/main.c b/src/main.c index 5154b575f..7edd6b581 100644 --- a/src/main.c +++ b/src/main.c @@ -51,6 +51,7 @@ #include "label.h" #include "build.h" #include "strv.h" +#include "def.h" static enum { ACTION_RUN, diff --git a/src/mount.c b/src/mount.c index 00780101a..39525b665 100644 --- a/src/mount.c +++ b/src/mount.c @@ -37,6 +37,7 @@ #include "special.h" #include "bus-errors.h" #include "exit-status.h" +#include "def.h" static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { [MOUNT_DEAD] = UNIT_INACTIVE, diff --git a/src/service.c b/src/service.c index e7a9e7c58..0f28312b3 100644 --- a/src/service.c +++ b/src/service.c @@ -35,13 +35,12 @@ #include "special.h" #include "bus-errors.h" #include "exit-status.h" - -#define COMMENTS "#;\n" -#define NEWLINES "\n\r" +#include "def.h" +#include "util.h" #ifdef HAVE_SYSV_COMPAT -#define DEFAULT_SYSV_TIMEOUT_USEC (3*USEC_PER_MINUTE) +#define DEFAULT_SYSV_TIMEOUT_USEC (5*USEC_PER_MINUTE) typedef enum RunlevelType { RUNLEVEL_UP, diff --git a/src/socket.c b/src/socket.c index 130f51c07..9045a2fc8 100644 --- a/src/socket.c +++ b/src/socket.c @@ -42,6 +42,7 @@ #include "bus-errors.h" #include "label.h" #include "exit-status.h" +#include "def.h" static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { [SOCKET_DEAD] = UNIT_INACTIVE, diff --git a/src/swap.c b/src/swap.c index f59b0fb18..035efbaf4 100644 --- a/src/swap.c +++ b/src/swap.c @@ -37,6 +37,7 @@ #include "special.h" #include "bus-errors.h" #include "exit-status.h" +#include "def.h" static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = { [SWAP_DEAD] = UNIT_INACTIVE, diff --git a/src/unit.h b/src/unit.h index 9b7eb5e85..4245f3cf1 100644 --- a/src/unit.h +++ b/src/unit.h @@ -40,9 +40,6 @@ typedef enum UnitDependency UnitDependency; #include "execute.h" #include "condition.h" -#define DEFAULT_TIMEOUT_USEC (3*USEC_PER_MINUTE) -#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC) - enum UnitType { UNIT_SERVICE = 0, UNIT_SOCKET, From d59d0a2b4b41a75eaf618b26b8f8bd1e17de7e2b Mon Sep 17 00:00:00 2001 From: cee1 Date: Thu, 17 Mar 2011 10:13:01 +0800 Subject: [PATCH 078/200] read-ahead: Fix broken systemd-readahead-collect on mips. This actually adjust the __NR_fanotify* system call numbers to proper ones on mips(according userspace ABI). --- configure.ac | 3 +++ src/missing.h | 51 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index cae2dce36..8a28c8e80 100644 --- a/configure.ac +++ b/configure.ac @@ -28,6 +28,9 @@ AC_SUBST(PACKAGE_URL, [http://www.freedesktop.org/wiki/Software/systemd]) AC_CANONICAL_HOST AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.]) +AS_IF([test "x$host_cpu" = "xmips" || test "x$host_cpu" = "xmipsel" || + test "x$host_cpu" = "xmips64" || test "x$host_cpu" = "xmips64el"], + [AC_DEFINE(ARCH_MIPS, [], [Whether on mips arch])]) AM_SILENT_RULES([yes]) diff --git a/src/missing.h b/src/missing.h index c0cb3eaea..35e209fba 100644 --- a/src/missing.h +++ b/src/missing.h @@ -36,6 +36,10 @@ #include "macro.h" +#ifdef ARCH_MIPS +#include +#endif + #ifndef RLIMIT_RTTIME #define RLIMIT_RTTIME 15 #endif @@ -77,19 +81,42 @@ static inline int pivot_root(const char *new_root, const char *put_old) { } #ifdef __x86_64__ -#ifndef __NR_fanotify_init -#define __NR_fanotify_init 300 -#endif -#ifndef __NR_fanotify_mark -#define __NR_fanotify_mark 301 -#endif +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 300 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 301 +# endif +#elif defined _MIPS_SIM +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 4336 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 4337 +# endif +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 6300 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 6301 +# endif +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 5295 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 5296 +# endif +# endif #else -#ifndef __NR_fanotify_init -#define __NR_fanotify_init 338 -#endif -#ifndef __NR_fanotify_mark -#define __NR_fanotify_mark 339 -#endif +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 338 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 339 +# endif #endif static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) { From 2791a8f8dc8764a9247cdba3562bd4c04010f144 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Mar 2011 04:36:19 +0100 Subject: [PATCH 079/200] unit: serialize condition test results --- TODO | 14 ++++++-------- src/unit.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 1a373cc10..17cf53a18 100644 --- a/TODO +++ b/TODO @@ -22,19 +22,13 @@ F15: * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown -* capability_bounding_set_drop not used. - -* recreate private socket on SIGUSR2 - -* serialize condition execution information +* capability_bounding_set_drop not used * rework syslog.service being up logic in PID 1 * rsyslog.service should hook itself into syslog.target? -* syslog.target should be pulled in by multi-user.target - -* don't strip facility from kmsg log messages as soon as that is possible. +* syslog.target should be pulled in by multi-user.target? * pull in .service from meta .targers AND vice versa too. i.e. syslog.target ←→ rsyslog.service, rpcbind similarly @@ -42,6 +36,10 @@ F15: Features: +* don't strip facility from kmsg log messages as soon as that is possible. + +* recreate private socket on SIGUSR2 + * optionally create watched directories in .path units * Support --test based on current system state diff --git a/src/unit.c b/src/unit.c index 117af4df4..10de40aff 100644 --- a/src/unit.c +++ b/src/unit.c @@ -647,6 +647,13 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { condition_dump_list(u->meta.conditions, f, prefix); + if (dual_timestamp_is_set(&u->meta.condition_timestamp)) + fprintf(f, + "%s\tCondition Timestamp: %s\n" + "%s\tCondition Result: %s\n", + prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->meta.condition_timestamp.realtime)), + prefix, yes_no(u->meta.condition_result)); + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) { Unit *other; @@ -2080,6 +2087,10 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) { dual_timestamp_serialize(f, "active-enter-timestamp", &u->meta.active_enter_timestamp); dual_timestamp_serialize(f, "active-exit-timestamp", &u->meta.active_exit_timestamp); dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->meta.inactive_enter_timestamp); + dual_timestamp_serialize(f, "condition-timestamp", &u->meta.condition_timestamp); + + if (dual_timestamp_is_set(&u->meta.condition_timestamp)) + unit_serialize_item(u, f, "condition-result", yes_no(u->meta.condition_result)); /* End marker */ fputc('\n', f); @@ -2169,6 +2180,16 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { } else if (streq(l, "inactive-enter-timestamp")) { dual_timestamp_deserialize(v, &u->meta.inactive_enter_timestamp); continue; + } else if (streq(l, "condition-timestamp")) { + dual_timestamp_deserialize(v, &u->meta.condition_timestamp); + continue; + } else if (streq(l, "condition-result")) { + int b; + + if ((b = parse_boolean(v)) < 0) + log_debug("Failed to parse condition result value %s", v); + else + u->meta.condition_result = b; } if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) From 7d9e57d2cf671f7173324942e0eb9de0d030c505 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 17 Mar 2011 14:03:17 +0100 Subject: [PATCH 080/200] update TODO --- TODO | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index 17cf53a18..1768b0bc2 100644 --- a/TODO +++ b/TODO @@ -21,6 +21,7 @@ F15: * bind mounts are ignored * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown + (path: after installing inotify watches, recheck file again to fix race) * capability_bounding_set_drop not used @@ -32,13 +33,24 @@ F15: * pull in .service from meta .targers AND vice versa too. i.e. syslog.target ←→ rsyslog.service, rpcbind similarly -* drop Names= option? +* drop Names= option? Symlinks only should be used. We don't want to need to read all service files. Features: - * don't strip facility from kmsg log messages as soon as that is possible. + http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=9d90c8d9cde929cbc575098e825d7c29d9f45054 -* recreate private socket on SIGUSR2 +* recreate systemd'd D-Bus private socket file on SIGUSR2 + +* be more specific what failed: + Unmounting file systems. + Not all file systems unmounted, 1 left. + Disabling swaps. + Detaching loop devices. + Detaching DM devices. + Cannot finalize remaining file systems and devices, trying to kill remaining processes. + Unmounting file systems. + Not all file systems unmounted, 1 left. + Cannot finalize remaining file systems and devices, giving up. * optionally create watched directories in .path units @@ -59,10 +71,12 @@ Features: * detect LXC environment * invoke vhangup() before and after invoking getty + http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3c95c985fa91ecf6a0e29622bbdd13dcfc5ce9f1 * support "auto" and "comment=systemd.automount" at the same time for an fstab entry * Maybe store in unit files whether a service should be enabled by default on package installation + (belongs into a distro pattern though, not in an upstream package's service file) * perhaps add "systemctl reenable" as combination of "systemctl disable" and "systemctl enable" @@ -106,13 +120,9 @@ Features: * implicitly import "defaults" settings file into all types * port over to LISTEN_FDS/LISTEN_PID: - - uuidd DONE - - dbus DONE - - rsyslog DONE - - rpcbind (/var/run/rpcbind.sock!) DONE - - cups DONE - - avahi-daemon (/var/run/avahi-daemon/socket) DONE - - ssh CLASSIC + - uuidd HAVEPATCH + - rpcbind (/var/run/rpcbind.sock!) HAVEPATCH + - cups HAVEPATCH - postfix, saslauthd - apache/samba - libvirtd (/var/run/libvirt/libvirt-sock-ro) @@ -135,7 +145,7 @@ Features: * add systemctl switch to dump transaction without executing it -* suspend, resume +* suspend, resume support? * readahead: btrfs/LVM SSD detection @@ -153,7 +163,7 @@ External: * snd-seq should go, https://bugzilla.redhat.com/show_bug.cgi?id=676095 -* gnome-shell python script/glxinfo/is-accelerated wech +* gnome-shell python script/glxinfo/is-accelerated must die * make cryptsetup lower --iter-time @@ -161,6 +171,7 @@ External: * patch kernel for cpu feature modalias for autoloading aes/kvm/... http://git.kernel.org/?p=linux/kernel/git/ak/linux-misc-2.6.git;a=shortlog;h=refs/heads/cpuid-match + (Rafael J. Wysocki's sysdev rework is on the way. After that CPUs can be exported a proper bus.) * procps, psmisc, sysvinit-tools, hostname → util-linux-ng From a49408ec64063023524b964064d393c1fce36e4a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 17 Mar 2011 15:15:36 +0100 Subject: [PATCH 081/200] update TODO --- TODO | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index 1768b0bc2..d2614b73c 100644 --- a/TODO +++ b/TODO @@ -21,7 +21,7 @@ F15: * bind mounts are ignored * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown - (path: after installing inotify watches, recheck file again to fix race) + (path: after installing inotify watches, recheck file again to fix race) * capability_bounding_set_drop not used @@ -37,7 +37,7 @@ F15: Features: * don't strip facility from kmsg log messages as soon as that is possible. - http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=9d90c8d9cde929cbc575098e825d7c29d9f45054 + http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=9d90c8d9cde929cbc575098e825d7c29d9f45054 * recreate systemd'd D-Bus private socket file on SIGUSR2 @@ -52,6 +52,10 @@ Features: Not all file systems unmounted, 1 left. Cannot finalize remaining file systems and devices, giving up. +* check for compiled-in, but not active selinux, and don't print any warnings + about policy loading. Probably check for available selinux in /proc/filesystems, + and check for active selinux with getcon_raw() == "kernel" + * optionally create watched directories in .path units * Support --test based on current system state @@ -64,14 +68,16 @@ Features: * make sure timeouts are applied to Type=oneshot services. -* maybe implement "systemctl mask" and "systemctl unmask", but not +* Maybe implement "systemctl mask" and "systemctl unmask", but not document it? When doing that add switch to make this temporary by placing mask links in /dev. + Consider moving the actual fs operations into systemd behind a D-Bus + interface, to make namespaces/containers/remote connections work properly. * detect LXC environment * invoke vhangup() before and after invoking getty - http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3c95c985fa91ecf6a0e29622bbdd13dcfc5ce9f1 + http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3c95c985fa91ecf6a0e29622bbdd13dcfc5ce9f1 * support "auto" and "comment=systemd.automount" at the same time for an fstab entry @@ -108,14 +114,14 @@ Features: - get PR_SET_ANCHOR merged: http://lkml.org/lkml/2010/2/2/165 * add VT tracking: - - provide CK functionality - - start getty only when actual vt switch happens (same model as - socket on-demand activation). allocate the next free tty and - start a getty there. this way, pressing alt-f[1-12] will switch - through running X and getty sessions, and any unallocated - activated tty will start a new getty. the hardcoding of - getty[1-6] will entirely go away. - - http://git.kernel.org/?p=linux/kernel/git/gregkh/tty-2.6.git;a=commitdiff;h=fbc92a3455577ab17615cbcb91826399061bd789 + - provide CK functionality + - start getty only when actual vt switch happens (same model as + socket on-demand activation). allocate the next free tty and + start a getty there. this way, pressing alt-f[1-12] will switch + through running X and getty sessions, and any unallocated + activated tty will start a new getty. the hardcoding of + getty[1-6] will entirely go away. + - http://git.kernel.org/?p=linux/kernel/git/gregkh/tty-2.6.git;a=commitdiff;h=fbc92a3455577ab17615cbcb91826399061bd789 * implicitly import "defaults" settings file into all types From cb7f69965d9e076fa387fef8d616051c8015855d Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 17 Mar 2011 23:22:49 +0300 Subject: [PATCH 082/200] dbus: consolidate service SysV conditionals No need to define the same set of properties twice. While on it, add FsckPassNo to introspection. --- src/dbus-service.c | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/src/dbus-service.c b/src/dbus-service.c index 6bb6a9d6e..4ba3891bf 100644 --- a/src/dbus-service.c +++ b/src/dbus-service.c @@ -26,34 +26,14 @@ #include "dbus-service.h" #ifdef HAVE_SYSV_COMPAT -#define BUS_SERVICE_INTERFACE \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \ - BUS_EXEC_COMMAND_INTERFACE("ExecStart") \ - BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \ - BUS_EXEC_COMMAND_INTERFACE("ExecReload") \ - BUS_EXEC_COMMAND_INTERFACE("ExecStop") \ - BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ - BUS_EXEC_CONTEXT_INTERFACE \ - " \n" \ - " \n" \ - " \n" \ - BUS_EXEC_STATUS_INTERFACE("ExecMain") \ - " \n" \ - " \n" \ +#define BUS_SERVICE_SYSV_INTERFACE_FRAGMENT \ " \n" \ " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" + " \n" #else +#define BUS_SERVICE_SYSV_INTERFACE_FRAGMENT "" +#endif + #define BUS_SERVICE_INTERFACE \ " \n" \ " \n" \ @@ -77,8 +57,9 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + BUS_SERVICE_SYSV_INTERFACE_FRAGMENT \ " \n" -#endif #define INTROSPECTION \ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ @@ -135,14 +116,12 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio BUS_EXEC_STATUS_PROPERTIES("org.freedesktop.systemd1.Service", u->service.main_exec_status, "ExecMain"), { "org.freedesktop.systemd1.Service", "MainPID", bus_property_append_pid, "u", &u->service.main_pid }, { "org.freedesktop.systemd1.Service", "ControlPID", bus_property_append_pid, "u", &u->service.control_pid }, -#ifdef HAVE_SYSV_COMPAT - { "org.freedesktop.systemd1.Service", "SysVPath", bus_property_append_string, "s", u->service.sysv_path }, -#endif { "org.freedesktop.systemd1.Service", "BusName", bus_property_append_string, "s", u->service.bus_name }, { "org.freedesktop.systemd1.Service", "StatusText", bus_property_append_string, "s", u->service.status_text }, #ifdef HAVE_SYSV_COMPAT { "org.freedesktop.systemd1.Service", "SysVRunLevels", bus_property_append_string, "s", u->service.sysv_runlevels }, { "org.freedesktop.systemd1.Service", "SysVStartPriority", bus_property_append_int, "i", &u->service.sysv_start_priority }, + { "org.freedesktop.systemd1.Service", "SysVPath", bus_property_append_string, "s", u->service.sysv_path }, #endif { "org.freedesktop.systemd1.Service", "FsckPassNo", bus_property_append_int, "i", &u->service.fsck_passno }, { NULL, NULL, NULL, NULL, NULL } From 893844ed434e35e6227e0b17c16b7047360170e2 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 17 Mar 2011 23:22:49 +0300 Subject: [PATCH 083/200] dbus: add service D-Bus property "Sockets" --- src/dbus-service.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dbus-service.c b/src/dbus-service.c index 4ba3891bf..9c3d73cbf 100644 --- a/src/dbus-service.c +++ b/src/dbus-service.c @@ -58,6 +58,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ BUS_SERVICE_SYSV_INTERFACE_FRAGMENT \ " \n" @@ -118,6 +119,7 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio { "org.freedesktop.systemd1.Service", "ControlPID", bus_property_append_pid, "u", &u->service.control_pid }, { "org.freedesktop.systemd1.Service", "BusName", bus_property_append_string, "s", u->service.bus_name }, { "org.freedesktop.systemd1.Service", "StatusText", bus_property_append_string, "s", u->service.status_text }, + { "org.freedesktop.systemd1.Service", "Sockets", bus_unit_append_dependencies, "as", u->service.configured_sockets }, #ifdef HAVE_SYSV_COMPAT { "org.freedesktop.systemd1.Service", "SysVRunLevels", bus_property_append_string, "s", u->service.sysv_runlevels }, { "org.freedesktop.systemd1.Service", "SysVStartPriority", bus_property_append_int, "i", &u->service.sysv_start_priority }, From 260abb780a135e4cae8c10715c7e85675efc345a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 03:13:15 +0100 Subject: [PATCH 084/200] exec: properly apply capability bounding set, add inverted bounding sets --- TODO | 17 +++++++------ man/systemd.exec.xml | 57 +++++++++++++++++++++++++++++++------------- src/dbus-execute.c | 18 ++++++++++++++ src/dbus-execute.h | 3 ++- src/execute.c | 15 +++++++++--- src/load-fragment.c | 21 ++++++++++++++-- 6 files changed, 101 insertions(+), 30 deletions(-) diff --git a/TODO b/TODO index d2614b73c..620cdfff0 100644 --- a/TODO +++ b/TODO @@ -23,23 +23,26 @@ F15: * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown (path: after installing inotify watches, recheck file again to fix race) -* capability_bounding_set_drop not used - -* rework syslog.service being up logic in PID 1 - * rsyslog.service should hook itself into syslog.target? * syslog.target should be pulled in by multi-user.target? * pull in .service from meta .targers AND vice versa too. i.e. syslog.target ←→ rsyslog.service, rpcbind similarly -* drop Names= option? Symlinks only should be used. We don't want to need to read all service files. - Features: + +* hide passwords on TAB + +* add switch to systemctl to show enabled but not running services. Or + another switch that shows service that have been running since + booting but aren't running anymore. + +* reuse mkdtemp namespace dirs in /tmp? + * don't strip facility from kmsg log messages as soon as that is possible. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=9d90c8d9cde929cbc575098e825d7c29d9f45054 -* recreate systemd'd D-Bus private socket file on SIGUSR2 +* recreate systemd's D-Bus private socket file on SIGUSR2 * be more specific what failed: Unmounting file systems. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index f96d181a9..fb8496f54 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -597,16 +597,34 @@ - Capabilities= - Controls the + CapabilityBoundingSet= + + Controls which + capabilities to include in the + capability bounding set for the + executed process. See capabilities7 - set for the executed process. Take a - capability string as described in - cap_from_text3. - Note that this capability set is - usually influenced by the capabilities - attached to the executed - file. + for details. Takes a whitespace + seperated list of capability names as + read by + cap_from_name3. + Capabilities listed will be included + in the bounding set, all others are + removed. If the list of capabilities + is prefixed with ~ all but the listed + capabilities will be included, the + effect of this assignment + inverted. Note that this option does + not actually set or unset any + capabilities in the effective, + permitted or inherited capability + sets. That's what + Capabilities= is + for. If this option is not used the + capability bounding set is not + modified on process execution, hence + no limits on the capabilities of the + process are enforced. @@ -625,16 +643,21 @@ - CapabilityBoundingSetDrop= - + Capabilities= Controls the - capability bounding set drop set for - the executed process. See capabilities7 - for details. Takes a list of - capability names as read by - cap_from_name3. - + set for the executed process. Take a + capability string describing the + effective, permitted and inherited + capability sets as documented in + cap_from_text3. + Note that these capability sets are + usually influenced by the capabilities + attached to the executed file. Due to + that + CapabilityBoundingSet= + is probably the much more useful + setting. diff --git a/src/dbus-execute.c b/src/dbus-execute.c index 504651fc9..35e6d377e 100644 --- a/src/dbus-execute.c +++ b/src/dbus-execute.c @@ -234,6 +234,24 @@ int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const ch return 0; } +int bus_execute_append_capability_bs(Manager *m, DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + uint64_t normal, inverted; + + assert(m); + assert(i); + assert(property); + assert(c); + + /* We store this negated internally, to match the kernel, bu + * we expose it normalized. */ + + normal = *(uint64_t*) data; + inverted = ~normal; + + return bus_property_append_uint64(m, i, property, &inverted); +} + int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; char *t = NULL; diff --git a/src/dbus-execute.h b/src/dbus-execute.h index 082456a9e..8bfaaaf12 100644 --- a/src/dbus-execute.h +++ b/src/dbus-execute.h @@ -131,7 +131,7 @@ { interface, "SyslogLevelPrefix", bus_property_append_bool, "b", &(context).syslog_level_prefix }, \ { interface, "Capabilities", bus_execute_append_capabilities, "s",&(context) }, \ { interface, "SecureBits", bus_property_append_int, "i", &(context).secure_bits }, \ - { interface, "CapabilityBoundingSetDrop", bus_property_append_uint64, "t", &(context).capability_bounding_set_drop }, \ + { interface, "CapabilityBoundingSet", bus_execute_append_capability_bs, "t", &(context).capability_bounding_set_drop }, \ { interface, "User", bus_property_append_string, "s", (context).user }, \ { interface, "Group", bus_property_append_string, "s", (context).group }, \ { interface, "SupplementaryGroups", bus_property_append_strv, "as", (context).supplementary_groups }, \ @@ -167,6 +167,7 @@ int bus_execute_append_cpu_sched_priority(Manager *m, DBusMessageIter *i, const int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_capability_bs(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_execute_append_command(Manager *m, DBusMessageIter *u, const char *property, void *data); int bus_execute_append_kill_mode(Manager *m, DBusMessageIter *i, const char *property, void *data); diff --git a/src/execute.c b/src/execute.c index c1edf61fb..a467411f7 100644 --- a/src/execute.c +++ b/src/execute.c @@ -1249,6 +1249,15 @@ int exec_spawn(ExecCommand *command, } } + if (context->capability_bounding_set_drop) + for (i = 0; i <= CAP_LAST_CAP; i++) + if (context->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) i)) { + if (prctl(PR_CAPBSET_DROP, i) < 0) { + r = EXIT_CAPABILITIES; + goto fail_child; + } + } + if (context->user) if (enforce_user(context, uid) < 0) { r = EXIT_USER; @@ -1664,15 +1673,15 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { (c->secure_bits & SECURE_NOROOT_LOCKED) ? "noroot-locked" : ""); if (c->capability_bounding_set_drop) { - fprintf(f, "%sCapabilityBoundingSetDrop:", prefix); + fprintf(f, "%sCapabilityBoundingSet:", prefix); for (i = 0; i <= CAP_LAST_CAP; i++) - if (c->capability_bounding_set_drop & (1 << i)) { + if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) i))) { char *t; if ((t = cap_to_name(i))) { fprintf(f, " %s", t); - free(t); + cap_free(t); } } diff --git a/src/load-fragment.c b/src/load-fragment.c index 334bc713b..ac22b9450 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -852,12 +852,24 @@ static int config_parse_bounding_set( char *w; size_t l; char *state; + bool invert = false; + uint64_t sum = 0; assert(filename); assert(lvalue); assert(rvalue); assert(data); + if (rvalue[0] == '~') { + invert = true; + rvalue++; + } + + /* Note that we store this inverted internally, since the + * kernel wants it like this. But we actually expose it + * non-inverted everywhere to have a fully normalized + * interface. */ + FOREACH_WORD_QUOTED(w, l, rvalue, state) { char *t; int r; @@ -874,9 +886,14 @@ static int config_parse_bounding_set( return 0; } - c->capability_bounding_set_drop |= 1 << cap; + sum |= ((uint64_t) 1ULL) << (uint64_t) cap; } + if (invert) + c->capability_bounding_set_drop |= sum; + else + c->capability_bounding_set_drop |= ~sum; + return 0; } @@ -1772,7 +1789,7 @@ static int load_from_path(Unit *u, const char *path) { { "SyslogLevelPrefix", config_parse_bool, &(context).syslog_level_prefix, section }, \ { "Capabilities", config_parse_capabilities, &(context), section }, \ { "SecureBits", config_parse_secure_bits, &(context), section }, \ - { "CapabilityBoundingSetDrop", config_parse_bounding_set, &(context), section }, \ + { "CapabilityBoundingSet", config_parse_bounding_set, &(context), section }, \ { "TimerSlackNSec", config_parse_timer_slack_nsec,&(context), section }, \ { "LimitCPU", config_parse_limit, &(context).rlimit[RLIMIT_CPU], section }, \ { "LimitFSIZE", config_parse_limit, &(context).rlimit[RLIMIT_FSIZE], section }, \ From 177b3ffedbfc1aea839324edeb1f35a1a754ef5b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 03:32:33 +0100 Subject: [PATCH 085/200] special: get rid of dbus.target --- Makefile.am | 1 - man/systemd.service.xml | 2 +- man/systemd.special.xml.in | 23 ----------------------- src/service.c | 2 +- src/special.h | 37 ++++++++++++++++++++----------------- units/dbus.target | 11 ----------- 6 files changed, 22 insertions(+), 54 deletions(-) delete mode 100644 units/dbus.target diff --git a/Makefile.am b/Makefile.am index 8d2343038..a94d2a7f7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -229,7 +229,6 @@ dist_systemunit_DATA = \ units/sigpwr.target \ units/sockets.target \ units/swap.target \ - units/dbus.target \ units/systemd-initctl.socket \ units/systemd-logger.socket \ units/systemd-shutdownd.socket \ diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 7200525c0..e444efeb4 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -180,7 +180,7 @@ acquired. Service units with this option configured implicitly gain dependencies on the - dbus.target + dbus.socket unit. Behaviour of diff --git a/man/systemd.special.xml.in b/man/systemd.special.xml.in index afe882e51..1506f3494 100644 --- a/man/systemd.special.xml.in +++ b/man/systemd.special.xml.in @@ -51,7 +51,6 @@ basic.target, ctrl-alt-del.target, dbus.service, - dbus.target, default.target, display-manager.service, emergency.target, @@ -143,28 +142,6 @@ up systemd will connect to it and register its service. - - Units should generally - avoid depending on this unit - directly and instead refer to - the - dbus.target - unit instead, which pulls this - one in directly or indirectly - via socket-based activation. - - - - dbus.target - - Administrators should - ensure that this target pulls - in a service unit with the - name or alias of - dbus.service - (or a socket unit that - activates this - service). diff --git a/src/service.c b/src/service.c index 0f28312b3..f0c72f2c2 100644 --- a/src/service.c +++ b/src/service.c @@ -1129,7 +1129,7 @@ static int service_load(Unit *u) { s->notify_access = NOTIFY_MAIN; if (s->type == SERVICE_DBUS || s->bus_name) - if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_TARGET, NULL, true)) < 0) + if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true)) < 0) return r; if (s->meta.default_dependencies) diff --git a/src/special.h b/src/special.h index 2f2d9e7b2..ba2bc143e 100644 --- a/src/special.h +++ b/src/special.h @@ -30,17 +30,24 @@ * system shutdown. */ #define SPECIAL_SHUTDOWN_TARGET "shutdown.target" #define SPECIAL_UMOUNT_TARGET "umount.target" +#define SPECIAL_HALT_TARGET "halt.target" +#define SPECIAL_POWEROFF_TARGET "poweroff.target" +#define SPECIAL_REBOOT_TARGET "reboot.target" +#define SPECIAL_KEXEC_TARGET "kexec.target" +#define SPECIAL_EXIT_TARGET "exit.target" -#define SPECIAL_LOGGER_SOCKET "systemd-logger.socket" - -#define SPECIAL_KBREQUEST_TARGET "kbrequest.target" -#define SPECIAL_SIGPWR_TARGET "sigpwr.target" -#define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target" +#define SPECIAL_RESCUE_TARGET "rescue.target" +#define SPECIAL_EMERGENCY_TARGET "emergency.target" +#define SPECIAL_SYSINIT_TARGET "sysinit.target" +#define SPECIAL_SOCKETS_TARGET "sockets.target" #define SPECIAL_LOCAL_FS_TARGET "local-fs.target" /* LSB's $local_fs */ #define SPECIAL_REMOTE_FS_TARGET "remote-fs.target" /* LSB's $remote_fs */ #define SPECIAL_SWAP_TARGET "swap.target" +#define SPECIAL_BASIC_TARGET "basic.target" + #define SPECIAL_NETWORK_TARGET "network.target" /* LSB's $network */ + #define SPECIAL_NSS_LOOKUP_TARGET "nss-lookup.target" /* LSB's $named */ #define SPECIAL_RPCBIND_TARGET "rpcbind.target" /* LSB's $portmap */ #define SPECIAL_SYSLOG_TARGET "syslog.target" /* LSB's $syslog; Should pull in syslog.socket or syslog.service */ @@ -48,22 +55,18 @@ #define SPECIAL_DISPLAY_MANAGER_SERVICE "display-manager.service" /* Debian's $x-display-manager */ #define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Debian's $mail-{transport|transfer-agent */ #define SPECIAL_HTTP_DAEMON_TARGET "http-daemon.target" -#define SPECIAL_DBUS_TARGET "dbus.target" -#define SPECIAL_BASIC_TARGET "basic.target" -#define SPECIAL_SOCKETS_TARGET "sockets.target" -#define SPECIAL_SYSINIT_TARGET "sysinit.target" + #define SPECIAL_FSCK_SERVICE "fsck@.service" #define SPECIAL_QUOTACHECK_SERVICE "quotacheck.service" -#define SPECIAL_RESCUE_TARGET "rescue.target" -#define SPECIAL_EXIT_TARGET "exit.target" -#define SPECIAL_EMERGENCY_TARGET "emergency.target" -#define SPECIAL_HALT_TARGET "halt.target" -#define SPECIAL_POWEROFF_TARGET "poweroff.target" -#define SPECIAL_REBOOT_TARGET "reboot.target" -#define SPECIAL_KEXEC_TARGET "kexec.target" +#define SPECIAL_REMOUNT_ROOTFS_SERVICE "remount-rootfs.service" + #define SPECIAL_DBUS_SERVICE "dbus.service" #define SPECIAL_DBUS_SOCKET "dbus.socket" -#define SPECIAL_REMOUNT_ROOTFS_SERVICE "remount-rootfs.service" +#define SPECIAL_LOGGER_SOCKET "systemd-logger.socket" + +#define SPECIAL_KBREQUEST_TARGET "kbrequest.target" +#define SPECIAL_SIGPWR_TARGET "sigpwr.target" +#define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target" #ifndef SPECIAL_SYSLOG_SERVICE #define SPECIAL_SYSLOG_SERVICE "syslog.service" diff --git a/units/dbus.target b/units/dbus.target deleted file mode 100644 index 63897685c..000000000 --- a/units/dbus.target +++ /dev/null @@ -1,11 +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. - -# See systemd.special(7) for details - -[Unit] -Description=D-Bus From 0732ec002ea941f32e8def518150d2b6423315e3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 03:32:47 +0100 Subject: [PATCH 086/200] man: document .requires/ directories --- man/systemd.unit.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 54903fb52..2ae986ad0 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -139,7 +139,10 @@ with the enable command of the systemctl1 tool which reads information from the [Install] - section of unit files. (See below.) + section of unit files. (See below.) A similar + functionality exists for Requires= + type dependencies as well, the directory suffix is + .requires/ in this case. Note that while systemd offers a flexible dependency system between units it is recommended to From f1dd0c3f9b4a257e81ff9c6a08070c702a0db45a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 04:31:22 +0100 Subject: [PATCH 087/200] syslog: rework syslog detection so that we need no compile-time option what the name of the syslog implementation is --- Makefile.am | 1 - TODO | 2 ++ configure.ac | 39 +------------------------------ man/systemd.special.xml.in | 31 ------------------------- src/manager.c | 47 ++++++++++++++++++++++++++++++++++++++ src/manager.h | 2 ++ src/special.h | 15 +++++++----- src/unit.c | 14 ++---------- units/syslog.target.in | 6 ----- 9 files changed, 63 insertions(+), 94 deletions(-) diff --git a/Makefile.am b/Makefile.am index a94d2a7f7..93225aac2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1102,7 +1102,6 @@ SED_PROCESS = \ $(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \ -e 's,@rootbindir\@,$(rootbindir),g' \ -e 's,@bindir\@,$(bindir),g' \ - -e 's,@SPECIAL_SYSLOG_SERVICE\@,$(SPECIAL_SYSLOG_SERVICE),g' \ -e 's,@SYSTEMCTL\@,$(rootbindir)/systemctl,g' \ -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \ -e 's,@pkgsysconfdir\@,$(pkgsysconfdir),g' \ diff --git a/TODO b/TODO index 620cdfff0..4191e5586 100644 --- a/TODO +++ b/TODO @@ -29,6 +29,8 @@ F15: * pull in .service from meta .targers AND vice versa too. i.e. syslog.target ←→ rsyslog.service, rpcbind similarly +* document default dependencies + Features: * hide passwords on TAB diff --git a/configure.ac b/configure.ac index 8a28c8e80..e6daf0354 100644 --- a/configure.ac +++ b/configure.ac @@ -297,30 +297,15 @@ fi with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' ` AC_DEFINE_UNQUOTED(DISTRIBUTION, ["${with_distro}"], [Target Distribution]) -# Default generic names -SPECIAL_SYSLOG_SERVICE=syslog.service - # Location of the init scripts as mandated by LSB SYSTEM_SYSVINIT_PATH=/etc/init.d +SYSTEM_SYSVRCND_PATH=/etc/rc.d M4_DISTRO_FLAG= case $with_distro in fedora) SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d - SYSTEM_SYSVRCND_PATH=/etc/rc.d - - # A little background why we define this special unit - # names here in configure.ac: SysV services currently - # cannot have aliases. As long as syslog is started - # via a SysV init script we hence define this name to - # the actual SysV name here. Later on when SysV init - # scripts are not used anymore it is advisable to use - # the generic name instead and use symlinks in the - # unit directories to point to the right native unit - # file. - - SPECIAL_SYSLOG_SERVICE=rsyslog.service AC_DEFINE(TARGET_FEDORA, [], [Target is Fedora/RHEL]) M4_DISTRO_FLAG=-DTARGET_FEDORA=1 have_plymouth=true @@ -333,61 +318,49 @@ case $with_distro in ;; debian) SYSTEM_SYSVRCND_PATH=/etc - SPECIAL_SYSLOG_SERVICE=rsyslog.service AC_DEFINE(TARGET_DEBIAN, [], [Target is Debian]) M4_DISTRO_FLAG=-DTARGET_DEBIAN=1 ;; ubuntu) SYSTEM_SYSVRCND_PATH=/etc - SPECIAL_SYSLOG_SERVICE=rsyslog.service AC_DEFINE(TARGET_UBUNTU, [], [Target is Ubuntu]) M4_DISTRO_FLAG=-DTARGET_UBUNTU=1 ;; arch) SYSTEM_SYSVINIT_PATH=/etc/rc.d SYSTEM_SYSVRCND_PATH=/etc - SPECIAL_SYSLOG_SERVICE=syslog-ng.service AC_DEFINE(TARGET_ARCH, [], [Target is ArchLinux]) M4_DISTRO_FLAG=-DTARGET_ARCH=1 ;; gentoo) SYSTEM_SYSVINIT_PATH= SYSTEM_SYSVRCND_PATH= - SPECIAL_SYSLOG_SERVICE=syslog-ng.service AC_DEFINE(TARGET_GENTOO, [], [Target is Gentoo]) M4_DISTRO_FLAG=-DTARGET_GENTOO=1 ;; slackware) SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d - SYSTEM_SYSVRCND_PATH=/etc/rc.d AC_DEFINE(TARGET_SLACKWARE, [], [Target is Slackware]) M4_DISTRO_FLAG=-DTARGET_SLACKWARE=1 ;; frugalware) SYSTEM_SYSVINIT_PATH=/etc/rc.d - SYSTEM_SYSVRCND_PATH=/etc/rc.d AC_DEFINE(TARGET_FRUGALWARE, [], [Target is Frugalware]) M4_DISTRO_FLAG=-DTARGET_FRUGALWARE=1 ;; altlinux) SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d - SYSTEM_SYSVRCND_PATH=/etc/rc.d - SPECIAL_SYSLOG_SERVICE=syslogd.service AC_DEFINE(TARGET_ALTLINUX, [], [Target is ALTLinux]) M4_DISTRO_FLAG=-DTARGET_ALTLINUX=1 have_plymouth=true ;; mandriva) SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d - SYSTEM_SYSVRCND_PATH=/etc/rc.d - SPECIAL_SYSLOG_SERVICE=rsyslog.service AC_DEFINE(TARGET_MANDRIVA, [], [Target is Mandriva]) M4_DISTRO_FLAG=-DTARGET_MANDRIVA=1 have_plymouth=true ;; other) - AS_IF([test "x$with_syslog_service" = "x"], - [AC_MSG_ERROR([With --distro=other, you must pass --with-syslog-service= to configure])]) ;; *) AC_MSG_ERROR([Your distribution (${with_distro}) is not yet supported, SysV init scripts could not be found! (patches welcome); you can specify --with-distro=other to skip this check]) @@ -406,15 +379,8 @@ AC_ARG_WITH([sysvrcd-path], [SYSTEM_SYSVRCND_PATH="$withval"], []) -AC_ARG_WITH([syslog-service], - [AS_HELP_STRING([--with-syslog-service=UNIT], - [Specify the name of the special syslog service @<:@default=based on distro@:>@])], - [SPECIAL_SYSLOG_SERVICE="$withval"], - []) - AC_SUBST(SYSTEM_SYSVINIT_PATH) AC_SUBST(SYSTEM_SYSVRCND_PATH) -AC_SUBST(SPECIAL_SYSLOG_SERVICE) AC_SUBST(M4_DISTRO_FLAG) if test "x${SYSTEM_SYSVINIT_PATH}" != "x" -a "x${SYSTEM_SYSVRCND_PATH}" != "x"; then @@ -446,8 +412,6 @@ AM_CONDITIONAL(TARGET_MANDRIVA, test x"$with_distro" = xmandriva) AM_CONDITIONAL(HAVE_PLYMOUTH, test -n "$have_plymouth") -AC_DEFINE_UNQUOTED(SPECIAL_SYSLOG_SERVICE, ["$SPECIAL_SYSLOG_SERVICE"], [Syslog service name]) - AC_ARG_WITH([dbuspolicydir], AS_HELP_STRING([--with-dbuspolicydir=DIR], [D-Bus policy directory]), [], @@ -501,7 +465,6 @@ echo " SysV compatibility: ${SYSTEM_SYSV_COMPAT} SysV init scripts: ${SYSTEM_SYSVINIT_PATH} SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH} - Syslog service: ${SPECIAL_SYSLOG_SERVICE} Gtk: ${have_gtk} libcryptsetup: ${have_libcryptsetup} tcpwrap: ${have_tcpwrap} diff --git a/man/systemd.special.xml.in b/man/systemd.special.xml.in index 1506f3494..df62e9c4c 100644 --- a/man/systemd.special.xml.in +++ b/man/systemd.special.xml.in @@ -78,7 +78,6 @@ sockets.target, swap.target, sysinit.target, - @SPECIAL_SYSLOG_SERVICE@, syslog.target, systemd-initctl.service, systemd-initctl.socket, @@ -542,27 +541,6 @@ or b. - - @SPECIAL_SYSLOG_SERVICE@ - - A special unit for the - syslog daemon. As soon as - this service is fully started - up systemd will connect to it - and use it for logging if it - has been configured for - that. - - Units should generally - avoid depending on this unit - directly and instead refer to - the - syslog.target - unit instead, which pulls this - one in directly or indirectly - via socket-based activation. - - syslog.target @@ -574,15 +552,6 @@ referring to the $syslog facility. - - Administrators should - ensure that this target pulls - in a service unit with the - name or alias of - @SPECIAL_SYSLOG_SERVICE@ - (or a socket unit that - activates this - service). diff --git a/src/manager.c b/src/manager.c index 9edb8f09b..a9aaee3d8 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2451,6 +2451,12 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) { if (m->n_deserializing > 0) return; + if (m->running_as != MANAGER_SYSTEM) + return; + + if (u->meta.type != UNIT_SERVICE) + return; + if (!(p = unit_name_to_prefix_and_instance(u->meta.id))) { log_error("Failed to allocate unit name for audit message: %s", strerror(ENOMEM)); return; @@ -2965,6 +2971,47 @@ int manager_set_default_controllers(Manager *m, char **controllers) { return 0; } +void manager_recheck_syslog(Manager *m) { + Unit *u; + + assert(m); + + if (m->running_as != MANAGER_SYSTEM) + return; + + if ((u = manager_get_unit(m, SPECIAL_SYSLOG_SOCKET))) { + SocketState state; + + state = SOCKET(u)->state; + + if (state != SOCKET_DEAD && + state != SOCKET_FAILED && + state != SOCKET_RUNNING) { + + /* Hmm, the socket is not set up, or is still + * listening, let's better not try to use + * it. Note that we have no problem if the + * socket is completely down, since there + * might be a foreign /dev/log socket around + * and we want to make use of that. + */ + + log_close_syslog(); + return; + } + } + + if ((u = manager_get_unit(m, SPECIAL_SYSLOG_TARGET))) + if (TARGET(u)->state != TARGET_ACTIVE) { + log_close_syslog(); + return; + } + + /* Hmm, OK, so the socket is either fully up, or fully down, + * and the target is up, then let's make use of the socket */ + log_open(); +} + static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = { [MANAGER_SYSTEM] = "system", [MANAGER_USER] = "user" diff --git a/src/manager.h b/src/manager.h index efca4ff7f..c183e105a 100644 --- a/src/manager.h +++ b/src/manager.h @@ -285,6 +285,8 @@ void manager_check_finished(Manager *m); void manager_run_generators(Manager *m); void manager_undo_generators(Manager *m); +void manager_recheck_syslog(Manager *m); + const char *manager_running_as_to_string(ManagerRunningAs i); ManagerRunningAs manager_running_as_from_string(const char *s); diff --git a/src/special.h b/src/special.h index ba2bc143e..6a75e2cf7 100644 --- a/src/special.h +++ b/src/special.h @@ -24,21 +24,24 @@ #define SPECIAL_DEFAULT_TARGET "default.target" +/* Shutdown targets */ +#define SPECIAL_UMOUNT_TARGET "umount.target" /* This is not really intended to be started by directly. This is * mostly so that other targets (reboot/halt/poweroff) can depend on * it to bring all services down that want to be brought down on * system shutdown. */ #define SPECIAL_SHUTDOWN_TARGET "shutdown.target" -#define SPECIAL_UMOUNT_TARGET "umount.target" #define SPECIAL_HALT_TARGET "halt.target" #define SPECIAL_POWEROFF_TARGET "poweroff.target" #define SPECIAL_REBOOT_TARGET "reboot.target" #define SPECIAL_KEXEC_TARGET "kexec.target" #define SPECIAL_EXIT_TARGET "exit.target" +/* Special boot targets */ #define SPECIAL_RESCUE_TARGET "rescue.target" #define SPECIAL_EMERGENCY_TARGET "emergency.target" +/* Early boot targets */ #define SPECIAL_SYSINIT_TARGET "sysinit.target" #define SPECIAL_SOCKETS_TARGET "sockets.target" #define SPECIAL_LOCAL_FS_TARGET "local-fs.target" /* LSB's $local_fs */ @@ -46,8 +49,8 @@ #define SPECIAL_SWAP_TARGET "swap.target" #define SPECIAL_BASIC_TARGET "basic.target" +/* LSB compatibility */ #define SPECIAL_NETWORK_TARGET "network.target" /* LSB's $network */ - #define SPECIAL_NSS_LOOKUP_TARGET "nss-lookup.target" /* LSB's $named */ #define SPECIAL_RPCBIND_TARGET "rpcbind.target" /* LSB's $portmap */ #define SPECIAL_SYSLOG_TARGET "syslog.target" /* LSB's $syslog; Should pull in syslog.socket or syslog.service */ @@ -56,22 +59,22 @@ #define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Debian's $mail-{transport|transfer-agent */ #define SPECIAL_HTTP_DAEMON_TARGET "http-daemon.target" +/* Magic early boot services */ #define SPECIAL_FSCK_SERVICE "fsck@.service" #define SPECIAL_QUOTACHECK_SERVICE "quotacheck.service" #define SPECIAL_REMOUNT_ROOTFS_SERVICE "remount-rootfs.service" +/* Services systemd relies on */ #define SPECIAL_DBUS_SERVICE "dbus.service" #define SPECIAL_DBUS_SOCKET "dbus.socket" #define SPECIAL_LOGGER_SOCKET "systemd-logger.socket" +#define SPECIAL_SYSLOG_SOCKET "syslog.socket" +/* Magic init signals */ #define SPECIAL_KBREQUEST_TARGET "kbrequest.target" #define SPECIAL_SIGPWR_TARGET "sigpwr.target" #define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target" -#ifndef SPECIAL_SYSLOG_SERVICE -#define SPECIAL_SYSLOG_SERVICE "syslog.service" -#endif - /* For SysV compatibility. Usually an alias for a saner target. On * SysV-free systems this doesn't exist. */ #define SPECIAL_RUNLEVEL2_TARGET "runlevel2.target" diff --git a/src/unit.c b/src/unit.c index 10de40aff..6f10f51fb 100644 --- a/src/unit.c +++ b/src/unit.c @@ -1224,12 +1224,6 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su * yet connected. */ bus_init(u->meta.manager, true); - if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE)) - /* The syslog daemon just might have become - * available, hence try to connect to it, if - * we aren't yet connected. */ - log_open(); - if (u->meta.type == UNIT_SERVICE && !UNIT_IS_ACTIVE_OR_RELOADING(os)) { /* Write audit record if we have just finished starting up */ @@ -1242,12 +1236,6 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su } else { - if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE)) - /* The syslog daemon might just have - * terminated, hence try to disconnect from - * it. */ - log_close_syslog(); - /* We don't care about D-Bus here, since we'll get an * asynchronous notification for it anyway. */ @@ -1277,6 +1265,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su unit_add_to_dbus_queue(u); unit_add_to_gc_queue(u); + + manager_recheck_syslog(u->meta.manager); } int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) { diff --git a/units/syslog.target.in b/units/syslog.target.in index 37d5de368..d5410cf58 100644 --- a/units/syslog.target.in +++ b/units/syslog.target.in @@ -9,9 +9,3 @@ [Unit] Description=Syslog - -# As soon as all syslog services have native unit files this explicit -# dependency should be dropped, and replaced by alias symlinks in the -# .wants/ directory, to either the .service or .socket unit of the -# syslog service. -After=@SPECIAL_SYSLOG_SERVICE@ From 997a624029822ebdabf834605831bf87ce0b3085 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 04:32:58 +0100 Subject: [PATCH 088/200] units: get rid of empty units/suse/ subdir --- units/suse/Makefile | 1 - 1 file changed, 1 deletion(-) delete mode 120000 units/suse/Makefile diff --git a/units/suse/Makefile b/units/suse/Makefile deleted file mode 120000 index 50be21181..000000000 --- a/units/suse/Makefile +++ /dev/null @@ -1 +0,0 @@ -../../src/Makefile \ No newline at end of file From 97df13c0ac43addbf2317e438d80aa78e90c3f92 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 04:37:31 +0100 Subject: [PATCH 089/200] units: get rid of runlevel Names=, the symlinks in /lib/systemd/system are much more useful --- units/graphical.target.m4 | 14 -------------- units/multi-user.target.m4 | 20 -------------------- units/poweroff.target | 1 - units/reboot.target | 1 - units/rescue.target | 1 - 5 files changed, 37 deletions(-) diff --git a/units/graphical.target.m4 b/units/graphical.target.m4 index 1931d7f98..f2e30341d 100644 --- a/units/graphical.target.m4 +++ b/units/graphical.target.m4 @@ -12,20 +12,6 @@ Description=Graphical Interface Requires=multi-user.target After=multi-user.target Conflicts=rescue.target -m4_dnl -m4_ifdef(`TARGET_FEDORA', -# On Fedora Runlevel 5 is graphical login -Names=runlevel5.target -)m4_dnl -m4_ifdef(`TARGET_SUSE', -Names=runlevel5.target -)m4_dnl -m4_ifdef(`TARGET_ALTLINUX', -Names=runlevel5.target -)m4_dnl -m4_ifdef(`TARGET_MANDRIVA', -Names=runlevel5.target -)m4_dnl AllowIsolate=yes [Install] diff --git a/units/multi-user.target.m4 b/units/multi-user.target.m4 index 51e7b6664..66f1a950f 100644 --- a/units/multi-user.target.m4 +++ b/units/multi-user.target.m4 @@ -12,26 +12,6 @@ Description=Multi-User Requires=basic.target Conflicts=rescue.service rescue.target After=basic.target rescue.service rescue.target -m4_dnl -m4_ifdef(`TARGET_FEDORA', -m4_dnl On Fedora Runlevel 3 is multi-user -Names=runlevel3.target -)m4_dnl -m4_ifdef(`TARGET_SUSE', -Names=runlevel3.target -)m4_dnl -m4_ifdef(`TARGET_ALTLINUX', -Names=runlevel3.target -)m4_dnl -m4_ifdef(`TARGET_DEBIAN', -m4_ifdef(`TARGET_UBUNTU', -m4_dnl On Debian/Ubuntu Runlevel 2, 3, 4 and 5 are multi-user -Names=runlevel2.target runlevel3.target runlevel4.target runlevel5.target -)m4_dnl -)m4_dnl -m4_ifdef(`TARGET_MANDRIVA', -Names=runlevel3.target -)m4_dnl AllowIsolate=yes [Install] diff --git a/units/poweroff.target b/units/poweroff.target index 975b08896..d2ccf4b2c 100644 --- a/units/poweroff.target +++ b/units/poweroff.target @@ -10,7 +10,6 @@ [Unit] Description=Power-Off DefaultDependencies=no -Names=runlevel0.target Requires=poweroff.service After=poweroff.service AllowIsolate=yes diff --git a/units/reboot.target b/units/reboot.target index 2cd46a062..41e133cb7 100644 --- a/units/reboot.target +++ b/units/reboot.target @@ -10,7 +10,6 @@ [Unit] Description=Reboot DefaultDependencies=no -Names=runlevel6.target Requires=reboot.service After=reboot.service AllowIsolate=yes diff --git a/units/rescue.target b/units/rescue.target index ff3aef033..5bf3f8e8e 100644 --- a/units/rescue.target +++ b/units/rescue.target @@ -11,7 +11,6 @@ Description=Rescue Mode Requires=basic.target rescue.service After=basic.target rescue.service -Names=runlevel1.target AllowIsolate=yes [Install] From b1c66c44ef9e312805295395d728e47cdd08335c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 04:41:47 +0100 Subject: [PATCH 090/200] units: on mandriva/fedora create single.service alias via symlink, not Names= --- Makefile.am | 10 ++++++---- units/rescue.service.m4 | 3 --- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am index 93225aac2..3120e7864 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1411,8 +1411,9 @@ if TARGET_FEDORA rm -f halt-local.service && \ $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) ( cd $(DESTDIR)$(systemunitdir) && \ - rm -f display-manager.service && \ - $(LN_S) prefdm.service display-manager.service ) + rm -f display-manager.service single.service && \ + $(LN_S) prefdm.service display-manager.service && \ + $(LN_S) rescue.service single.service ) ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ rm -f display-manager.service && \ $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) @@ -1427,8 +1428,9 @@ if TARGET_MANDRIVA rm -f halt-local.service && \ $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) ( cd $(DESTDIR)$(systemunitdir) && \ - rm -f display-manager.service && \ - $(LN_S) prefdm.service display-manager.service ) + rm -f display-manager.service single.service && \ + $(LN_S) prefdm.service display-manager.service && \ + $(LN_S) rescue.service single.service ) ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ rm -f display-manager.service && \ $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) diff --git a/units/rescue.service.m4 b/units/rescue.service.m4 index 8b42e9f69..969ac4728 100644 --- a/units/rescue.service.m4 +++ b/units/rescue.service.m4 @@ -13,9 +13,6 @@ DefaultDependencies=no Conflicts=shutdown.target After=basic.target Before=shutdown.target -m4_ifdef(`TARGET_MANDRIVA', -`# Hide SysV script -Names=single.service') [Service] Environment=HOME=/root From e2130f189a543c859b569985d8670132df40673e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 04:49:38 +0100 Subject: [PATCH 091/200] units: deemphesize Names= settings, and explain why nobody whould use them --- man/systemd.unit.xml | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 2ae986ad0..ff199e43c 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -219,21 +219,6 @@ dependent on the type of unit: - - Names= - - Additional names for - this unit. The names listed here must - have the same suffix (i.e. type) as - the unit file name. This option may be - specified more than once, in which - case all listed names are used. Note - that this option is different from the - Alias= option from - the [Install] section mentioned - below. See below for details. - - Description= @@ -660,6 +645,35 @@ pipe symbol must be passed first, the exclamation second. + + + Names= + + Additional names for + this unit. The names listed here must + have the same suffix (i.e. type) as + the unit file name. This option may be + specified more than once, in which + case all listed names are used. Note + that this option is different from the + Alias= option from + the [Install] section mentioned + below. See below for details. Note + that in almost all cases this option + is not what you want. A symlink alias + in the file system is generally + preferable since it can be used as + lookup key. If a unit with a symlinked + alias name is not loaded and needs to + be it is easily found via the + symlink. However, if a unit with an + alias name configured with this + setting is not loaded it will not be + discovered. This settings' only use is + in conjunction with service + instances. + + Unit file may include a [Install] section, which From 28cf382a0afd10d0e2a71d152f0df4909e90d159 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 04:49:53 +0100 Subject: [PATCH 092/200] man: document pidns containers --- man/systemd.unit.xml | 1 + src/util.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index ff199e43c..d447c3a0a 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -618,6 +618,7 @@ microsoft, oracle, xen, + pidns, openvz to test against a specific implementation. The test may be negated by prepending an diff --git a/src/util.c b/src/util.c index c9c88927b..1febd073d 100644 --- a/src/util.c +++ b/src/util.c @@ -3991,7 +3991,7 @@ int detect_container(const char **id) { fclose(f); if (id) - *id = "ns"; + *id = "pidns"; return 1; } From db25d1d7655b1de4554942e49bc80a9b176ef8df Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 04:59:05 +0100 Subject: [PATCH 093/200] units: we no longer need m4 to build graphical.target or multi-user.taregt --- Makefile.am | 6 ++---- units/.gitignore | 2 -- units/{graphical.target.m4 => graphical.target} | 0 units/{multi-user.target.m4 => multi-user.target} | 0 4 files changed, 2 insertions(+), 6 deletions(-) rename units/{graphical.target.m4 => graphical.target} (100%) rename units/{multi-user.target.m4 => multi-user.target} (100%) diff --git a/Makefile.am b/Makefile.am index 3120e7864..5769dcb62 100644 --- a/Makefile.am +++ b/Makefile.am @@ -205,6 +205,8 @@ dist_tmpfiles_DATA = \ tmpfiles.d/x11.conf dist_systemunit_DATA = \ + units/graphical.target \ + units/multi-user.target \ units/emergency.service \ units/emergency.target \ units/sysinit.target \ @@ -263,9 +265,7 @@ nodist_systemunit_DATA = \ units/getty@.service \ units/serial-getty@.service \ units/console-shell.service \ - units/graphical.target \ units/remote-fs.target \ - units/multi-user.target \ units/systemd-initctl.service \ units/systemd-logger.service \ units/systemd-shutdownd.service \ @@ -308,8 +308,6 @@ EXTRA_DIST = \ units/getty@.service.m4 \ units/serial-getty@.service.m4 \ units/console-shell.service.m4 \ - units/graphical.target.m4 \ - units/multi-user.target.m4 \ units/remote-fs.target.m4 \ units/rescue.service.m4 \ units/systemd-initctl.service.in \ diff --git a/units/.gitignore b/units/.gitignore index a64cac13e..cb0c7d5c0 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -30,8 +30,6 @@ systemd-random-seed-save.service systemd-initctl.service systemd-logger.service syslog.target -graphical.target -multi-user.target getty@.service remote-fs.target systemd-update-utmp-runlevel.service diff --git a/units/graphical.target.m4 b/units/graphical.target similarity index 100% rename from units/graphical.target.m4 rename to units/graphical.target diff --git a/units/multi-user.target.m4 b/units/multi-user.target similarity index 100% rename from units/multi-user.target.m4 rename to units/multi-user.target From 6699c857a20378e1fd2a33e3e306a96404e7f83d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 05:01:30 +0100 Subject: [PATCH 094/200] units: we don't need to generate syslog.target with sed anymore --- Makefile.am | 5 ++--- units/.gitignore | 1 - units/{syslog.target.in => syslog.target} | 0 3 files changed, 2 insertions(+), 4 deletions(-) rename units/{syslog.target.in => syslog.target} (100%) diff --git a/Makefile.am b/Makefile.am index 5769dcb62..371cc562e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -259,7 +259,8 @@ dist_systemunit_DATA = \ units/systemd-tmpfiles-clean.timer \ units/quotaon.service \ units/systemd-ask-password-wall.path \ - units/systemd-ask-password-console.path + units/systemd-ask-password-console.path \ + units/syslog.target nodist_systemunit_DATA = \ units/getty@.service \ @@ -286,7 +287,6 @@ nodist_systemunit_DATA = \ units/systemd-ask-password-wall.service \ units/systemd-ask-password-console.service \ units/systemd-sysctl.service \ - units/syslog.target \ units/halt.service \ units/poweroff.service \ units/reboot.service \ @@ -330,7 +330,6 @@ EXTRA_DIST = \ units/systemd-ask-password-wall.service.in \ units/systemd-ask-password-console.service.in \ units/systemd-sysctl.service.in \ - units/syslog.target.in \ units/halt.service.in \ units/poweroff.service.in \ units/reboot.service.in \ diff --git a/units/.gitignore b/units/.gitignore index cb0c7d5c0..41ab51b2a 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -29,7 +29,6 @@ systemd-random-seed-load.service systemd-random-seed-save.service systemd-initctl.service systemd-logger.service -syslog.target getty@.service remote-fs.target systemd-update-utmp-runlevel.service diff --git a/units/syslog.target.in b/units/syslog.target similarity index 100% rename from units/syslog.target.in rename to units/syslog.target From 1c7c17ea61727eb6af8159bb519beeced1c25eb4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 05:12:34 +0100 Subject: [PATCH 095/200] units: document that some targets exists only for compat with SysV --- units/http-daemon.target | 3 +++ units/mail-transfer-agent.target | 3 +++ units/nss-lookup.target | 3 +++ units/rpcbind.target | 3 +++ units/rtc-set.target | 3 +++ units/syslog.target | 3 +++ 6 files changed, 18 insertions(+) diff --git a/units/http-daemon.target b/units/http-daemon.target index bd7a1ef0d..45f10182e 100644 --- a/units/http-daemon.target +++ b/units/http-daemon.target @@ -7,5 +7,8 @@ # See systemd.special(7) for details +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + [Unit] Description=Web Server diff --git a/units/mail-transfer-agent.target b/units/mail-transfer-agent.target index 2640076d6..ebb1ea125 100644 --- a/units/mail-transfer-agent.target +++ b/units/mail-transfer-agent.target @@ -7,5 +7,8 @@ # See systemd.special(7) for details +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + [Unit] Description=Mail Transfer Agent diff --git a/units/nss-lookup.target b/units/nss-lookup.target index 3158441b2..dc3a06334 100644 --- a/units/nss-lookup.target +++ b/units/nss-lookup.target @@ -7,6 +7,9 @@ # See systemd.special(7) for details +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + [Unit] Description=Name Lookups Wants=network.target diff --git a/units/rpcbind.target b/units/rpcbind.target index 41eb3a507..a5cea8c57 100644 --- a/units/rpcbind.target +++ b/units/rpcbind.target @@ -7,5 +7,8 @@ # See systemd.special(7) for details +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + [Unit] Description=RPC Port Mapper diff --git a/units/rtc-set.target b/units/rtc-set.target index eabdaf458..df4c40298 100644 --- a/units/rtc-set.target +++ b/units/rtc-set.target @@ -7,5 +7,8 @@ # See systemd.special(7) for details +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + [Unit] Description=RTC Set diff --git a/units/syslog.target b/units/syslog.target index d5410cf58..8b1626ed5 100644 --- a/units/syslog.target +++ b/units/syslog.target @@ -7,5 +7,8 @@ # See systemd.special(7) for details +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + [Unit] Description=Syslog From d94ac66d3232054f1249821e74badeb4c99ae60e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 05:13:06 +0100 Subject: [PATCH 096/200] units: don't ever pull in SysV targets from other SysV targets --- units/nss-lookup.target | 1 - units/remote-fs.target.m4 | 1 - 2 files changed, 2 deletions(-) diff --git a/units/nss-lookup.target b/units/nss-lookup.target index dc3a06334..bdca03cd8 100644 --- a/units/nss-lookup.target +++ b/units/nss-lookup.target @@ -12,5 +12,4 @@ [Unit] Description=Name Lookups -Wants=network.target After=network.target diff --git a/units/remote-fs.target.m4 b/units/remote-fs.target.m4 index f70fda464..53054b6ec 100644 --- a/units/remote-fs.target.m4 +++ b/units/remote-fs.target.m4 @@ -12,7 +12,6 @@ Description=Remote File Systems m4_dnl m4_ifdef(`FOR_SYSTEM', m4_dnl When running in system mode we need the network up -Requires=network.target After=network.target )m4_dnl From a0e155d440173ba524918cb3800350b452952082 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 05:17:02 +0100 Subject: [PATCH 097/200] units: pull in syslog.target from syslog.socket --- TODO | 6 +----- units/syslog.socket | 3 +++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 4191e5586..297d616e8 100644 --- a/TODO +++ b/TODO @@ -23,11 +23,7 @@ F15: * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown (path: after installing inotify watches, recheck file again to fix race) -* rsyslog.service should hook itself into syslog.target? - -* syslog.target should be pulled in by multi-user.target? - -* pull in .service from meta .targers AND vice versa too. i.e. syslog.target ←→ rsyslog.service, rpcbind similarly +* NM should pull in network.target, ntpd should pull in rtc-set.target. * document default dependencies diff --git a/units/syslog.socket b/units/syslog.socket index d4bbc4d9f..500bb7c31 100644 --- a/units/syslog.socket +++ b/units/syslog.socket @@ -12,6 +12,9 @@ Description=Syslog Socket DefaultDependencies=no Before=sockets.target syslog.target +# Pull in syslog.target to tell people that /dev/log is now accessible +Wants=syslog.target + [Socket] ListenDatagram=/dev/log SocketMode=0666 From 9700edb4e836f95815ee3237e5bc8d224b5014d7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2011 05:26:25 +0100 Subject: [PATCH 098/200] service: pull in sysv facility targets from the sysv units, not the other way round For an explanation see: http://lists.freedesktop.org/archives/systemd-devel/2011-March/001692.html --- TODO | 2 ++ src/service.c | 25 +++++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index 297d616e8..4916da2b6 100644 --- a/TODO +++ b/TODO @@ -25,6 +25,8 @@ F15: * NM should pull in network.target, ntpd should pull in rtc-set.target. +* fix sysv parser to add right wants dependencies + * document default dependencies Features: diff --git a/src/service.c b/src/service.c index f0c72f2c2..1735a96c8 100644 --- a/src/service.c +++ b/src/service.c @@ -655,16 +655,21 @@ static int service_load_sysv_path(Service *s, const char *path) { if (unit_name_to_type(m) == UNIT_SERVICE) r = unit_add_name(u, m); - else { - r = unit_add_dependency_by_name(u, UNIT_BEFORE, m, NULL, true); - - if (s->sysv_enabled) { - int k; - - if ((k = unit_add_dependency_by_name_inverse(u, UNIT_WANTS, m, NULL, true)) < 0) - r = k; - } - } + else + /* NB: SysV targets + * which are provided + * by a service are + * pulled in by the + * services, as an + * indication that the + * generic service is + * now available. This + * is strictly + * one-way. The + * targets do NOT pull + * in the SysV + * services! */ + r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_WANTS, m, NULL, true); if (r < 0) log_error("[%s:%u] Failed to add LSB Provides name %s, ignoring: %s", path, line, m, strerror(-r)); From 0c380104cfc52b69ab39737722e8e91fbad6c676 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Fri, 18 Mar 2011 19:12:58 +0300 Subject: [PATCH 099/200] mount: pull in quota services from local mountpoints with usr/grpquota options --- Makefile.am | 4 ---- src/mount.c | 17 +++++++++++++++-- src/special.h | 1 + units/quotacheck.service.in | 3 --- units/quotaon.service | 3 --- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Makefile.am b/Makefile.am index 371cc562e..8df636f39 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1327,10 +1327,6 @@ install-data-hook: $(LN_S) $(systemunitdir)/getty@.service getty@tty4.service && \ $(LN_S) $(systemunitdir)/getty@.service getty@tty5.service && \ $(LN_S) $(systemunitdir)/getty@.service getty@tty6.service ) - ( cd $(DESTDIR)$(pkgsysconfdir)/system/local-fs.target.wants && \ - rm -f quotaon.service quotacheck.service && \ - $(LN_S) $(systemunitdir)/quotacheck.service quotacheck.service && \ - $(LN_S) $(systemunitdir)/quotaon.service quotaon.service ) ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ rm -f remote-fs.target && \ $(LN_S) $(systemunitdir)/remote-fs.target remote-fs.target ) diff --git a/src/mount.c b/src/mount.c index 39525b665..99867172c 100644 --- a/src/mount.c +++ b/src/mount.c @@ -413,9 +413,22 @@ static int mount_add_default_dependencies(Mount *m) { if (m->meta.manager->running_as == MANAGER_SYSTEM && !path_equal(m->where, "/")) { + MountParameters *p; - if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, SPECIAL_QUOTACHECK_SERVICE, NULL, true)) < 0) - return r; + if (m->from_fragment) + p = &m->parameters_fragment; + else if (m->from_etc_fstab) + p = &m->parameters_etc_fstab; + else + p = NULL; + + if (!p || + (!mount_test_option(p->options, "_netdev") && + !(p->fstype && fstype_is_network(p->fstype)) && + (mount_test_option(p->options, "usrquota") || mount_test_option(p->options, "grpquota")))) + if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true)) < 0 || + (r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true)) < 0) + return r; if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) return r; diff --git a/src/special.h b/src/special.h index 6a75e2cf7..6cedf18c0 100644 --- a/src/special.h +++ b/src/special.h @@ -62,6 +62,7 @@ /* Magic early boot services */ #define SPECIAL_FSCK_SERVICE "fsck@.service" #define SPECIAL_QUOTACHECK_SERVICE "quotacheck.service" +#define SPECIAL_QUOTAON_SERVICE "quotaon.service" #define SPECIAL_REMOUNT_ROOTFS_SERVICE "remount-rootfs.service" /* Services systemd relies on */ diff --git a/units/quotacheck.service.in b/units/quotacheck.service.in index d46a33564..ed1ddc558 100644 --- a/units/quotacheck.service.in +++ b/units/quotacheck.service.in @@ -18,6 +18,3 @@ RemainAfterExit=yes ExecStart=@rootlibexecdir@/systemd-quotacheck StandardOutput=syslog TimeoutSec=0 - -[Install] -WantedBy=local-fs.target diff --git a/units/quotaon.service b/units/quotaon.service index ddb51284d..2c7b36b4f 100644 --- a/units/quotaon.service +++ b/units/quotaon.service @@ -17,6 +17,3 @@ Type=oneshot RemainAfterExit=yes ExecStart=/sbin/quotaon -aug StandardOutput=syslog - -[Install] -WantedBy=local-fs.target From 8c944383c2c03fbd219f54660f7ce99bea70dfd8 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Fri, 18 Mar 2011 19:32:49 +0300 Subject: [PATCH 100/200] units: replace Names=dm.service with symlink for mandriva prefdm --- Makefile.am | 3 ++- units/mandriva/prefdm.service | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 8df636f39..130e76c45 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1421,8 +1421,9 @@ if TARGET_MANDRIVA rm -f halt-local.service && \ $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) ( cd $(DESTDIR)$(systemunitdir) && \ - rm -f display-manager.service single.service && \ + rm -f display-manager.service dm.service single.service && \ $(LN_S) prefdm.service display-manager.service && \ + $(LN_S) prefdm.service dm.service && \ $(LN_S) rescue.service single.service ) ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ rm -f display-manager.service && \ diff --git a/units/mandriva/prefdm.service b/units/mandriva/prefdm.service index 43b505db8..d0c7f99c6 100644 --- a/units/mandriva/prefdm.service +++ b/units/mandriva/prefdm.service @@ -14,9 +14,6 @@ After=network.target acpid.service fs.service haldaemon.service Conflicts=plymouth-quit.service After=plymouth-quit.service -# Hide SysV script -Names=dm.service - [Service] ExecStart=/etc/X11/prefdm Type=forking From 4d99d2fd3cc3c02173ad935f94a6f96195fc9e2b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 21 Mar 2011 15:09:12 +0100 Subject: [PATCH 101/200] update TODO --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 4916da2b6..231d5b9bc 100644 --- a/TODO +++ b/TODO @@ -33,6 +33,9 @@ Features: * hide passwords on TAB +* get rid of random file name in generator directory? + /run/systemd/generator-IH1vFu + * add switch to systemctl to show enabled but not running services. Or another switch that shows service that have been running since booting but aren't running anymore. From 2fccaefffe4391bbd7e743e84c970424388b0ae2 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Tue, 22 Mar 2011 20:31:10 +0300 Subject: [PATCH 102/200] man: no keep-root in pam_systemd anymore --- man/pam_systemd.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index 915e0b601..43d239f49 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -284,7 +284,6 @@ , , , - , , , . From 7a03b1970c35c2b0924152404fb7526965eb4f3c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 23 Mar 2011 01:32:40 +0100 Subject: [PATCH 103/200] update TODO --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 231d5b9bc..11b9dbb9f 100644 --- a/TODO +++ b/TODO @@ -36,6 +36,9 @@ Features: * get rid of random file name in generator directory? /run/systemd/generator-IH1vFu +* fix SD_WARNING syslog stuff in src/sd-daemon.h to include the + facility + * add switch to systemctl to show enabled but not running services. Or another switch that shows service that have been running since booting but aren't running anymore. From 65c9e467528daa438167853cc91d37bfcb875836 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 24 Mar 2011 22:32:21 +0100 Subject: [PATCH 104/200] tainted: don't check if /usr is a mount point, only if it's not already mounted at startup --- src/dbus-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dbus-manager.c b/src/dbus-manager.c index 2edbc37b5..c21cb5f57 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -223,7 +223,7 @@ static int bus_manager_append_tainted(Manager *m, DBusMessageIter *i, const char assert(i); assert(property); - if (path_is_mount_point("/usr") > 0 || dir_is_empty("/usr") > 0) + if (dir_is_empty("/usr") > 0) e = stpcpy(e, "usr-separate-fs"); if (readlink_malloc("/etc/mtab", &p) < 0) { From f9276855a1d270b6c3f857cdaf2c4b49920c2228 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 28 Mar 2011 21:36:13 +0200 Subject: [PATCH 105/200] man: explain a couple of default dependencies --- TODO | 6 ++++-- man/systemd.swap.xml | 23 ++++++++++++++++++++--- man/systemd.target.xml | 13 +++++++------ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index 11b9dbb9f..0db681b76 100644 --- a/TODO +++ b/TODO @@ -25,12 +25,14 @@ F15: * NM should pull in network.target, ntpd should pull in rtc-set.target. -* fix sysv parser to add right wants dependencies - * document default dependencies +* remove KillMode=process-group + Features: +* when key file cannot be found, read it from kbd in cryptsetup + * hide passwords on TAB * get rid of random file name in generator directory? diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index 45f8f40ae..d95e39ed8 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -68,13 +68,23 @@ specific configuration options are configured in the [Swap] section. - Swap units must be named after the devices they - control. Example: the swap device + Swap units must be named after the devices + (resp. files) they control. Example: the swap device /dev/sda5 must be configured in a unit file dev-sda5.swap. For details about the escaping logic used to convert a file system path to a unit name see systemd.unit5. + + All swap units automatically get the appropriate + dependencies on the devices (resp. on the mount points + of the files) they are actived from. + + Swap units with + DefaultDependencies= enabled + implicitly acquire a conflicting dependency to + umount.target so that they are + deactivated at shutdown. @@ -88,6 +98,13 @@ If a swap device or file is configured in both /etc/fstab and a unit file the configuration in the latter takes precedence. + + Unless the option is set + for them all swap units configured in + /etc/fstab are also added as + requirements to swap.target, so + that they are waited for and activated during + boot. @@ -149,7 +166,7 @@ a time span value such as "5min 20s". Pass 0 to disable the timeout logic. Defaults to - 60s. + 3min. diff --git a/man/systemd.target.xml b/man/systemd.target.xml index 5c2642759..6b1dbfbde 100644 --- a/man/systemd.target.xml +++ b/man/systemd.target.xml @@ -83,14 +83,15 @@ systemd.special7 for details). - Unless - DefaultDependencies= is set to - , target units will - implicitly complement all configured dependencies of type - Wants=, + Unless DefaultDependencies= + is set to , target units will + implicitly complement all configured dependencies of + type Wants=, Requires=, RequiresOverridable= with - dependencies of type After=. + dependencies of type After= if the + units in question also have + DefaultDependencies=true. From 37f85e66e8f396b6f758e063531b95531aef628e Mon Sep 17 00:00:00 2001 From: cee1 Date: Fri, 18 Mar 2011 10:03:41 +0800 Subject: [PATCH 106/200] util: detect page size runtime. Some architectures support multiple machine types with diffenent page sizes, and some machine types even support multiple page sizes themselves. --- src/macro.h | 11 +++-------- src/readahead-collect.c | 3 ++- src/readahead-replay.c | 2 +- src/util.c | 14 ++++++++++++++ src/util.h | 3 +++ 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/macro.h b/src/macro.h index 996b7c2ed..e7a4d2cde 100644 --- a/src/macro.h +++ b/src/macro.h @@ -27,8 +27,6 @@ #include #include -#define PAGE_SIZE 4096 - #define _printf_attr_(a,b) __attribute__ ((format (printf, a, b))) #define _sentinel_ __attribute__ ((sentinel)) #define _noreturn_ __attribute__((noreturn)) @@ -51,12 +49,9 @@ #define STRINGIFY(x) XSTRINGIFY(x) /* Rounds up */ -static inline size_t ALIGN(size_t l) { - return ((l + sizeof(void*) - 1) & ~(sizeof(void*) - 1)); -} - -static inline size_t PAGE_ALIGN(size_t l) { - return ((l + PAGE_SIZE - 1) & ~(PAGE_SIZE -1)); +#define ALIGN(l) ALIGN_TO((l), sizeof(void*)) +static inline size_t ALIGN_TO(size_t l, size_t ali) { + return ((l + ali - 1) & ~(ali - 1)); } #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) diff --git a/src/readahead-collect.c b/src/readahead-collect.c index ca8227135..693729598 100644 --- a/src/readahead-collect.c +++ b/src/readahead-collect.c @@ -119,9 +119,10 @@ static int pack_file(FILE *pack, const char *fn, bool on_btrfs) { goto finish; } - pages = l / PAGE_SIZE; + pages = l / page_size(); vec = alloca(pages); + memset(vec, 0, pages); if (mincore(start, l, vec) < 0) { log_warning("mincore(%s) failed: %m", fn); r = -errno; diff --git a/src/readahead-replay.c b/src/readahead-replay.c index d2de7ef28..3984c36c3 100644 --- a/src/readahead-replay.c +++ b/src/readahead-replay.c @@ -94,7 +94,7 @@ static int unpack_file(FILE *pack) { any = true; if (fd >= 0) - if (posix_fadvise(fd, b * PAGE_SIZE, (c - b) * PAGE_SIZE, POSIX_FADV_WILLNEED) < 0) { + if (posix_fadvise(fd, b * page_size(), (c - b) * page_size(), POSIX_FADV_WILLNEED) < 0) { log_warning("posix_fadvise() failed: %m"); goto finish; } diff --git a/src/util.c b/src/util.c index 1febd073d..fada69cf1 100644 --- a/src/util.c +++ b/src/util.c @@ -61,6 +61,20 @@ #include "exit-status.h" #include "hashmap.h" +size_t page_size(void) { + static __thread size_t pgsz = 0; + long r; + + if (pgsz) + return pgsz; + + assert_se((r = sysconf(_SC_PAGESIZE)) > 0); + + pgsz = (size_t) r; + + return pgsz; +} + bool streq_ptr(const char *a, const char *b) { /* Like streq(), but tries to make sense of NULL pointers */ diff --git a/src/util.h b/src/util.h index 192ebff1f..04afc731e 100644 --- a/src/util.h +++ b/src/util.h @@ -83,6 +83,9 @@ struct timespec *timespec_store(struct timespec *ts, usec_t u); usec_t timeval_load(const struct timeval *tv); struct timeval *timeval_store(struct timeval *tv, usec_t u); +size_t page_size(void); +#define PAGE_ALIGN(l) ALIGN_TO((l), page_size()) + #define streq(a,b) (strcmp((a),(b)) == 0) #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) From 2b583ce6576d4a074ce6f1570b3e60b65c64ae7d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 25 Mar 2011 05:07:20 +0100 Subject: [PATCH 107/200] use /run instead of /dev/.run Instead of the /dev/.run trick we have currently implemented, we decided to move the early-boot runtime dir to /run. An existing /var/run directory is bind-mounted to /run. If /var/run is already a symlink, no action is taken. An existing /var/lock directory is bind-mounted to /run/lock. If /var/lock is already a symlink, no action is taken. To implement the directory vs. symlink logic, we have a: ConditionPathIsDirectory= now, which is used in the mount units. Skipped mount unit in case of symlink: $ systemctl status var-run.mount var-run.mount - Runtime Directory Loaded: loaded (/lib/systemd/system/var-run.mount) Active: inactive (dead) start condition failed at Fri, 25 Mar 2011 04:51:41 +0100; 6min ago Where: /var/run What: /run CGroup: name=systemd:/system/var-run.mount The systemd rpm needs to make sure to add something like: %pre mkdir -p -m0755 /run >/dev/null 2>&1 || : or it needs to be added to filesystem.rpm. Udev -git already uses /run if that exists, and is writable at bootup. Otherwise it falls back to the current /dev/.udev. Dracut and plymouth need to be adopted to switch from /dev/.run to run too. Cheers, Kay --- man/sd_readahead.xml | 2 +- man/systemd-nspawn.xml | 2 +- src/ask-password-api.c | 6 +- src/cgroups-agent.c | 2 +- src/condition.c | 8 + src/condition.h | 1 + src/conf-parser.c | 11 +- src/conf-parser.h | 22 +- src/dbus-common.c | 2 +- src/dbus.c | 4 +- src/execute.h | 2 +- src/fsck.c | 2 +- src/load-fragment.c | 352 +++++++++++++---------- src/machine-id-setup.c | 14 +- src/main.c | 34 +-- src/manager.c | 6 +- src/mount-setup.c | 6 +- src/mount.c | 4 + src/nspawn.c | 2 +- src/path-lookup.c | 2 +- src/quotacheck.c | 2 +- src/readahead-collect.c | 4 +- src/readahead-common.c | 14 +- src/readahead-replay.c | 2 +- src/sd-readahead.c | 10 +- src/systemctl.c | 12 +- src/tty-ask-password-agent.c | 24 +- systemd.pc.in | 2 +- tmpfiles.d/systemd.conf | 7 +- units/fsck-root.service.in | 2 +- units/plymouth-start.service | 2 +- units/systemd-ask-password-console.path | 2 +- units/systemd-ask-password-plymouth.path | 2 +- units/systemd-ask-password-wall.path | 2 +- units/systemd-logger.socket | 2 +- units/systemd-shutdownd.socket | 2 +- units/var-lock.mount | 8 +- units/var-run.mount | 4 +- 38 files changed, 329 insertions(+), 258 deletions(-) diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml index f5114e49a..004608dfb 100644 --- a/man/sd_readahead.xml +++ b/man/sd_readahead.xml @@ -123,7 +123,7 @@ reference implementation. Internally, this function creates a file in - /dev/.run/systemd/readahead/ which is + /run/systemd/readahead/ which is then used as flag file to notify the read-ahead subsystem. diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index 70ebf94e0..667e75c2c 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -99,7 +99,7 @@ Note that systemd-nspawn will mount file systems private to the container to /dev, - /dev/.run and similar. These will + /run and similar. These will not be visible outside of the container, and their contents will be lost when the container exits. diff --git a/src/ask-password-api.c b/src/ask-password-api.c index 9c3dad965..5d17d4cd5 100644 --- a/src/ask-password-api.c +++ b/src/ask-password-api.c @@ -223,7 +223,7 @@ static int create_socket(char **name) { zero(sa); sa.un.sun_family = AF_UNIX; - snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/dev/.run/systemd/ask-password/sck.%llu", random_ull()); + snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%llu", random_ull()); if (bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { r = -errno; @@ -265,7 +265,7 @@ int ask_password_agent( _FD_MAX }; - char temp[] = "/dev/.run/systemd/ask-password/tmp.XXXXXX"; + char temp[] = "/run/systemd/ask-password/tmp.XXXXXX"; char final[sizeof(temp)] = ""; int fd = -1, r; FILE *f = NULL; @@ -280,7 +280,7 @@ int ask_password_agent( sigset_add_many(&mask, SIGINT, SIGTERM, -1); assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); - mkdir_p("/dev/.run/systemd/ask-password", 0755); + mkdir_p("/run/systemd/ask-password", 0755); if ((fd = mkostemp(temp, O_CLOEXEC|O_CREAT|O_WRONLY)) < 0) { log_error("Failed to create password file: %m"); diff --git a/src/cgroups-agent.c b/src/cgroups-agent.c index 18612eca3..e0868b613 100644 --- a/src/cgroups-agent.c +++ b/src/cgroups-agent.c @@ -49,7 +49,7 @@ int main(int argc, char *argv[]) { * this to avoid an activation loop when we start dbus when we * are called when the dbus service is shut down. */ - if (!(bus = dbus_connection_open_private("unix:path=/dev/.run/systemd/private", &error))) { + if (!(bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error))) { #ifndef LEGACY dbus_error_free(&error); diff --git a/src/condition.c b/src/condition.c index 1dce276c0..61812c257 100644 --- a/src/condition.c +++ b/src/condition.c @@ -134,6 +134,14 @@ bool condition_test(Condition *c) { case CONDITION_PATH_EXISTS: return (access(c->parameter, F_OK) >= 0) == !c->negate; + case CONDITION_PATH_IS_DIRECTORY: { + struct stat st; + + if (lstat(c->parameter, &st) < 0) + return !c->negate; + return S_ISDIR(st.st_mode) == !c->negate; + } + case CONDITION_DIRECTORY_NOT_EMPTY: { int k; diff --git a/src/condition.h b/src/condition.h index 0ce713bc1..9913c8c84 100644 --- a/src/condition.h +++ b/src/condition.h @@ -28,6 +28,7 @@ typedef enum ConditionType { CONDITION_PATH_EXISTS, + CONDITION_PATH_IS_DIRECTORY, CONDITION_DIRECTORY_NOT_EMPTY, CONDITION_KERNEL_COMMAND_LINE, CONDITION_VIRTUALIZATION, diff --git a/src/conf-parser.c b/src/conf-parser.c index aac64b29a..a086cf7a0 100644 --- a/src/conf-parser.c +++ b/src/conf-parser.c @@ -61,7 +61,7 @@ static int next_assignment( if (!t->parse) return 0; - return t->parse(filename, line, section, lvalue, rvalue, t->data, userdata); + return t->parse(filename, line, section, lvalue, t->ltype, rvalue, t->data, userdata); } /* Warn about unknown non-extension fields. */ @@ -226,6 +226,7 @@ int config_parse_int( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -251,6 +252,7 @@ int config_parse_uint64( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -276,6 +278,7 @@ int config_parse_unsigned( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -301,6 +304,7 @@ int config_parse_size( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -328,6 +332,7 @@ int config_parse_bool( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -354,6 +359,7 @@ int config_parse_string( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -383,6 +389,7 @@ int config_parse_path( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -416,6 +423,7 @@ int config_parse_strv( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -468,6 +476,7 @@ int config_parse_path_strv( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { diff --git a/src/conf-parser.h b/src/conf-parser.h index 019b7afd1..3432695db 100644 --- a/src/conf-parser.h +++ b/src/conf-parser.h @@ -28,12 +28,13 @@ /* An abstract parser for simple, line based, shallow configuration * files consisting of variable assignments only. */ -typedef int (*ConfigParserCallback)(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); +typedef int (*ConfigParserCallback)(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); /* Wraps info for parsing a specific configuration variable */ typedef struct ConfigItem { const char *lvalue; /* name of the variable */ ConfigParserCallback parse; /* Function that is called to parse the variable's value */ + int ltype; /* Distinguish differnt variables passed to the same callback */ void *data; /* Where to store the variable's data */ const char *section; } ConfigItem; @@ -44,15 +45,15 @@ typedef struct ConfigItem { int config_parse(const char *filename, FILE *f, const char* const *sections, const ConfigItem *t, bool relaxed, void *userdata); /* Generic parsers */ -int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); -int config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); -int config_parse_uint64(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); -int config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); -int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); -int config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); -int config_parse_path(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); -int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); -int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); +int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_uint64(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \ int function( \ @@ -60,6 +61,7 @@ int config_parse_path_strv(const char *filename, unsigned line, const char *sect unsigned line, \ const char *section, \ const char *lvalue, \ + int ltype, \ const char *rvalue, \ void *data, \ void *userdata) { \ diff --git a/src/dbus-common.c b/src/dbus-common.c index e352b8cf9..dcce10e55 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -104,7 +104,7 @@ int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private, DBusError * /* If we are root, then let's not go via the bus */ if (geteuid() == 0 && t == DBUS_BUS_SYSTEM) { - if (!(bus = dbus_connection_open_private("unix:path=/dev/.run/systemd/private", error))) { + if (!(bus = dbus_connection_open_private("unix:path=/run/systemd/private", error))) { #ifndef LEGACY dbus_error_free(error); diff --git a/src/dbus.c b/src/dbus.c index 7afb0fb5e..31b1ce6ee 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -955,8 +955,8 @@ static int bus_init_private(Manager *m) { if (getpid() != 1) return 0; - unlink("/dev/.run/systemd/private"); - if (!(m->private_bus = dbus_server_listen("unix:path=/dev/.run/systemd/private", &error))) { + unlink("/run/systemd/private"); + if (!(m->private_bus = dbus_server_listen("unix:path=/run/systemd/private", &error))) { log_error("Failed to create private D-Bus server: %s", error.message); r = -EIO; goto fail; diff --git a/src/execute.h b/src/execute.h index 755dea35a..3b2b4e8ed 100644 --- a/src/execute.h +++ b/src/execute.h @@ -40,7 +40,7 @@ struct CGroupBonding; #include "util.h" /* Abstract namespace! */ -#define LOGGER_SOCKET "/dev/.run/systemd/logger" +#define LOGGER_SOCKET "/run/systemd/logger" typedef enum KillMode { KILL_CONTROL_GROUP = 0, diff --git a/src/fsck.c b/src/fsck.c index a3c83c3c2..7b809b32b 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -265,7 +265,7 @@ int main(int argc, char *argv[]) { r = EXIT_SUCCESS; if (status.si_code == CLD_EXITED && (status.si_status & 1)) - touch("/dev/.run/systemd/quotacheck"); + touch("/run/systemd/quotacheck"); finish: if (udev_device) diff --git a/src/load-fragment.c b/src/load-fragment.c index ac22b9450..343525665 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -48,6 +48,7 @@ static int config_parse_warn_compat( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -62,6 +63,7 @@ static int config_parse_deps( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -108,6 +110,7 @@ static int config_parse_names( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -154,6 +157,7 @@ static int config_parse_string_printf( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -187,6 +191,7 @@ static int config_parse_listen( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -249,6 +254,7 @@ static int config_parse_socket_bind( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -283,6 +289,7 @@ static int config_parse_nice( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -316,6 +323,7 @@ static int config_parse_oom_score_adjust( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -349,6 +357,7 @@ static int config_parse_mode( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -383,6 +392,7 @@ static int config_parse_exec( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -500,6 +510,7 @@ static int config_parse_usec( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -527,6 +538,7 @@ static int config_parse_bindtodevice( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -559,6 +571,7 @@ static int config_parse_facility( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -586,6 +599,7 @@ static int config_parse_level( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -612,6 +626,7 @@ static int config_parse_io_class( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -640,6 +655,7 @@ static int config_parse_io_priority( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -668,6 +684,7 @@ static int config_parse_cpu_sched_policy( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -697,6 +714,7 @@ static int config_parse_cpu_sched_prio( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -726,6 +744,7 @@ static int config_parse_cpu_affinity( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -771,6 +790,7 @@ static int config_parse_capabilities( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -803,6 +823,7 @@ static int config_parse_secure_bits( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -844,6 +865,7 @@ static int config_parse_bounding_set( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -902,6 +924,7 @@ static int config_parse_timer_slack_nsec( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -929,6 +952,7 @@ static int config_parse_limit( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -959,6 +983,7 @@ static int config_parse_cgroup( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -993,6 +1018,7 @@ static int config_parse_sysv_priority( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1020,6 +1046,7 @@ static int config_parse_fsck_passno( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1048,6 +1075,7 @@ static int config_parse_kill_signal( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1074,6 +1102,7 @@ static int config_parse_mount_flags( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1111,6 +1140,7 @@ static int config_parse_timer( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1151,6 +1181,7 @@ static int config_parse_timer_unit( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1185,6 +1216,7 @@ static int config_parse_path_spec( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1231,6 +1263,7 @@ static int config_parse_path_unit( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1265,6 +1298,7 @@ static int config_parse_socket_service( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1299,6 +1333,7 @@ static int config_parse_service_sockets( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1353,6 +1388,7 @@ static int config_parse_env_file( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1383,6 +1419,7 @@ static int config_parse_ip_tos( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1409,10 +1446,12 @@ static int config_parse_condition_path( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { + ConditionType cond = ltype; Unit *u = data; bool trigger, negate; Condition *c; @@ -1433,8 +1472,7 @@ static int config_parse_condition_path( return 0; } - if (!(c = condition_new(streq(lvalue, "ConditionPathExists") ? CONDITION_PATH_EXISTS : CONDITION_DIRECTORY_NOT_EMPTY, - rvalue, trigger, negate))) + if (!(c = condition_new(cond, rvalue, trigger, negate))) return -ENOMEM; LIST_PREPEND(Condition, conditions, u->meta.conditions, c); @@ -1446,6 +1484,7 @@ static int config_parse_condition_kernel( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1477,6 +1516,7 @@ static int config_parse_condition_virt( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1508,6 +1548,7 @@ static int config_parse_condition_null( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -1763,178 +1804,179 @@ static int load_from_path(Unit *u, const char *path) { }; #define EXEC_CONTEXT_CONFIG_ITEMS(context, section) \ - { "WorkingDirectory", config_parse_path, &(context).working_directory, section }, \ - { "RootDirectory", config_parse_path, &(context).root_directory, section }, \ - { "User", config_parse_string_printf, &(context).user, section }, \ - { "Group", config_parse_string_printf, &(context).group, section }, \ - { "SupplementaryGroups", config_parse_strv, &(context).supplementary_groups, section }, \ - { "Nice", config_parse_nice, &(context), section }, \ - { "OOMScoreAdjust", config_parse_oom_score_adjust,&(context), section }, \ - { "IOSchedulingClass", config_parse_io_class, &(context), section }, \ - { "IOSchedulingPriority", config_parse_io_priority, &(context), section }, \ - { "CPUSchedulingPolicy", config_parse_cpu_sched_policy,&(context), section }, \ - { "CPUSchedulingPriority", config_parse_cpu_sched_prio, &(context), section }, \ - { "CPUSchedulingResetOnFork", config_parse_bool, &(context).cpu_sched_reset_on_fork, section }, \ - { "CPUAffinity", config_parse_cpu_affinity, &(context), section }, \ - { "UMask", config_parse_mode, &(context).umask, section }, \ - { "Environment", config_parse_strv, &(context).environment, section }, \ - { "EnvironmentFile", config_parse_env_file, &(context).environment_files, section }, \ - { "StandardInput", config_parse_input, &(context).std_input, section }, \ - { "StandardOutput", config_parse_output, &(context).std_output, section }, \ - { "StandardError", config_parse_output, &(context).std_error, section }, \ - { "TTYPath", config_parse_path, &(context).tty_path, section }, \ - { "SyslogIdentifier", config_parse_string_printf, &(context).syslog_identifier, section }, \ - { "SyslogFacility", config_parse_facility, &(context).syslog_priority, section }, \ - { "SyslogLevel", config_parse_level, &(context).syslog_priority, section }, \ - { "SyslogLevelPrefix", config_parse_bool, &(context).syslog_level_prefix, section }, \ - { "Capabilities", config_parse_capabilities, &(context), section }, \ - { "SecureBits", config_parse_secure_bits, &(context), section }, \ - { "CapabilityBoundingSet", config_parse_bounding_set, &(context), section }, \ - { "TimerSlackNSec", config_parse_timer_slack_nsec,&(context), section }, \ - { "LimitCPU", config_parse_limit, &(context).rlimit[RLIMIT_CPU], section }, \ - { "LimitFSIZE", config_parse_limit, &(context).rlimit[RLIMIT_FSIZE], section }, \ - { "LimitDATA", config_parse_limit, &(context).rlimit[RLIMIT_DATA], section }, \ - { "LimitSTACK", config_parse_limit, &(context).rlimit[RLIMIT_STACK], section }, \ - { "LimitCORE", config_parse_limit, &(context).rlimit[RLIMIT_CORE], section }, \ - { "LimitRSS", config_parse_limit, &(context).rlimit[RLIMIT_RSS], section }, \ - { "LimitNOFILE", config_parse_limit, &(context).rlimit[RLIMIT_NOFILE], section }, \ - { "LimitAS", config_parse_limit, &(context).rlimit[RLIMIT_AS], section }, \ - { "LimitNPROC", config_parse_limit, &(context).rlimit[RLIMIT_NPROC], section }, \ - { "LimitMEMLOCK", config_parse_limit, &(context).rlimit[RLIMIT_MEMLOCK], section }, \ - { "LimitLOCKS", config_parse_limit, &(context).rlimit[RLIMIT_LOCKS], section }, \ - { "LimitSIGPENDING", config_parse_limit, &(context).rlimit[RLIMIT_SIGPENDING], section }, \ - { "LimitMSGQUEUE", config_parse_limit, &(context).rlimit[RLIMIT_MSGQUEUE], section }, \ - { "LimitNICE", config_parse_limit, &(context).rlimit[RLIMIT_NICE], section }, \ - { "LimitRTPRIO", config_parse_limit, &(context).rlimit[RLIMIT_RTPRIO], section }, \ - { "LimitRTTIME", config_parse_limit, &(context).rlimit[RLIMIT_RTTIME], section }, \ - { "ControlGroup", config_parse_cgroup, u, section }, \ - { "ReadWriteDirectories", config_parse_path_strv, &(context).read_write_dirs, section }, \ - { "ReadOnlyDirectories", config_parse_path_strv, &(context).read_only_dirs, section }, \ - { "InaccessibleDirectories",config_parse_path_strv, &(context).inaccessible_dirs, section }, \ - { "PrivateTmp", config_parse_bool, &(context).private_tmp, section }, \ - { "MountFlags", config_parse_mount_flags, &(context), section }, \ - { "TCPWrapName", config_parse_string_printf, &(context).tcpwrap_name, section }, \ - { "PAMName", config_parse_string_printf, &(context).pam_name, section }, \ - { "KillMode", config_parse_kill_mode, &(context).kill_mode, section }, \ - { "KillSignal", config_parse_kill_signal, &(context).kill_signal, section }, \ - { "SendSIGKILL", config_parse_bool, &(context).send_sigkill, section }, \ - { "UtmpIdentifier", config_parse_string_printf, &(context).utmp_id, section } + { "WorkingDirectory", config_parse_path, 0, &(context).working_directory, section }, \ + { "RootDirectory", config_parse_path, 0, &(context).root_directory, section }, \ + { "User", config_parse_string_printf, 0, &(context).user, section }, \ + { "Group", config_parse_string_printf, 0, &(context).group, section }, \ + { "SupplementaryGroups", config_parse_strv, 0, &(context).supplementary_groups, section }, \ + { "Nice", config_parse_nice, 0, &(context), section }, \ + { "OOMScoreAdjust", config_parse_oom_score_adjust,0, &(context), section }, \ + { "IOSchedulingClass", config_parse_io_class, 0, &(context), section }, \ + { "IOSchedulingPriority", config_parse_io_priority, 0, &(context), section }, \ + { "CPUSchedulingPolicy", config_parse_cpu_sched_policy,0, &(context), section }, \ + { "CPUSchedulingPriority", config_parse_cpu_sched_prio, 0, &(context), section }, \ + { "CPUSchedulingResetOnFork", config_parse_bool, 0, &(context).cpu_sched_reset_on_fork, section }, \ + { "CPUAffinity", config_parse_cpu_affinity, 0, &(context), section }, \ + { "UMask", config_parse_mode, 0, &(context).umask, section }, \ + { "Environment", config_parse_strv, 0, &(context).environment, section }, \ + { "EnvironmentFile", config_parse_env_file, 0, &(context).environment_files, section }, \ + { "StandardInput", config_parse_input, 0, &(context).std_input, section }, \ + { "StandardOutput", config_parse_output, 0, &(context).std_output, section }, \ + { "StandardError", config_parse_output, 0, &(context).std_error, section }, \ + { "TTYPath", config_parse_path, 0, &(context).tty_path, section }, \ + { "SyslogIdentifier", config_parse_string_printf, 0, &(context).syslog_identifier, section }, \ + { "SyslogFacility", config_parse_facility, 0, &(context).syslog_priority, section }, \ + { "SyslogLevel", config_parse_level, 0, &(context).syslog_priority, section }, \ + { "SyslogLevelPrefix", config_parse_bool, 0, &(context).syslog_level_prefix, section }, \ + { "Capabilities", config_parse_capabilities, 0, &(context), section }, \ + { "SecureBits", config_parse_secure_bits, 0, &(context), section }, \ + { "CapabilityBoundingSet", config_parse_bounding_set, 0, &(context), section }, \ + { "TimerSlackNSec", config_parse_timer_slack_nsec,0, &(context), section }, \ + { "LimitCPU", config_parse_limit, 0, &(context).rlimit[RLIMIT_CPU], section }, \ + { "LimitFSIZE", config_parse_limit, 0, &(context).rlimit[RLIMIT_FSIZE], section }, \ + { "LimitDATA", config_parse_limit, 0, &(context).rlimit[RLIMIT_DATA], section }, \ + { "LimitSTACK", config_parse_limit, 0, &(context).rlimit[RLIMIT_STACK], section }, \ + { "LimitCORE", config_parse_limit, 0, &(context).rlimit[RLIMIT_CORE], section }, \ + { "LimitRSS", config_parse_limit, 0, &(context).rlimit[RLIMIT_RSS], section }, \ + { "LimitNOFILE", config_parse_limit, 0, &(context).rlimit[RLIMIT_NOFILE], section }, \ + { "LimitAS", config_parse_limit, 0, &(context).rlimit[RLIMIT_AS], section }, \ + { "LimitNPROC", config_parse_limit, 0, &(context).rlimit[RLIMIT_NPROC], section }, \ + { "LimitMEMLOCK", config_parse_limit, 0, &(context).rlimit[RLIMIT_MEMLOCK], section }, \ + { "LimitLOCKS", config_parse_limit, 0, &(context).rlimit[RLIMIT_LOCKS], section }, \ + { "LimitSIGPENDING", config_parse_limit, 0, &(context).rlimit[RLIMIT_SIGPENDING], section }, \ + { "LimitMSGQUEUE", config_parse_limit, 0, &(context).rlimit[RLIMIT_MSGQUEUE], section }, \ + { "LimitNICE", config_parse_limit, 0, &(context).rlimit[RLIMIT_NICE], section }, \ + { "LimitRTPRIO", config_parse_limit, 0, &(context).rlimit[RLIMIT_RTPRIO], section }, \ + { "LimitRTTIME", config_parse_limit, 0, &(context).rlimit[RLIMIT_RTTIME], section }, \ + { "ControlGroup", config_parse_cgroup, 0, u, section }, \ + { "ReadWriteDirectories", config_parse_path_strv, 0, &(context).read_write_dirs, section }, \ + { "ReadOnlyDirectories", config_parse_path_strv, 0, &(context).read_only_dirs, section }, \ + { "InaccessibleDirectories",config_parse_path_strv, 0, &(context).inaccessible_dirs, section }, \ + { "PrivateTmp", config_parse_bool, 0, &(context).private_tmp, section }, \ + { "MountFlags", config_parse_mount_flags, 0, &(context), section }, \ + { "TCPWrapName", config_parse_string_printf, 0, &(context).tcpwrap_name, section }, \ + { "PAMName", config_parse_string_printf, 0, &(context).pam_name, section }, \ + { "KillMode", config_parse_kill_mode, 0, &(context).kill_mode, section }, \ + { "KillSignal", config_parse_kill_signal, 0, &(context).kill_signal, section }, \ + { "SendSIGKILL", config_parse_bool, 0, &(context).send_sigkill, section }, \ + { "UtmpIdentifier", config_parse_string_printf, 0, &(context).utmp_id, section } const ConfigItem items[] = { - { "Names", config_parse_names, u, "Unit" }, - { "Description", config_parse_string_printf, &u->meta.description, "Unit" }, - { "Requires", config_parse_deps, UINT_TO_PTR(UNIT_REQUIRES), "Unit" }, - { "RequiresOverridable", config_parse_deps, UINT_TO_PTR(UNIT_REQUIRES_OVERRIDABLE), "Unit" }, - { "Requisite", config_parse_deps, UINT_TO_PTR(UNIT_REQUISITE), "Unit" }, - { "RequisiteOverridable", config_parse_deps, UINT_TO_PTR(UNIT_REQUISITE_OVERRIDABLE), "Unit" }, - { "Wants", config_parse_deps, UINT_TO_PTR(UNIT_WANTS), "Unit" }, - { "BindTo", config_parse_deps, UINT_TO_PTR(UNIT_BIND_TO), "Unit" }, - { "Conflicts", config_parse_deps, UINT_TO_PTR(UNIT_CONFLICTS), "Unit" }, - { "Before", config_parse_deps, UINT_TO_PTR(UNIT_BEFORE), "Unit" }, - { "After", config_parse_deps, UINT_TO_PTR(UNIT_AFTER), "Unit" }, - { "OnFailure", config_parse_deps, UINT_TO_PTR(UNIT_ON_FAILURE), "Unit" }, - { "StopWhenUnneeded", config_parse_bool, &u->meta.stop_when_unneeded, "Unit" }, - { "RefuseManualStart", config_parse_bool, &u->meta.refuse_manual_start, "Unit" }, - { "RefuseManualStop", config_parse_bool, &u->meta.refuse_manual_stop, "Unit" }, - { "AllowIsolate", config_parse_bool, &u->meta.allow_isolate, "Unit" }, - { "DefaultDependencies", config_parse_bool, &u->meta.default_dependencies, "Unit" }, - { "JobTimeoutSec", config_parse_usec, &u->meta.job_timeout, "Unit" }, - { "ConditionPathExists", config_parse_condition_path, u, "Unit" }, - { "ConditionDirectoryNotEmpty", config_parse_condition_path, u, "Unit" }, - { "ConditionKernelCommandLine", config_parse_condition_kernel, u, "Unit" }, - { "ConditionVirtualization",config_parse_condition_virt, u, "Unit" }, - { "ConditionNull", config_parse_condition_null, u, "Unit" }, + { "Names", config_parse_names, 0, u, "Unit" }, + { "Description", config_parse_string_printf, 0, &u->meta.description, "Unit" }, + { "Requires", config_parse_deps, 0, UINT_TO_PTR(UNIT_REQUIRES), "Unit" }, + { "RequiresOverridable", config_parse_deps, 0, UINT_TO_PTR(UNIT_REQUIRES_OVERRIDABLE), "Unit" }, + { "Requisite", config_parse_deps, 0, UINT_TO_PTR(UNIT_REQUISITE), "Unit" }, + { "RequisiteOverridable", config_parse_deps, 0, UINT_TO_PTR(UNIT_REQUISITE_OVERRIDABLE), "Unit" }, + { "Wants", config_parse_deps, 0, UINT_TO_PTR(UNIT_WANTS), "Unit" }, + { "BindTo", config_parse_deps, 0, UINT_TO_PTR(UNIT_BIND_TO), "Unit" }, + { "Conflicts", config_parse_deps, 0, UINT_TO_PTR(UNIT_CONFLICTS), "Unit" }, + { "Before", config_parse_deps, 0, UINT_TO_PTR(UNIT_BEFORE), "Unit" }, + { "After", config_parse_deps, 0, UINT_TO_PTR(UNIT_AFTER), "Unit" }, + { "OnFailure", config_parse_deps, 0, UINT_TO_PTR(UNIT_ON_FAILURE), "Unit" }, + { "StopWhenUnneeded", config_parse_bool, 0, &u->meta.stop_when_unneeded, "Unit" }, + { "RefuseManualStart", config_parse_bool, 0, &u->meta.refuse_manual_start, "Unit" }, + { "RefuseManualStop", config_parse_bool, 0, &u->meta.refuse_manual_stop, "Unit" }, + { "AllowIsolate", config_parse_bool, 0, &u->meta.allow_isolate, "Unit" }, + { "DefaultDependencies", config_parse_bool, 0, &u->meta.default_dependencies, "Unit" }, + { "JobTimeoutSec", config_parse_usec, 0, &u->meta.job_timeout, "Unit" }, + { "ConditionPathExists", config_parse_condition_path, CONDITION_PATH_EXISTS, u, "Unit" }, + { "ConditionPathIsDirectory", config_parse_condition_path, CONDITION_PATH_IS_DIRECTORY, u, "Unit" }, + { "ConditionDirectoryNotEmpty", config_parse_condition_path, CONDITION_DIRECTORY_NOT_EMPTY, u, "Unit" }, + { "ConditionKernelCommandLine", config_parse_condition_kernel, 0, u, "Unit" }, + { "ConditionVirtualization",config_parse_condition_virt, 0, u, "Unit" }, + { "ConditionNull", config_parse_condition_null, 0, u, "Unit" }, - { "PIDFile", config_parse_path, &u->service.pid_file, "Service" }, - { "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" }, - { "ExecStart", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START, "Service" }, - { "ExecStartPost", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_POST, "Service" }, - { "ExecReload", config_parse_exec, u->service.exec_command+SERVICE_EXEC_RELOAD, "Service" }, - { "ExecStop", config_parse_exec, u->service.exec_command+SERVICE_EXEC_STOP, "Service" }, - { "ExecStopPost", config_parse_exec, u->service.exec_command+SERVICE_EXEC_STOP_POST, "Service" }, - { "RestartSec", config_parse_usec, &u->service.restart_usec, "Service" }, - { "TimeoutSec", config_parse_usec, &u->service.timeout_usec, "Service" }, - { "Type", config_parse_service_type, &u->service.type, "Service" }, - { "Restart", config_parse_service_restart, &u->service.restart, "Service" }, - { "PermissionsStartOnly", config_parse_bool, &u->service.permissions_start_only, "Service" }, - { "RootDirectoryStartOnly", config_parse_bool, &u->service.root_directory_start_only, "Service" }, - { "RemainAfterExit", config_parse_bool, &u->service.remain_after_exit, "Service" }, - { "GuessMainPID", config_parse_bool, &u->service.guess_main_pid, "Service" }, + { "PIDFile", config_parse_path, 0, &u->service.pid_file, "Service" }, + { "ExecStartPre", config_parse_exec, 0, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" }, + { "ExecStart", config_parse_exec, 0, u->service.exec_command+SERVICE_EXEC_START, "Service" }, + { "ExecStartPost", config_parse_exec, 0, u->service.exec_command+SERVICE_EXEC_START_POST, "Service" }, + { "ExecReload", config_parse_exec, 0, u->service.exec_command+SERVICE_EXEC_RELOAD, "Service" }, + { "ExecStop", config_parse_exec, 0, u->service.exec_command+SERVICE_EXEC_STOP, "Service" }, + { "ExecStopPost", config_parse_exec, 0, u->service.exec_command+SERVICE_EXEC_STOP_POST, "Service" }, + { "RestartSec", config_parse_usec, 0, &u->service.restart_usec, "Service" }, + { "TimeoutSec", config_parse_usec, 0, &u->service.timeout_usec, "Service" }, + { "Type", config_parse_service_type, 0, &u->service.type, "Service" }, + { "Restart", config_parse_service_restart, 0, &u->service.restart, "Service" }, + { "PermissionsStartOnly", config_parse_bool, 0, &u->service.permissions_start_only, "Service" }, + { "RootDirectoryStartOnly", config_parse_bool, 0, &u->service.root_directory_start_only, "Service" }, + { "RemainAfterExit", config_parse_bool, 0, &u->service.remain_after_exit, "Service" }, + { "GuessMainPID", config_parse_bool, 0, &u->service.guess_main_pid, "Service" }, #ifdef HAVE_SYSV_COMPAT - { "SysVStartPriority", config_parse_sysv_priority, &u->service.sysv_start_priority, "Service" }, + { "SysVStartPriority", config_parse_sysv_priority, 0, &u->service.sysv_start_priority, "Service" }, #else - { "SysVStartPriority", config_parse_warn_compat, NULL, "Service" }, + { "SysVStartPriority", config_parse_warn_compat, 0, NULL, "Service" }, #endif - { "NonBlocking", config_parse_bool, &u->service.exec_context.non_blocking, "Service" }, - { "BusName", config_parse_string_printf, &u->service.bus_name, "Service" }, - { "NotifyAccess", config_parse_notify_access, &u->service.notify_access, "Service" }, - { "Sockets", config_parse_service_sockets, &u->service, "Service" }, - { "FsckPassNo", config_parse_fsck_passno, &u->service.fsck_passno, "Service" }, + { "NonBlocking", config_parse_bool, 0, &u->service.exec_context.non_blocking, "Service" }, + { "BusName", config_parse_string_printf, 0, &u->service.bus_name, "Service" }, + { "NotifyAccess", config_parse_notify_access, 0, &u->service.notify_access, "Service" }, + { "Sockets", config_parse_service_sockets, 0, &u->service, "Service" }, + { "FsckPassNo", config_parse_fsck_passno, 0, &u->service.fsck_passno, "Service" }, EXEC_CONTEXT_CONFIG_ITEMS(u->service.exec_context, "Service"), - { "ListenStream", config_parse_listen, &u->socket, "Socket" }, - { "ListenDatagram", config_parse_listen, &u->socket, "Socket" }, - { "ListenSequentialPacket", config_parse_listen, &u->socket, "Socket" }, - { "ListenFIFO", config_parse_listen, &u->socket, "Socket" }, - { "BindIPv6Only", config_parse_socket_bind, &u->socket, "Socket" }, - { "Backlog", config_parse_unsigned, &u->socket.backlog, "Socket" }, - { "BindToDevice", config_parse_bindtodevice, &u->socket, "Socket" }, - { "ExecStartPre", config_parse_exec, u->socket.exec_command+SOCKET_EXEC_START_PRE, "Socket" }, - { "ExecStartPost", config_parse_exec, u->socket.exec_command+SOCKET_EXEC_START_POST, "Socket" }, - { "ExecStopPre", config_parse_exec, u->socket.exec_command+SOCKET_EXEC_STOP_PRE, "Socket" }, - { "ExecStopPost", config_parse_exec, u->socket.exec_command+SOCKET_EXEC_STOP_POST, "Socket" }, - { "TimeoutSec", config_parse_usec, &u->socket.timeout_usec, "Socket" }, - { "DirectoryMode", config_parse_mode, &u->socket.directory_mode, "Socket" }, - { "SocketMode", config_parse_mode, &u->socket.socket_mode, "Socket" }, - { "Accept", config_parse_bool, &u->socket.accept, "Socket" }, - { "MaxConnections", config_parse_unsigned, &u->socket.max_connections, "Socket" }, - { "KeepAlive", config_parse_bool, &u->socket.keep_alive, "Socket" }, - { "Priority", config_parse_int, &u->socket.priority, "Socket" }, - { "ReceiveBuffer", config_parse_size, &u->socket.receive_buffer, "Socket" }, - { "SendBuffer", config_parse_size, &u->socket.send_buffer, "Socket" }, - { "IPTOS", config_parse_ip_tos, &u->socket.ip_tos, "Socket" }, - { "IPTTL", config_parse_int, &u->socket.ip_ttl, "Socket" }, - { "Mark", config_parse_int, &u->socket.mark, "Socket" }, - { "PipeSize", config_parse_size, &u->socket.pipe_size, "Socket" }, - { "FreeBind", config_parse_bool, &u->socket.free_bind, "Socket" }, - { "TCPCongestion", config_parse_string, &u->socket.tcp_congestion, "Socket" }, - { "Service", config_parse_socket_service, &u->socket, "Socket" }, + { "ListenStream", config_parse_listen, 0, &u->socket, "Socket" }, + { "ListenDatagram", config_parse_listen, 0, &u->socket, "Socket" }, + { "ListenSequentialPacket", config_parse_listen, 0, &u->socket, "Socket" }, + { "ListenFIFO", config_parse_listen, 0, &u->socket, "Socket" }, + { "BindIPv6Only", config_parse_socket_bind, 0, &u->socket, "Socket" }, + { "Backlog", config_parse_unsigned, 0, &u->socket.backlog, "Socket" }, + { "BindToDevice", config_parse_bindtodevice, 0, &u->socket, "Socket" }, + { "ExecStartPre", config_parse_exec, 0, u->socket.exec_command+SOCKET_EXEC_START_PRE, "Socket" }, + { "ExecStartPost", config_parse_exec, 0, u->socket.exec_command+SOCKET_EXEC_START_POST, "Socket" }, + { "ExecStopPre", config_parse_exec, 0, u->socket.exec_command+SOCKET_EXEC_STOP_PRE, "Socket" }, + { "ExecStopPost", config_parse_exec, 0, u->socket.exec_command+SOCKET_EXEC_STOP_POST, "Socket" }, + { "TimeoutSec", config_parse_usec, 0, &u->socket.timeout_usec, "Socket" }, + { "DirectoryMode", config_parse_mode, 0, &u->socket.directory_mode, "Socket" }, + { "SocketMode", config_parse_mode, 0, &u->socket.socket_mode, "Socket" }, + { "Accept", config_parse_bool, 0, &u->socket.accept, "Socket" }, + { "MaxConnections", config_parse_unsigned, 0, &u->socket.max_connections, "Socket" }, + { "KeepAlive", config_parse_bool, 0, &u->socket.keep_alive, "Socket" }, + { "Priority", config_parse_int, 0, &u->socket.priority, "Socket" }, + { "ReceiveBuffer", config_parse_size, 0, &u->socket.receive_buffer, "Socket" }, + { "SendBuffer", config_parse_size, 0, &u->socket.send_buffer, "Socket" }, + { "IPTOS", config_parse_ip_tos, 0, &u->socket.ip_tos, "Socket" }, + { "IPTTL", config_parse_int, 0, &u->socket.ip_ttl, "Socket" }, + { "Mark", config_parse_int, 0, &u->socket.mark, "Socket" }, + { "PipeSize", config_parse_size, 0, &u->socket.pipe_size, "Socket" }, + { "FreeBind", config_parse_bool, 0, &u->socket.free_bind, "Socket" }, + { "TCPCongestion", config_parse_string, 0, &u->socket.tcp_congestion, "Socket" }, + { "Service", config_parse_socket_service, 0, &u->socket, "Socket" }, EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"), - { "What", config_parse_string, &u->mount.parameters_fragment.what, "Mount" }, - { "Where", config_parse_path, &u->mount.where, "Mount" }, - { "Options", config_parse_string, &u->mount.parameters_fragment.options, "Mount" }, - { "Type", config_parse_string, &u->mount.parameters_fragment.fstype, "Mount" }, - { "TimeoutSec", config_parse_usec, &u->mount.timeout_usec, "Mount" }, - { "DirectoryMode", config_parse_mode, &u->mount.directory_mode, "Mount" }, + { "What", config_parse_string, 0, &u->mount.parameters_fragment.what, "Mount" }, + { "Where", config_parse_path, 0, &u->mount.where, "Mount" }, + { "Options", config_parse_string, 0, &u->mount.parameters_fragment.options, "Mount" }, + { "Type", config_parse_string, 0, &u->mount.parameters_fragment.fstype, "Mount" }, + { "TimeoutSec", config_parse_usec, 0, &u->mount.timeout_usec, "Mount" }, + { "DirectoryMode", config_parse_mode, 0, &u->mount.directory_mode, "Mount" }, EXEC_CONTEXT_CONFIG_ITEMS(u->mount.exec_context, "Mount"), - { "Where", config_parse_path, &u->automount.where, "Automount" }, - { "DirectoryMode", config_parse_mode, &u->automount.directory_mode, "Automount" }, + { "Where", config_parse_path, 0, &u->automount.where, "Automount" }, + { "DirectoryMode", config_parse_mode, 0, &u->automount.directory_mode, "Automount" }, - { "What", config_parse_path, &u->swap.parameters_fragment.what, "Swap" }, - { "Priority", config_parse_int, &u->swap.parameters_fragment.priority, "Swap" }, - { "TimeoutSec", config_parse_usec, &u->swap.timeout_usec, "Swap" }, + { "What", config_parse_path, 0, &u->swap.parameters_fragment.what, "Swap" }, + { "Priority", config_parse_int, 0, &u->swap.parameters_fragment.priority, "Swap" }, + { "TimeoutSec", config_parse_usec, 0, &u->swap.timeout_usec, "Swap" }, EXEC_CONTEXT_CONFIG_ITEMS(u->swap.exec_context, "Swap"), - { "OnActiveSec", config_parse_timer, &u->timer, "Timer" }, - { "OnBootSec", config_parse_timer, &u->timer, "Timer" }, - { "OnStartupSec", config_parse_timer, &u->timer, "Timer" }, - { "OnUnitActiveSec", config_parse_timer, &u->timer, "Timer" }, - { "OnUnitInactiveSec", config_parse_timer, &u->timer, "Timer" }, - { "Unit", config_parse_timer_unit, &u->timer, "Timer" }, + { "OnActiveSec", config_parse_timer, 0, &u->timer, "Timer" }, + { "OnBootSec", config_parse_timer, 0, &u->timer, "Timer" }, + { "OnStartupSec", config_parse_timer, 0, &u->timer, "Timer" }, + { "OnUnitActiveSec", config_parse_timer, 0, &u->timer, "Timer" }, + { "OnUnitInactiveSec", config_parse_timer, 0, &u->timer, "Timer" }, + { "Unit", config_parse_timer_unit, 0, &u->timer, "Timer" }, - { "PathExists", config_parse_path_spec, &u->path, "Path" }, - { "PathChanged", config_parse_path_spec, &u->path, "Path" }, - { "DirectoryNotEmpty", config_parse_path_spec, &u->path, "Path" }, - { "Unit", config_parse_path_unit, &u->path, "Path" }, + { "PathExists", config_parse_path_spec, 0, &u->path, "Path" }, + { "PathChanged", config_parse_path_spec, 0, &u->path, "Path" }, + { "DirectoryNotEmpty", config_parse_path_spec, 0, &u->path, "Path" }, + { "Unit", config_parse_path_unit, 0, &u->path, "Path" }, /* The [Install] section is ignored here. */ - { "Alias", NULL, NULL, "Install" }, - { "WantedBy", NULL, NULL, "Install" }, - { "Also", NULL, NULL, "Install" }, + { "Alias", NULL, 0, NULL, "Install" }, + { "WantedBy", NULL, 0, NULL, "Install" }, + { "Also", NULL, 0, NULL, "Install" }, - { NULL, NULL, NULL, NULL } + { NULL, NULL, 0, NULL, NULL } }; #undef EXEC_CONTEXT_CONFIG_ITEMS diff --git a/src/machine-id-setup.c b/src/machine-id-setup.c index 59a14249e..98e288e1b 100644 --- a/src/machine-id-setup.c +++ b/src/machine-id-setup.c @@ -142,20 +142,20 @@ int machine_id_setup(void) { fd = -1; /* Hmm, we couldn't write it? So let's write it to - * /dev/.run/systemd/machine-id as a replacement */ + * /run/systemd/machine-id as a replacement */ - mkdir_p("/dev/.run/systemd", 0755); + mkdir_p("/run/systemd", 0755); - if ((r = write_one_line_file("/dev/.run/systemd/machine-id", id)) < 0) { - log_error("Cannot write /dev/.run/systemd/machine-id: %s", strerror(-r)); + if ((r = write_one_line_file("/run/systemd/machine-id", id)) < 0) { + log_error("Cannot write /run/systemd/machine-id: %s", strerror(-r)); - unlink("/dev/.run/systemd/machine-id"); + unlink("/run/systemd/machine-id"); goto finish; } /* And now, let's mount it over */ - r = mount("/dev/.run/systemd/machine-id", "/etc/machine-id", "bind", MS_BIND|MS_RDONLY, NULL) < 0 ? -errno : 0; - unlink("/dev/.run/systemd/machine-id"); + r = mount("/run/systemd/machine-id", "/etc/machine-id", "bind", MS_BIND|MS_RDONLY, NULL) < 0 ? -errno : 0; + unlink("/run/systemd/machine-id"); if (r < 0) log_error("Failed to mount /etc/machine-id: %s", strerror(-r)); diff --git a/src/main.c b/src/main.c index 7edd6b581..b7c240040 100644 --- a/src/main.c +++ b/src/main.c @@ -494,24 +494,24 @@ static DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "F 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" }, + { "LogLevel", config_parse_level, 0, NULL, "Manager" }, + { "LogTarget", config_parse_target, 0, NULL, "Manager" }, + { "LogColor", config_parse_color, 0, NULL, "Manager" }, + { "LogLocation", config_parse_location, 0, NULL, "Manager" }, + { "DumpCore", config_parse_bool, 0, &arg_dump_core, "Manager" }, + { "CrashShell", config_parse_bool, 0, &arg_crash_shell, "Manager" }, + { "ShowStatus", config_parse_bool, 0, &arg_show_status, "Manager" }, #ifdef HAVE_SYSV_COMPAT - { "SysVConsole", config_parse_bool, &arg_sysv_console, "Manager" }, + { "SysVConsole", config_parse_bool, 0, &arg_sysv_console, "Manager" }, #endif - { "CrashChVT", config_parse_int, &arg_crash_chvt, "Manager" }, - { "CPUAffinity", config_parse_cpu_affinity, NULL, "Manager" }, - { "MountAuto", config_parse_bool, &arg_mount_auto, "Manager" }, - { "SwapAuto", config_parse_bool, &arg_swap_auto, "Manager" }, - { "DefaultControllers", config_parse_strv, &arg_default_controllers, "Manager" }, - { "DefaultStandardOutput", config_parse_output, &arg_default_std_output, "Manager" }, - { "DefaultStandardError", config_parse_output, &arg_default_std_error, "Manager" }, - { NULL, NULL, NULL, NULL } + { "CrashChVT", config_parse_int, 0, &arg_crash_chvt, "Manager" }, + { "CPUAffinity", config_parse_cpu_affinity, 0, NULL, "Manager" }, + { "MountAuto", config_parse_bool, 0, &arg_mount_auto, "Manager" }, + { "SwapAuto", config_parse_bool, 0, &arg_swap_auto, "Manager" }, + { "DefaultControllers", config_parse_strv, 0, &arg_default_controllers, "Manager" }, + { "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output, "Manager" }, + { "DefaultStandardError", config_parse_output, 0, &arg_default_std_error, "Manager" }, + { NULL, NULL, 0, NULL, NULL } }; static const char * const sections[] = { @@ -1074,7 +1074,7 @@ int main(int argc, char *argv[]) { /* If Plymouth is being run make sure we show the status, so * that there's something nice to see when people press Esc */ - if (access("/dev/.run/initramfs/plymouth", F_OK) >= 0) + if (access("/run/initramfs/plymouth", F_OK) >= 0) arg_show_status = true; if (arg_action == ACTION_HELP) { diff --git a/src/manager.c b/src/manager.c index a9aaee3d8..69d231a85 100644 --- a/src/manager.c +++ b/src/manager.c @@ -66,7 +66,7 @@ #define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC) /* Where clients shall send notification messages to */ -#define NOTIFY_SOCKET_SYSTEM "/dev/.run/systemd/notify" +#define NOTIFY_SOCKET_SYSTEM "/run/systemd/notify" #define NOTIFY_SOCKET_USER "@/org/freedesktop/systemd1/notify" static int manager_setup_notify(Manager *m) { @@ -2592,7 +2592,7 @@ int manager_open_serialization(Manager *m, FILE **_f) { assert(_f); if (m->running_as == MANAGER_SYSTEM) - asprintf(&path, "/dev/.run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid()); + asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid()); else asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid()); @@ -2895,7 +2895,7 @@ void manager_run_generators(Manager *m) { if (!m->generator_unit_path) { char *p; - char system_path[] = "/dev/.run/systemd/generator-XXXXXX", + char system_path[] = "/run/systemd/generator-XXXXXX", user_path[] = "/tmp/systemd-generator-XXXXXX"; if (!(p = mkdtemp(m->running_as == MANAGER_SYSTEM ? system_path : user_path))) { diff --git a/src/mount-setup.c b/src/mount-setup.c index d740d4f35..056e4a1c6 100644 --- a/src/mount-setup.c +++ b/src/mount-setup.c @@ -54,7 +54,7 @@ static const MountPoint mount_table[] = { { "devtmpfs", "/dev", "devtmpfs", "mode=755", MS_NOSUID, true }, { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV, true }, { "devpts", "/dev/pts", "devpts", "mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, false }, - { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, }; @@ -253,8 +253,8 @@ int mount_setup(void) { symlink_and_label(j, k); /* Create a few directories we always want around */ - mkdir("/dev/.run/systemd", 0755); - mkdir("/dev/.run/systemd/ask-password", 0755); + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/ask-password", 0755); return mount_cgroup_controllers(); } diff --git a/src/mount.c b/src/mount.c index 99867172c..cc49b1993 100644 --- a/src/mount.c +++ b/src/mount.c @@ -844,6 +844,10 @@ static void mount_enter_mounting(Mount *m) { mkdir_p(m->where, m->directory_mode); + /* create the source directory for bind-mounts if needed */ + if (m->parameters_fragment.fstype && strcmp(m->parameters_fragment.fstype, "bind") == 0) + mkdir_p(m->parameters_fragment.what, m->directory_mode); + if (m->from_fragment) r = exec_command_set( m->control_command, diff --git a/src/nspawn.c b/src/nspawn.c index aaa5d1f9d..6b0ba4e57 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -117,7 +117,7 @@ static int mount_all(const char *dest) { { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true }, { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID, true }, { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND, true }, - { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, #ifdef HAVE_SELINUX { "selinux", "/selinux", "selinuxfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false }, #endif diff --git a/src/path-lookup.c b/src/path-lookup.c index 922e722e1..fff930469 100644 --- a/src/path-lookup.c +++ b/src/path-lookup.c @@ -183,7 +183,7 @@ int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as) { if (!(p->unit_path = strv_new( /* If you modify this you also want to modify * systemdsystemunitpath= in systemd.pc.in! */ - "/dev/.run/systemd/system", + "/run/systemd/system", SYSTEM_CONFIG_UNIT_PATH, "/etc/systemd/system", "/usr/local/share/systemd/system", diff --git a/src/quotacheck.c b/src/quotacheck.c index 057d8617c..c7b20a60e 100644 --- a/src/quotacheck.c +++ b/src/quotacheck.c @@ -97,7 +97,7 @@ int main(int argc, char *argv[]) { if (arg_skip) return 0; - if (access("/dev/.run/systemd/quotacheck", F_OK) < 0) + if (access("/run/systemd/quotacheck", F_OK) < 0) return 0; } diff --git a/src/readahead-collect.c b/src/readahead-collect.c index 693729598..3c48a02fc 100644 --- a/src/readahead-collect.c +++ b/src/readahead-collect.c @@ -290,13 +290,13 @@ static int collect(const char *root) { log_debug("Collecting..."); - if (access("/dev/.run/systemd/readahead/cancel", F_OK) >= 0) { + if (access("/run/systemd/readahead/cancel", F_OK) >= 0) { log_debug("Collection canceled"); r = -ECANCELED; goto finish; } - if (access("/dev/.run/systemd/readahead/done", F_OK) >= 0) { + if (access("/run/systemd/readahead/done", F_OK) >= 0) { log_debug("Got termination request"); goto done; } diff --git a/src/readahead-common.c b/src/readahead-common.c index 990ffd4d0..fc49a3310 100644 --- a/src/readahead-common.c +++ b/src/readahead-common.c @@ -167,11 +167,11 @@ int open_inotify(void) { return -errno; } - mkdir("/dev/.run/systemd", 0755); - mkdir("/dev/.run/systemd/readahead", 0755); + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); - if (inotify_add_watch(fd, "/dev/.run/systemd/readahead", IN_CREATE) < 0) { - log_error("Failed to watch /dev/.run/systemd/readahead: %m"); + if (inotify_add_watch(fd, "/run/systemd/readahead", IN_CREATE) < 0) { + log_error("Failed to watch /run/systemd/readahead: %m"); close_nointr_nofail(fd); return -errno; } @@ -183,10 +183,10 @@ ReadaheadShared *shared_get(void) { int fd; ReadaheadShared *m = NULL; - mkdir("/dev/.run/systemd", 0755); - mkdir("/dev/.run/systemd/readahead", 0755); + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); - if ((fd = open("/dev/.run/systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) { + if ((fd = open("/run/systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) { log_error("Failed to create shared memory segment: %m"); goto finish; } diff --git a/src/readahead-replay.c b/src/readahead-replay.c index 3984c36c3..fee2171dd 100644 --- a/src/readahead-replay.c +++ b/src/readahead-replay.c @@ -192,7 +192,7 @@ static int replay(const char *root) { log_debug("Replaying..."); - if (access("/dev/.run/systemd/readahead/noreplay", F_OK) >= 0) { + if (access("/run/systemd/readahead/noreplay", F_OK) >= 0) { log_debug("Got termination request"); goto done; } diff --git a/src/sd-readahead.c b/src/sd-readahead.c index 0dfe4abab..c5cfe6710 100644 --- a/src/sd-readahead.c +++ b/src/sd-readahead.c @@ -42,8 +42,8 @@ static int touch(const char *path) { #if !defined(DISABLE_SYSTEMD) && defined(__linux__) int fd; - mkdir("/dev/.run/systemd", 0755); - mkdir("/dev/.run/systemd/readahead", 0755); + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666)) < 0) return -errno; @@ -66,11 +66,11 @@ int sd_readahead(const char *action) { return -EINVAL; if (strcmp(action, "cancel") == 0) - return touch("/dev/.run/systemd/readahead/cancel"); + return touch("/run/systemd/readahead/cancel"); else if (strcmp(action, "done") == 0) - return touch("/dev/.run/systemd/readahead/done"); + return touch("/run/systemd/readahead/done"); else if (strcmp(action, "noreplay") == 0) - return touch("/dev/.run/systemd/readahead/noreplay"); + return touch("/run/systemd/readahead/noreplay"); return -EINVAL; } diff --git a/src/systemctl.c b/src/systemctl.c index 5e34d0394..4879b29d1 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -4023,11 +4023,11 @@ finish: static int install_info_apply(const char *verb, LookupPaths *paths, InstallInfo *i, const char *config_path) { const ConfigItem items[] = { - { "Alias", config_parse_strv, &i->aliases, "Install" }, - { "WantedBy", config_parse_strv, &i->wanted_by, "Install" }, - { "Also", config_parse_also, NULL, "Install" }, + { "Alias", config_parse_strv, 0, &i->aliases, "Install" }, + { "WantedBy", config_parse_strv, 0, &i->wanted_by, "Install" }, + { "Also", config_parse_also, 0, NULL, "Install" }, - { NULL, NULL, NULL, NULL } + { NULL, NULL, 0, NULL, NULL } }; char **p; @@ -5366,7 +5366,7 @@ static int send_shutdownd(usec_t t, char mode, bool warn, const char *message) { zero(sockaddr); sockaddr.sa.sa_family = AF_UNIX; sockaddr.un.sun_path[0] = 0; - strncpy(sockaddr.un.sun_path, "/dev/.run/systemd/shutdownd", sizeof(sockaddr.un.sun_path)); + strncpy(sockaddr.un.sun_path, "/run/systemd/shutdownd", sizeof(sockaddr.un.sun_path)); zero(iovec); iovec.iov_base = (char*) &c; @@ -5374,7 +5374,7 @@ static int send_shutdownd(usec_t t, char mode, bool warn, const char *message) { zero(msghdr); msghdr.msg_name = &sockaddr; - msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + sizeof("/dev/.run/systemd/shutdownd") - 1; + msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + sizeof("/run/systemd/shutdownd") - 1; msghdr.msg_iov = &iovec; msghdr.msg_iovlen = 1; diff --git a/src/tty-ask-password-agent.c b/src/tty-ask-password-agent.c index 2c854fa8d..dcf4b332b 100644 --- a/src/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent.c @@ -251,12 +251,12 @@ static int parse_password(const char *filename, char **wall) { bool accept_cached = false; const ConfigItem items[] = { - { "Socket", config_parse_string, &socket_name, "Ask" }, - { "NotAfter", config_parse_uint64, ¬_after, "Ask" }, - { "Message", config_parse_string, &message, "Ask" }, - { "PID", config_parse_unsigned, &pid, "Ask" }, - { "AcceptCached", config_parse_bool, &accept_cached, "Ask" }, - { NULL, NULL, NULL, NULL } + { "Socket", config_parse_string, 0, &socket_name, "Ask" }, + { "NotAfter", config_parse_uint64, 0, ¬_after, "Ask" }, + { "Message", config_parse_string, 0, &message, "Ask" }, + { "PID", config_parse_unsigned, 0, &pid, "Ask" }, + { "AcceptCached", config_parse_bool, 0, &accept_cached, "Ask" }, + { NULL, NULL, 0, NULL, NULL } }; FILE *f; @@ -431,7 +431,7 @@ static int wall_tty_block(void) { if ((r = get_ctty_devnr(&devnr)) < 0) return -r; - if (asprintf(&p, "/dev/.run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0) + if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0) return -ENOMEM; mkdir_parents(p, 0700); @@ -475,7 +475,7 @@ static bool wall_tty_match(const char *path) { * advantage that the block will automatically go away if the * process dies. */ - if (asprintf(&p, "/dev/.run/systemd/ask-password-block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0) + if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0) return true; fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); @@ -494,7 +494,7 @@ static int show_passwords(void) { struct dirent *de; int r = 0; - if (!(d = opendir("/dev/.run/systemd/ask-password"))) { + if (!(d = opendir("/run/systemd/ask-password"))) { if (errno == ENOENT) return 0; @@ -519,7 +519,7 @@ static int show_passwords(void) { if (!startswith(de->d_name, "ask.")) continue; - if (!(p = strappend("/dev/.run/systemd/ask-password/", de->d_name))) { + if (!(p = strappend("/run/systemd/ask-password/", de->d_name))) { log_error("Out of memory"); r = -ENOMEM; goto finish; @@ -558,14 +558,14 @@ static int watch_passwords(void) { tty_block_fd = wall_tty_block(); - mkdir_p("/dev/.run/systemd/ask-password", 0755); + mkdir_p("/run/systemd/ask-password", 0755); if ((notify = inotify_init1(IN_CLOEXEC)) < 0) { r = -errno; goto finish; } - if (inotify_add_watch(notify, "/dev/.run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) { + if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) { r = -errno; goto finish; } diff --git a/systemd.pc.in b/systemd.pc.in index f962b58d9..6a843fbde 100644 --- a/systemd.pc.in +++ b/systemd.pc.in @@ -11,7 +11,7 @@ systemdsystemunitdir=@systemunitdir@ systemduserunitdir=@pkgdatadir@/user systemdsystemconfdir=@pkgsysconfdir@/system systemduserconfdir=@pkgsysconfdir@/user -systemdsystemunitpath=/dev/.run/systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/share/systemd/system:/lib/systemd/system:${systemdsystemunitdir} +systemdsystemunitpath=/run/systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/share/systemd/system:/lib/systemd/system:${systemdsystemunitdir} Name: systemd Description: systemd System and Service Manager diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index 880a6ed7d..2d8e52043 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -7,9 +7,10 @@ # See tmpfiles.d(5) for details -d /var/lock/subsys 0755 root root - -d /var/run/user 0755 root root 10d -F /var/run/utmp 0664 root utmp - +d /run/lock 0755 root lock - +d /run/lock/subsys 0755 root root - +d /run/user 0755 root root 10d +F /run/utmp 0664 root utmp - f /var/log/wtmp 0664 root utmp - f /var/log/btmp 0600 root utmp - diff --git a/units/fsck-root.service.in b/units/fsck-root.service.in index ae6ea924a..8f4adc48e 100644 --- a/units/fsck-root.service.in +++ b/units/fsck-root.service.in @@ -12,7 +12,7 @@ After=systemd-readahead-collect.service systemd-readahead-replay.service Before=local-fs.target shutdown.target remount-rootfs.service quotacheck.service # Dracut informs us with this flag file if the root fsck was already run -ConditionPathExists=!/dev/.run/initramfs/root-fsck +ConditionPathExists=!/run/initramfs/root-fsck [Service] Type=oneshot diff --git a/units/plymouth-start.service b/units/plymouth-start.service index 4ef2bcc02..eb336e619 100644 --- a/units/plymouth-start.service +++ b/units/plymouth-start.service @@ -13,7 +13,7 @@ After=systemd-vconsole-setup.service udev-settle.service Before=systemd-ask-password-plymouth.service # Dracut informs us with this flag file if plymouth is already running -ConditionPathExists=!/dev/.run/initramfs/plymouth +ConditionPathExists=!/run/initramfs/plymouth [Service] ExecStart=/sbin/plymouthd --mode=boot diff --git a/units/systemd-ask-password-console.path b/units/systemd-ask-password-console.path index ac76fc170..4005a2773 100644 --- a/units/systemd-ask-password-console.path +++ b/units/systemd-ask-password-console.path @@ -12,4 +12,4 @@ Conflicts=shutdown.target Before=basic.target shutdown.target [Path] -DirectoryNotEmpty=/dev/.run/systemd/ask-password +DirectoryNotEmpty=/run/systemd/ask-password diff --git a/units/systemd-ask-password-plymouth.path b/units/systemd-ask-password-plymouth.path index b339b5e26..a2aec4412 100644 --- a/units/systemd-ask-password-plymouth.path +++ b/units/systemd-ask-password-plymouth.path @@ -12,4 +12,4 @@ Conflicts=shutdown.target systemd-ask-password-console.path systemd-ask-password Before=basic.target shutdown.target [Path] -DirectoryNotEmpty=/dev/.run/systemd/ask-password +DirectoryNotEmpty=/run/systemd/ask-password diff --git a/units/systemd-ask-password-wall.path b/units/systemd-ask-password-wall.path index c277563b7..7a883d5af 100644 --- a/units/systemd-ask-password-wall.path +++ b/units/systemd-ask-password-wall.path @@ -12,4 +12,4 @@ Conflicts=shutdown.target Before=basic.target shutdown.target [Path] -DirectoryNotEmpty=/dev/.run/systemd/ask-password +DirectoryNotEmpty=/run/systemd/ask-password diff --git a/units/systemd-logger.socket b/units/systemd-logger.socket index 5cf6a9b0b..9b2d202f2 100644 --- a/units/systemd-logger.socket +++ b/units/systemd-logger.socket @@ -13,4 +13,4 @@ DefaultDependencies=no Before=sockets.target [Socket] -ListenStream=/dev/.run/systemd/logger +ListenStream=/run/systemd/logger diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket index 6faf36f0e..b30a6657c 100644 --- a/units/systemd-shutdownd.socket +++ b/units/systemd-shutdownd.socket @@ -13,4 +13,4 @@ DefaultDependencies=no Before=sockets.target [Socket] -ListenDatagram=/dev/.run/systemd/shutdownd +ListenDatagram=/run/systemd/shutdownd diff --git a/units/var-lock.mount b/units/var-lock.mount index 0ea2599b7..80e1bab26 100644 --- a/units/var-lock.mount +++ b/units/var-lock.mount @@ -8,9 +8,11 @@ [Unit] Description=Lock Directory Before=local-fs.target +# skip mounting if the directory does not exist or is a symlink +ConditionPathIsDirectory=/var/lock [Mount] -What=tmpfs +What=/run/lock Where=/var/lock -Type=tmpfs -Options=mode=775,gid=lock,nosuid,nodev,noexec +Type=bind +Options=bind diff --git a/units/var-run.mount b/units/var-run.mount index cd3889ebc..c513dfecd 100644 --- a/units/var-run.mount +++ b/units/var-run.mount @@ -8,9 +8,11 @@ [Unit] Description=Runtime Directory Before=local-fs.target +# skip mounting if the directory does not exist or is a symlink +ConditionPathIsDirectory=/var/run [Mount] -What=/dev/.run +What=/run Where=/var/run Type=bind Options=bind From 03b4471dc37e5078d55b3dfa28a6c8793e24160b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 28 Mar 2011 23:04:07 +0200 Subject: [PATCH 108/200] execute: socket isn't abstract anymore --- TODO | 6 ++++++ src/execute.h | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 0db681b76..fabc18d67 100644 --- a/TODO +++ b/TODO @@ -29,6 +29,12 @@ F15: * remove KillMode=process-group +* kernel patch wegen kmsg prio nach f15 + +* LOG_DAEMON/LOG_USER für kmsg messages schreiben + +* fix /usr taint + Features: * when key file cannot be found, read it from kbd in cryptsetup diff --git a/src/execute.h b/src/execute.h index 3b2b4e8ed..44856d11f 100644 --- a/src/execute.h +++ b/src/execute.h @@ -39,7 +39,6 @@ struct CGroupBonding; #include "list.h" #include "util.h" -/* Abstract namespace! */ #define LOGGER_SOCKET "/run/systemd/logger" typedef enum KillMode { From 3731f1eaa8f9df60db469b665246a02d5e31d92b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 28 Mar 2011 23:04:30 +0200 Subject: [PATCH 109/200] conf-parser: fix remaining parser functions according to new prototype --- src/main.c | 5 +++++ src/systemctl.c | 1 + 2 files changed, 6 insertions(+) diff --git a/src/main.c b/src/main.c index b7c240040..8d27eb426 100644 --- a/src/main.c +++ b/src/main.c @@ -373,6 +373,7 @@ static int config_parse_level( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -390,6 +391,7 @@ static int config_parse_target( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -407,6 +409,7 @@ static int config_parse_color( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -424,6 +427,7 @@ static int config_parse_location( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { @@ -441,6 +445,7 @@ static int config_parse_cpu_affinity( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { diff --git a/src/systemctl.c b/src/systemctl.c index 4879b29d1..599894ef2 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -3609,6 +3609,7 @@ static int config_parse_also( unsigned line, const char *section, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata) { From d167623084f20d6286c8385de15c8ca0e2fc551d Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 27 Mar 2011 23:52:11 +0200 Subject: [PATCH 110/200] crypto: to show stars or not to show them On Friday 2011-03-18 01:41, Lennart Poettering wrote: >On Fri, 18.03.11 00:18, Jan Engelhardt (jengelh@medozas.de) wrote: > >> Meanwhile, I have two new suggestions. > >I have one too (or actually Kay came up with it), and I think you are >going to like it: > >Start with showing input feedback as we currently do. If the user then >presses TAB the stars disappear, and instead we show "(no echo)" or >so. Then, the user can proceed with typing his password without >asterisks. >[...] Incorporating Graham's suggestion to use BKSP instead: The following changes since commit 65c9e467528daa438167853cc91d37bfcb875836: tainted: don't check if /usr is a mount point, only if it's not already mounted at startup (2011-03-24 22:32:21 +0100) are available in the git repository at: git://dev.medozas.de/systemd master Jan Engelhardt (1): ask-password: provide a way to activate a silent prompt src/ask-password-api.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) --- src/ask-password-api.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ask-password-api.c b/src/ask-password-api.c index 5d17d4cd5..022f1cae8 100644 --- a/src/ask-password-api.c +++ b/src/ask-password-api.c @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with systemd; If not, see . ***/ - +#include #include #include #include @@ -48,6 +48,7 @@ int ask_password_tty( int r, ttyfd = -1, notify = -1; struct pollfd pollfd[2]; bool reset_tty = false; + bool silent_mode = false; enum { POLL_TTY, POLL_INOTIFY @@ -156,7 +157,6 @@ int ask_password_tty( if (c == '\n') break; else if (c == 21) { - while (p > 0) { p--; @@ -165,7 +165,10 @@ int ask_password_tty( } } else if (c == '\b' || c == 127) { - if (p > 0) { + if (p == 0 && !silent_mode) { + silent_mode = true; + loop_write(ttyfd, "(no echo) ", 10, false); + } else if (p > 0) { p--; if (ttyfd >= 0) @@ -174,7 +177,7 @@ int ask_password_tty( } else { passphrase[p++] = c; - if (ttyfd >= 0) + if (!silent_mode && ttyfd >= 0) loop_write(ttyfd, "*", 1, false); } } From 58fc840b8325395d24ab70e84cb69880c6daa9ee Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 28 Mar 2011 23:27:04 +0200 Subject: [PATCH 111/200] ask-password: use TAB instead of backspace to disable asterisk password echo --- src/ask-password-api.c | 46 +++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/ask-password-api.c b/src/ask-password-api.c index 022f1cae8..cb0559065 100644 --- a/src/ask-password-api.c +++ b/src/ask-password-api.c @@ -36,6 +36,18 @@ #include "ask-password-api.h" +static void backspace_chars(int ttyfd, size_t p) { + + if (ttyfd < 0) + return; + + while (p > 0) { + p--; + + loop_write(ttyfd, "\b \b", 3, false); + } +} + int ask_password_tty( const char *message, usec_t until, @@ -156,24 +168,30 @@ int ask_password_tty( if (c == '\n') break; - else if (c == 21) { - while (p > 0) { - p--; + else if (c == 21) { /* C-u */ - if (ttyfd >= 0) - loop_write(ttyfd, "\b \b", 3, false); - } + if (!silent_mode) + backspace_chars(ttyfd, p); + p = 0; } else if (c == '\b' || c == 127) { - if (p == 0 && !silent_mode) { - silent_mode = true; - loop_write(ttyfd, "(no echo) ", 10, false); - } else if (p > 0) { - p--; - if (ttyfd >= 0) - loop_write(ttyfd, "\b \b", 3, false); - } + if (p > 0) { + + if (!silent_mode) + backspace_chars(ttyfd, 1); + + p--; + } else if (ttyfd >= 0) + loop_write(ttyfd, "\a", 1, false); + + } else if (c == '\t' && !silent_mode) { + + backspace_chars(ttyfd, p); + silent_mode = true; + + if (ttyfd >= 0) + loop_write(ttyfd, "(no echo) ", 10, false); } else { passphrase[p++] = c; From 6edef9c587b374a81f4ecc23359bb958857d3def Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 21 Mar 2011 17:16:50 +0100 Subject: [PATCH 112/200] udev: expose some more tty's for various embedded hardware --- src/99-systemd.rules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/99-systemd.rules b/src/99-systemd.rules index 4fba6d4d0..08ee59f17 100644 --- a/src/99-systemd.rules +++ b/src/99-systemd.rules @@ -11,6 +11,9 @@ SUBSYSTEM=="tty", KERNEL=="tty[0-9]|tty1[0-2]", TAG+="systemd" SUBSYSTEM=="tty", KERNEL=="ttyS*", TAG+="systemd" SUBSYSTEM=="tty", KERNEL=="hvc*", TAG+="systemd" SUBSYSTEM=="tty", KERNEL=="ttyUSB*", TAG+="systemd" +SUBSYSTEM=="tty", KERNEL=="ttyAM*", TAG+="systemd" +SUBSYSTEM=="tty", KERNEL=="ttymxc*", TAG+="systemd" +SUBSYSTEM=="tty", KERNEL=="ttyPSC*", TAG+="systemd" SUBSYSTEM=="block", KERNEL!="ram*|loop*", TAG+="systemd" SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0" From 2d87855ae873aa3a4816c8e3a37e5ec06cc65c5e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 28 Mar 2011 23:39:18 +0200 Subject: [PATCH 113/200] man: fix references to systemd.unit= on the kernel cmdline https://bugs.freedesktop.org/show_bug.cgi?id=35720 --- man/systemd.special.xml.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/systemd.special.xml.in b/man/systemd.special.xml.in index df62e9c4c..804504a83 100644 --- a/man/systemd.special.xml.in +++ b/man/systemd.special.xml.in @@ -156,7 +156,7 @@ The default unit systemd starts at bootup can be overriden with the - systemd.default= + systemd.unit= kernel command line option. @@ -189,7 +189,7 @@ console. This unit is supposed to be used with the kernel command line option - systemd.default= + systemd.unit= and has otherwise little use. From 6f4ed5203aca6d792f056b6dad1ea4bfe4f25396 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 29 Mar 2011 00:15:14 +0200 Subject: [PATCH 114/200] tmpfiles fix /run/lock permissions kay: just wondering: d /run/lock 0755 root lock - shouldn't that rather be 0775? otherwise it doesn't make sense --- tmpfiles.d/systemd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index 2d8e52043..e77cf7d20 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -7,7 +7,7 @@ # See tmpfiles.d(5) for details -d /run/lock 0755 root lock - +d /run/lock 0775 root lock - d /run/lock/subsys 0755 root root - d /run/user 0755 root root 10d F /run/utmp 0664 root utmp - From 1f7f38f6d49eb60e412e1dc79dda3c1766970aa0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 29 Mar 2011 01:19:39 +0200 Subject: [PATCH 115/200] udev: systemd-tag all ttys --- src/99-systemd.rules | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/99-systemd.rules b/src/99-systemd.rules index 08ee59f17..3761058c4 100644 --- a/src/99-systemd.rules +++ b/src/99-systemd.rules @@ -8,12 +8,7 @@ ACTION!="add|change", GOTO="systemd_end" SUBSYSTEM=="tty", KERNEL=="tty[0-9]|tty1[0-2]", TAG+="systemd" -SUBSYSTEM=="tty", KERNEL=="ttyS*", TAG+="systemd" -SUBSYSTEM=="tty", KERNEL=="hvc*", TAG+="systemd" -SUBSYSTEM=="tty", KERNEL=="ttyUSB*", TAG+="systemd" -SUBSYSTEM=="tty", KERNEL=="ttyAM*", TAG+="systemd" -SUBSYSTEM=="tty", KERNEL=="ttymxc*", TAG+="systemd" -SUBSYSTEM=="tty", KERNEL=="ttyPSC*", TAG+="systemd" +SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*", TAG+="systemd" SUBSYSTEM=="block", KERNEL!="ram*|loop*", TAG+="systemd" SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0" From c20deda415c724482f952ac385610ef28d82e23d Mon Sep 17 00:00:00 2001 From: William Jon McCann Date: Sun, 27 Mar 2011 00:18:16 -0400 Subject: [PATCH 116/200] plymouth: Remove the calls to plymouth message * messages aren't translated * console text is ugly * they are jargonny * they really aren't needed https://bugs.freedesktop.org/show_bug.cgi?id=35711 --- units/plymouth-halt.service | 1 - units/plymouth-kexec.service | 1 - units/plymouth-poweroff.service | 1 - units/plymouth-reboot.service | 1 - 4 files changed, 4 deletions(-) diff --git a/units/plymouth-halt.service b/units/plymouth-halt.service index fa1a20a46..962d829ff 100644 --- a/units/plymouth-halt.service +++ b/units/plymouth-halt.service @@ -14,5 +14,4 @@ DefaultDependencies=no [Service] ExecStart=/sbin/plymouthd --mode=shutdown ExecStartPost=-/bin/plymouth --show-splash -ExecStartPost=-/bin/plymouth message '--text=Halting...' Type=forking diff --git a/units/plymouth-kexec.service b/units/plymouth-kexec.service index 61c6376a7..0d7450fee 100644 --- a/units/plymouth-kexec.service +++ b/units/plymouth-kexec.service @@ -14,5 +14,4 @@ DefaultDependencies=no [Service] ExecStart=/sbin/plymouthd --mode=shutdown ExecStartPost=-/bin/plymouth --show-splash -ExecStartPost=-/bin/plymouth message '--text=Rebooting with kexec...' Type=forking diff --git a/units/plymouth-poweroff.service b/units/plymouth-poweroff.service index c1eebb5ac..d4979df1e 100644 --- a/units/plymouth-poweroff.service +++ b/units/plymouth-poweroff.service @@ -14,5 +14,4 @@ DefaultDependencies=no [Service] ExecStart=/sbin/plymouthd --mode=shutdown ExecStartPost=-/bin/plymouth --show-splash -ExecStartPost=-/bin/plymouth message '--text=Powering Off...' Type=forking diff --git a/units/plymouth-reboot.service b/units/plymouth-reboot.service index 974db31d6..7304a5fba 100644 --- a/units/plymouth-reboot.service +++ b/units/plymouth-reboot.service @@ -14,5 +14,4 @@ DefaultDependencies=no [Service] ExecStart=/sbin/plymouthd --mode=shutdown ExecStartPost=-/bin/plymouth --show-splash -ExecStartPost=-/bin/plymouth message '--text=Rebooting...' Type=forking From 08a67ac43df4819e1820ca4e3e3f9ed9b60dce22 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 01:38:06 +0200 Subject: [PATCH 117/200] locale: fix LC_MESSAGES variable name https://bugs.freedesktop.org/show_bug.cgi?id=35534 --- src/locale-setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale-setup.c b/src/locale-setup.c index 055c1fa3f..f6fd97ebb 100644 --- a/src/locale-setup.c +++ b/src/locale-setup.c @@ -54,7 +54,7 @@ static const char * const variable_names[_VARIABLE_MAX] = { [VARIABLE_LC_TIME] = "LC_TIME", [VARIABLE_LC_COLLATE] = "LC_COLLATE", [VARIABLE_LC_MONETARY] = "LC_MONETARY", - [VARIABLE_LC_MESSAGES] = "LC_MESSAGE", + [VARIABLE_LC_MESSAGES] = "LC_MESSAGES", [VARIABLE_LC_PAPER] = "LC_PAPER", [VARIABLE_LC_NAME] = "LC_NAME", [VARIABLE_LC_ADDRESS] = "LC_ADDRESS", From e30b45bb846f0071292f1ffa4a6599e1072d992f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 29 Mar 2011 01:41:50 +0200 Subject: [PATCH 118/200] udev: tty - re-add accidentially removed hvc* match --- src/99-systemd.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/99-systemd.rules b/src/99-systemd.rules index 3761058c4..186ef45f4 100644 --- a/src/99-systemd.rules +++ b/src/99-systemd.rules @@ -8,7 +8,7 @@ ACTION!="add|change", GOTO="systemd_end" SUBSYSTEM=="tty", KERNEL=="tty[0-9]|tty1[0-2]", TAG+="systemd" -SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*", TAG+="systemd" +SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*", TAG+="systemd" SUBSYSTEM=="block", KERNEL!="ram*|loop*", TAG+="systemd" SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0" From 18a5d7fffbcaea5ebd721df5f4938e8a347a2d3b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 02:20:05 +0200 Subject: [PATCH 119/200] build-sys: bump version --- TODO | 2 ++ configure.ac | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index fabc18d67..eeb6c0728 100644 --- a/TODO +++ b/TODO @@ -35,6 +35,8 @@ F15: * fix /usr taint +* disable /dev/console status messages after plymouth went down + Features: * when key file cannot be found, read it from kbd in cryptsetup diff --git a/configure.ac b/configure.ac index e6daf0354..73764712f 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.63) -AC_INIT([systemd],[20],[systemd-devel@lists.freedesktop.org]) +AC_INIT([systemd],[21],[systemd-devel@lists.freedesktop.org]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) From 1ead1cad4b63a5dc586ae5a630d3f2857d3a86a2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 12:11:14 +0200 Subject: [PATCH 120/200] man: really fix all LC_MESSAGE to LC_MESSAGES https://bugs.freedesktop.org/show_bug.cgi?id=35534 --- man/locale.conf.xml | 2 +- units/getty@.service.m4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/locale.conf.xml b/man/locale.conf.xml index d36e7bda6..bb7e1130e 100644 --- a/man/locale.conf.xml +++ b/man/locale.conf.xml @@ -128,7 +128,7 @@ /etc/locale.conf: LANG=de_DE.UTF-8 -LC_MESSAGE=C +LC_MESSAGES=C diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index 8e1f250ad..1a8a6a0e9 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -40,7 +40,7 @@ KillMode=process-group # Unset locale for the console getty since the console has problems # displaying some internationalized messages. -Environment=LANG= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGE= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= +Environment=LANG= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= # Some login implementations ignore SIGTERM, so we send SIGHUP # instead, to ensure that login terminates cleanly. From e6402d1077499d741ea747bbaaba51856d00219b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 13:11:13 +0200 Subject: [PATCH 121/200] unit: when deserializing jobs, don't pull in dependencies --- src/unit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unit.c b/src/unit.c index 6f10f51fb..68eba69c6 100644 --- a/src/unit.c +++ b/src/unit.c @@ -2231,7 +2231,7 @@ int unit_coldplug(Unit *u) { return r; if (u->meta.deserialized_job >= 0) { - if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL, NULL)) < 0) + if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_IGNORE_DEPENDENCIES, false, NULL, NULL)) < 0) return r; u->meta.deserialized_job = _JOB_TYPE_INVALID; From 441dfe092acb0f283f7712a80e144b4392b526a0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 18:32:46 +0200 Subject: [PATCH 122/200] ask-password: also accept Backspace as first keypress as silent mode switch --- src/ask-password-api.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/ask-password-api.c b/src/ask-password-api.c index cb0559065..da967ab7a 100644 --- a/src/ask-password-api.c +++ b/src/ask-password-api.c @@ -61,6 +61,7 @@ int ask_password_tty( struct pollfd pollfd[2]; bool reset_tty = false; bool silent_mode = false; + bool dirty = false; enum { POLL_TTY, POLL_INOTIFY @@ -182,6 +183,17 @@ int ask_password_tty( backspace_chars(ttyfd, 1); p--; + } else if (!dirty && !silent_mode) { + + silent_mode = true; + + /* There are two ways to enter silent + * mode. Either by pressing backspace + * as first key (and only as first key), + * or ... */ + if (ttyfd >= 0) + loop_write(ttyfd, "(no echo) ", 10, false); + } else if (ttyfd >= 0) loop_write(ttyfd, "\a", 1, false); @@ -190,6 +202,8 @@ int ask_password_tty( backspace_chars(ttyfd, p); silent_mode = true; + /* ... or by pressing TAB at any time. */ + if (ttyfd >= 0) loop_write(ttyfd, "(no echo) ", 10, false); } else { @@ -197,6 +211,8 @@ int ask_password_tty( if (!silent_mode && ttyfd >= 0) loop_write(ttyfd, "*", 1, false); + + dirty = true; } } From 964d124efad8a2fe07141338cb4ef674f7217fe2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 18:32:46 +0200 Subject: [PATCH 123/200] systemctl: don't truncate description when using pager https://bugs.freedesktop.org/show_bug.cgi?id=35725 --- src/systemctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/systemctl.c b/src/systemctl.c index 599894ef2..1507b52f9 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -387,7 +387,7 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { if (on_tty()) { printf("%-25s %-6s %-*s %-*s %-*s", "UNIT", "LOAD", active_len, "ACTIVE", sub_len, "SUB", job_len, "JOB"); - if (columns() >= 80+12 || arg_full) + if (columns() >= 80+12 || arg_full || !arg_no_pager) printf(" %s\n", "DESCRIPTION"); else printf("\n"); @@ -440,7 +440,7 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { if (u->job_id == 0) printf(" %-*s", job_len, ""); - if (arg_full) + if (arg_full || !arg_no_pager) printf(" %s", u->description); else printf(" %.*s", columns() - a - b - 1, u->description); From 34f0fd8187e3de692a04f20958893e163ead72ca Mon Sep 17 00:00:00 2001 From: Florian Kriener Date: Tue, 29 Mar 2011 18:31:38 +0200 Subject: [PATCH 124/200] locale: full fledged /etc/default/locale support for debian debian uses /etc/default/locale for all locale setup, this patch adds full support for it to systemd. --- src/locale-setup.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/locale-setup.c b/src/locale-setup.c index f6fd97ebb..e146746df 100644 --- a/src/locale-setup.c +++ b/src/locale-setup.c @@ -139,7 +139,19 @@ int locale_setup(void) { #elif defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) if (r <= 0 && (r = parse_env_file("/etc/default/locale", NEWLINE, - "LANG", &variables[VARIABLE_LANG], + "LANG", &variables[VARIABLE_LANG], + "LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "LC_TIME", &variables[VARIABLE_LC_TIME], + "LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "LC_PAPER", &variables[VARIABLE_LC_PAPER], + "LC_NAME", &variables[VARIABLE_LC_NAME], + "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], NULL)) < 0) { if (r != -ENOENT) From 12235040ec94279ad92693dcfae0a4d9c35a6076 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 20:29:02 +0200 Subject: [PATCH 125/200] cgroup: explain when we cannot initialize the cgroup stuff --- src/cgroup.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cgroup.c b/src/cgroup.c index b75fe0bee..5864858dd 100644 --- a/src/cgroup.c +++ b/src/cgroup.c @@ -226,8 +226,10 @@ int manager_setup_cgroup(Manager *m) { assert(m); /* 1. Determine hierarchy */ - if ((r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, ¤t)) < 0) + if ((r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, ¤t)) < 0) { + log_error("Cannot determine cgroup we are running in: %s", strerror(-r)); goto finish; + } if (m->running_as == MANAGER_SYSTEM) strcpy(suffix, "/system"); @@ -246,14 +248,17 @@ int manager_setup_cgroup(Manager *m) { /* We need a new root cgroup */ m->cgroup_hierarchy = NULL; if (asprintf(&m->cgroup_hierarchy, "%s%s", streq(current, "/") ? "" : current, suffix) < 0) { + log_error("Out of memory"); r = -ENOMEM; goto finish; } } /* 2. Show data */ - if ((r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path)) < 0) + if ((r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path)) < 0) { + log_error("Cannot find cgroup mount point: %s", strerror(-r)); goto finish; + } log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path); @@ -276,6 +281,7 @@ int manager_setup_cgroup(Manager *m) { close_nointr_nofail(m->pin_cgroupfs_fd); if ((m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK)) < 0) { + log_error("Failed to open pin file: %m"); r = -errno; goto finish; } From cd25cce98f5cc930202212c3c9c13605c09698b4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 23:31:38 +0200 Subject: [PATCH 126/200] exec: drop process group kill mode since it has little use and confuses the user --- TODO | 6 ------ man/systemctl.xml | 8 +++----- man/systemd.mount.xml | 1 - man/systemd.service.xml | 5 ----- man/systemd.socket.xml | 1 - man/systemd.swap.xml | 1 - src/execute.c | 1 - src/execute.h | 1 - src/mount.c | 6 ++---- src/service.c | 15 +++++---------- src/socket.c | 6 ++---- src/swap.c | 6 ++---- src/systemctl-bash-completion.sh | 2 +- units/console-shell.service.m4 | 2 +- units/emergency.service | 2 +- units/getty@.service.m4 | 2 +- units/rescue.service.m4 | 2 +- units/serial-getty@.service.m4 | 2 +- 18 files changed, 20 insertions(+), 49 deletions(-) diff --git a/TODO b/TODO index eeb6c0728..4302eeefe 100644 --- a/TODO +++ b/TODO @@ -12,8 +12,6 @@ F15: * hook emergency.target into local-fs.target in some way as OnFailure with isolate -* drop SIGHUP handling from rsyslog.service upstream (PENDING) - * teach dbus to activate all services it finds in /etc/systemd/services/org-*.service * save/restore tool for SysV as requested by FPC (PENDING) @@ -27,8 +25,6 @@ F15: * document default dependencies -* remove KillMode=process-group - * kernel patch wegen kmsg prio nach f15 * LOG_DAEMON/LOG_USER für kmsg messages schreiben @@ -41,8 +37,6 @@ Features: * when key file cannot be found, read it from kbd in cryptsetup -* hide passwords on TAB - * get rid of random file name in generator directory? /run/systemd/generator-IH1vFu diff --git a/man/systemctl.xml b/man/systemctl.xml index 535f9bd13..922fd2d68 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -304,13 +304,11 @@ kill, choose the mode how to kill the selected processes. Must be one of - , - or + or to select whether to kill the entire control - group, the process group or only the - selected process itself. If omitted - defaults to + group or only the selected process + itself. If omitted defaults to if is set, or diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index c7045e842..dd66d2ad7 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -221,7 +221,6 @@ processes of this mount shall be killed. One of , - , , . diff --git a/man/systemd.service.xml b/man/systemd.service.xml index e444efeb4..7458720a3 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -558,7 +558,6 @@ processes of this service shall be killed. One of , - , , . @@ -570,10 +569,6 @@ stop command (as configured with ExecStop=) is executed. If set to - only - the members of the process group of - the main service process are - killed. If set to only the main process itself is killed. If set to no process is diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 3b7581c54..8cbb512ec 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -519,7 +519,6 @@ processes of this socket unit shall be killed. One of , - , , . diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index d95e39ed8..3277ddbd4 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -175,7 +175,6 @@ processes of this swap shall be killed. One of , - , , . diff --git a/src/execute.c b/src/execute.c index a467411f7..cd44640a5 100644 --- a/src/execute.c +++ b/src/execute.c @@ -1933,7 +1933,6 @@ DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput); static const char* const kill_mode_table[_KILL_MODE_MAX] = { [KILL_CONTROL_GROUP] = "control-group", - [KILL_PROCESS_GROUP] = "process-group", [KILL_PROCESS] = "process", [KILL_NONE] = "none" }; diff --git a/src/execute.h b/src/execute.h index 44856d11f..208fe4ad5 100644 --- a/src/execute.h +++ b/src/execute.h @@ -43,7 +43,6 @@ struct CGroupBonding; typedef enum KillMode { KILL_CONTROL_GROUP = 0, - KILL_PROCESS_GROUP, KILL_PROCESS, KILL_NONE, _KILL_MODE_MAX, diff --git a/src/mount.c b/src/mount.c index cc49b1993..8528d17a8 100644 --- a/src/mount.c +++ b/src/mount.c @@ -747,9 +747,7 @@ static void mount_enter_signal(Mount *m, MountState state, bool success) { state == MOUNT_REMOUNTING_SIGTERM) ? m->exec_context.kill_signal : SIGKILL; if (m->control_pid > 0) { - if (kill_and_sigcont(m->exec_context.kill_mode == KILL_PROCESS_GROUP ? - -m->control_pid : - m->control_pid, sig) < 0 && errno != ESRCH) + if (kill_and_sigcont(m->control_pid, sig) < 0 && errno != ESRCH) log_warning("Failed to kill control process %li: %m", (long) m->control_pid); else @@ -1684,7 +1682,7 @@ static int mount_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError } if (m->control_pid > 0) - if (kill(mode == KILL_PROCESS_GROUP ? -m->control_pid : m->control_pid, signo) < 0) + if (kill(m->control_pid, signo) < 0) r = -errno; if (mode == KILL_CONTROL_GROUP) { diff --git a/src/service.c b/src/service.c index 1735a96c8..fd3a9c94e 100644 --- a/src/service.c +++ b/src/service.c @@ -828,7 +828,7 @@ static int service_load_sysv_path(Service *s, const char *path) { s->exec_context.std_output = (s->meta.manager->sysv_console || s->exec_context.std_input == EXEC_INPUT_TTY) ? EXEC_OUTPUT_TTY : s->meta.manager->default_std_output; - s->exec_context.kill_mode = KILL_PROCESS_GROUP; + s->exec_context.kill_mode = KILL_PROCESS; /* We use the long description only if * no short description is set. */ @@ -1838,19 +1838,14 @@ static void service_enter_signal(Service *s, ServiceState state, bool success) { int sig = (state == SERVICE_STOP_SIGTERM || state == SERVICE_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL; if (s->main_pid > 0) { - if (kill_and_sigcont(s->exec_context.kill_mode == KILL_PROCESS_GROUP ? - -s->main_pid : - s->main_pid, sig) < 0 && errno != ESRCH) - + if (kill_and_sigcont(s->main_pid, sig) < 0 && errno != ESRCH) log_warning("Failed to kill main process %li: %m", (long) s->main_pid); else wait_for_exit = true; } if (s->control_pid > 0) { - if (kill_and_sigcont(s->exec_context.kill_mode == KILL_PROCESS_GROUP ? - -s->control_pid : - s->control_pid, sig) < 0 && errno != ESRCH) + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) log_warning("Failed to kill control process %li: %m", (long) s->control_pid); else @@ -3212,11 +3207,11 @@ static int service_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusErro } if (s->control_pid > 0) - if (kill(mode == KILL_PROCESS_GROUP ? -s->control_pid : s->control_pid, signo) < 0) + if (kill(s->control_pid, signo) < 0) r = -errno; if (s->main_pid > 0) - if (kill(mode == KILL_PROCESS_GROUP ? -s->main_pid : s->main_pid, signo) < 0) + if (kill(s->main_pid, signo) < 0) r = -errno; if (mode == KILL_CONTROL_GROUP) { diff --git a/src/socket.c b/src/socket.c index 9045a2fc8..72be0e223 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1040,9 +1040,7 @@ static void socket_enter_signal(Socket *s, SocketState state, bool success) { int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL; if (s->control_pid > 0) { - if (kill_and_sigcont(s->exec_context.kill_mode == KILL_PROCESS_GROUP ? - -s->control_pid : - s->control_pid, sig) < 0 && errno != ESRCH) + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) log_warning("Failed to kill control process %li: %m", (long) s->control_pid); else @@ -1837,7 +1835,7 @@ static int socket_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError } if (s->control_pid > 0) - if (kill(mode == KILL_PROCESS_GROUP ? -s->control_pid : s->control_pid, signo) < 0) + if (kill(s->control_pid, signo) < 0) r = -errno; if (mode == KILL_CONTROL_GROUP) { diff --git a/src/swap.c b/src/swap.c index 035efbaf4..66bf5c2bf 100644 --- a/src/swap.c +++ b/src/swap.c @@ -661,9 +661,7 @@ static void swap_enter_signal(Swap *s, SwapState state, bool success) { state == SWAP_DEACTIVATING_SIGTERM) ? s->exec_context.kill_signal : SIGKILL; if (s->control_pid > 0) { - if (kill_and_sigcont(s->exec_context.kill_mode == KILL_PROCESS_GROUP ? - -s->control_pid : - s->control_pid, sig) < 0 && errno != ESRCH) + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) log_warning("Failed to kill control process %li: %m", (long) s->control_pid); else @@ -1286,7 +1284,7 @@ static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError * } if (s->control_pid > 0) - if (kill(mode == KILL_PROCESS_GROUP ? -s->control_pid : s->control_pid, signo) < 0) + if (kill(s->control_pid, signo) < 0) r = -errno; if (mode == KILL_CONTROL_GROUP) { diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh index f3420217b..ae0ecb7b7 100644 --- a/src/systemctl-bash-completion.sh +++ b/src/systemctl-bash-completion.sh @@ -60,7 +60,7 @@ _systemctl () { comps='all control main' ;; --kill-mode) - comps='control-group process process-group' + comps='control-group process' ;; --property|-p) comps='' diff --git a/units/console-shell.service.m4 b/units/console-shell.service.m4 index c98a08fcc..cce2d5a5a 100644 --- a/units/console-shell.service.m4 +++ b/units/console-shell.service.m4 @@ -31,7 +31,7 @@ WorkingDirectory=/root ExecStart=-/sbin/sulogin ExecStopPost=-/bin/systemctl poweroff StandardInput=tty-force -KillMode=process-group +KillMode=process # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash # terminates cleanly. diff --git a/units/emergency.service b/units/emergency.service index cb28a7838..a97ec5e38 100644 --- a/units/emergency.service +++ b/units/emergency.service @@ -21,7 +21,7 @@ ExecStartPre=-/bin/echo 'Welcome to emergency mode. Use "systemctl default" or ^ ExecStart=-/sbin/sulogin ExecStopPost=/bin/systemctl --fail default StandardInput=tty-force -KillMode=process-group +KillMode=process # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash # terminates cleanly. diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index 1a8a6a0e9..a9733a60d 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -36,7 +36,7 @@ ExecStart=-/sbin/agetty %I 38400 Restart=always RestartSec=0 UtmpIdentifier=%I -KillMode=process-group +KillMode=process # Unset locale for the console getty since the console has problems # displaying some internationalized messages. diff --git a/units/rescue.service.m4 b/units/rescue.service.m4 index 969ac4728..241c75071 100644 --- a/units/rescue.service.m4 +++ b/units/rescue.service.m4 @@ -28,7 +28,7 @@ ExecStart=-/bin/bash -c "exec ${SINGLE}"', `ExecStart=-/sbin/sulogin')) ExecStopPost=-/bin/systemctl --fail default StandardInput=tty-force -KillMode=process-group +KillMode=process # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash # terminates cleanly. diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 index d42330a1a..8b4f0fb9d 100644 --- a/units/serial-getty@.service.m4 +++ b/units/serial-getty@.service.m4 @@ -36,7 +36,7 @@ ExecStart=-/sbin/agetty -s %I 115200,38400,9600 Restart=always RestartSec=0 UtmpIdentifier=%I -KillMode=process-group +KillMode=process # Some login implementations ignore SIGTERM, so we send SIGHUP # instead, to ensure that login terminates cleanly. From d325ef27a7d482a57a1ce3d8c85e2c91be398c9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 23:32:10 +0200 Subject: [PATCH 127/200] unit: don't complain about failed units when deserializing --- src/unit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unit.c b/src/unit.c index 68eba69c6..40aae7527 100644 --- a/src/unit.c +++ b/src/unit.c @@ -1211,7 +1211,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su retroactively_stop_dependencies(u); } - if (ns != os && ns == UNIT_FAILED) { + if (ns != os && ns == UNIT_FAILED && u->meta.manager->n_deserializing <= 0) { log_notice("Unit %s entered failed state.", u->meta.id); unit_trigger_on_failure(u); } From efbac6d29c374696fba8f501b6f080e79584cc94 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Mar 2011 23:32:31 +0200 Subject: [PATCH 128/200] unit: fix parsing of condition-result --- src/unit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/unit.c b/src/unit.c index 40aae7527..a2953a6bc 100644 --- a/src/unit.c +++ b/src/unit.c @@ -2180,6 +2180,8 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { log_debug("Failed to parse condition result value %s", v); else u->meta.condition_result = b; + + continue; } if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) From ea87ca5a9ee9c82b456a54747d442c715ff26bee Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 00:43:16 +0200 Subject: [PATCH 129/200] unit: never apply /etc/rcN.d/ priority to native services --- TODO | 2 -- src/service.c | 13 ++++++++++--- src/service.h | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 4302eeefe..4759fcdd8 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,6 @@ F15: * swap units that are activated by one name but shown in the kernel under another are semi-broken -* dep cycle basic → udev-retry → auditd → iptables → basic - * isolate multi-user.target doesn't start a getty@tty1 if we run it from graphical.target * NFS, networkmanager ordering issue (PENDING) diff --git a/src/service.c b/src/service.c index fd3a9c94e..c74e8a009 100644 --- a/src/service.c +++ b/src/service.c @@ -115,6 +115,7 @@ static void service_init(Unit *u) { s->timer_watch.type = WATCH_INVALID; #ifdef HAVE_SYSV_COMPAT s->sysv_start_priority = -1; + s->sysv_start_priority_from_rcnd = -1; #endif s->socket_fd = -1; s->guess_main_pid = true; @@ -537,7 +538,7 @@ static int service_load_sysv_path(Service *s, const char *path) { * data from the LSB header. */ if (start_priority < 0 || start_priority > 99) log_warning("[%s:%u] Start priority out of range. Ignoring.", path, line); - else if (s->sysv_start_priority < 0) + else s->sysv_start_priority = start_priority; char_array_0(runlevels); @@ -853,6 +854,12 @@ static int service_load_sysv_path(Service *s, const char *path) { u->meta.description = d; } + /* The priority that has been set in /etc/rcN.d/ hierarchies + * takes precedence over what is stored as default in the LSB + * header */ + if (s->sysv_start_priority_from_rcnd >= 0) + s->sysv_start_priority = s->sysv_start_priority_from_rcnd; + u->meta.load_state = UNIT_LOADED; r = 0; @@ -3009,8 +3016,8 @@ static int service_enumerate(Manager *m) { if (de->d_name[0] == 'S') { if (rcnd_table[i].type == RUNLEVEL_UP || rcnd_table[i].type == RUNLEVEL_SYSINIT) { - SERVICE(service)->sysv_start_priority = - MAX(a*10 + b, SERVICE(service)->sysv_start_priority); + SERVICE(service)->sysv_start_priority_from_rcnd = + MAX(a*10 + b, SERVICE(service)->sysv_start_priority_from_rcnd); SERVICE(service)->sysv_enabled = true; } diff --git a/src/service.h b/src/service.h index 627b356e2..e3cb431cf 100644 --- a/src/service.h +++ b/src/service.h @@ -138,6 +138,7 @@ struct Service { #ifdef HAVE_SYSV_COMPAT bool sysv_has_lsb:1; bool sysv_enabled:1; + int sysv_start_priority_from_rcnd; int sysv_start_priority; char *sysv_path; From 72bc8d005654ad30838edfe9373109a49cc29448 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 00:47:50 +0200 Subject: [PATCH 130/200] manager: fix taint check for /usr --- TODO | 4 ++-- src/dbus-manager.c | 2 +- src/manager.c | 2 ++ src/manager.h | 2 ++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 4759fcdd8..59bd2130d 100644 --- a/TODO +++ b/TODO @@ -27,10 +27,10 @@ F15: * LOG_DAEMON/LOG_USER für kmsg messages schreiben -* fix /usr taint - * disable /dev/console status messages after plymouth went down +* quotacheck pulled in too often + Features: * when key file cannot be found, read it from kbd in cryptsetup diff --git a/src/dbus-manager.c b/src/dbus-manager.c index c21cb5f57..a2a25b72f 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -223,7 +223,7 @@ static int bus_manager_append_tainted(Manager *m, DBusMessageIter *i, const char assert(i); assert(property); - if (dir_is_empty("/usr") > 0) + if (m->taint_usr) e = stpcpy(e, "usr-separate-fs"); if (readlink_malloc("/etc/mtab", &p) < 0) { diff --git a/src/manager.c b/src/manager.c index 69d231a85..faf30dc49 100644 --- a/src/manager.c +++ b/src/manager.c @@ -278,6 +278,8 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) { log_error("Failed to connect to audit log: %m"); #endif + m->taint_usr = dir_is_empty("/usr") > 0; + *_m = m; return 0; diff --git a/src/manager.h b/src/manager.h index c183e105a..4b405d61c 100644 --- a/src/manager.h +++ b/src/manager.h @@ -211,6 +211,8 @@ struct Manager { bool dispatching_run_queue:1; bool dispatching_dbus_queue:1; + bool taint_usr:1; + bool show_status; bool confirm_spawn; #ifdef HAVE_SYSV_COMPAT From cb39ed3fdeb102a921e862a23b90607b5242f94e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 01:53:34 +0200 Subject: [PATCH 131/200] quota: do not pull in quota tools for mounts that do not originate in neither /etc/fstab nor fragment files --- TODO | 6 --- src/mount.c | 140 +++++++++++++++++++++++++++++----------------------- 2 files changed, 77 insertions(+), 69 deletions(-) diff --git a/TODO b/TODO index 59bd2130d..1074d63c6 100644 --- a/TODO +++ b/TODO @@ -29,8 +29,6 @@ F15: * disable /dev/console status messages after plymouth went down -* quotacheck pulled in too often - Features: * when key file cannot be found, read it from kbd in cryptsetup @@ -168,10 +166,6 @@ Features: * add separate man page for [Install] settings -* only add quotacheck deps to .mount units which mention grpquota/usrquota in the mount flags - -* systemctl condrestart should return 0 if service isn't running - * allow runtime changing of log level and target External: diff --git a/src/mount.c b/src/mount.c index 8528d17a8..209e19c17 100644 --- a/src/mount.c +++ b/src/mount.c @@ -128,6 +128,26 @@ static void mount_done(Unit *u) { unit_unwatch_timer(u, &m->timer_watch); } +static MountParameters* get_mount_parameters_configured(Mount *m) { + assert(m); + + if (m->from_fragment) + return &m->parameters_fragment; + else if (m->from_etc_fstab) + return &m->parameters_etc_fstab; + + return NULL; +} + +static MountParameters* get_mount_parameters(Mount *m) { + assert(m); + + if (m->from_proc_self_mountinfo) + return &m->parameters_proc_self_mountinfo; + + return get_mount_parameters_configured(m); +} + static int mount_add_mount_links(Mount *m) { Meta *other; int r; @@ -135,12 +155,7 @@ static int mount_add_mount_links(Mount *m) { assert(m); - if (m->from_fragment) - pm = &m->parameters_fragment; - else if (m->from_etc_fstab) - pm = &m->parameters_etc_fstab; - else - pm = NULL; + pm = get_mount_parameters_configured(m); /* Adds in links to other mount points that might lie below or * above us in the hierarchy */ @@ -155,19 +170,14 @@ static int mount_add_mount_links(Mount *m) { if (n->meta.load_state != UNIT_LOADED) continue; - if (n->from_fragment) - pn = &n->parameters_fragment; - else if (n->from_etc_fstab) - pn = &n->parameters_etc_fstab; - else - pn = NULL; + pn = get_mount_parameters_configured(n); if (path_startswith(m->where, n->where)) { if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0) return r; - if (n->from_etc_fstab || n->from_fragment) + if (pn) if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) return r; @@ -176,7 +186,7 @@ static int mount_add_mount_links(Mount *m) { if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0) return r; - if (m->from_etc_fstab || m->from_fragment) + if (pm) if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) return r; @@ -185,18 +195,16 @@ static int mount_add_mount_links(Mount *m) { if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0) return r; - if (m->from_etc_fstab || m->from_fragment) - if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) - return r; + if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) + return r; } else if (pn && path_startswith(pn->what, m->where)) { if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0) return r; - if (n->from_etc_fstab || n->from_fragment) - if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) - return r; + if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; } } @@ -272,6 +280,43 @@ static char* mount_test_option(const char *haystack, const char *needle) { return hasmntopt(&me, needle); } +static bool mount_is_network(MountParameters *p) { + assert(p); + + if (mount_test_option(p->options, "_netdev")) + return true; + + if (p->fstype && fstype_is_network(p->fstype)) + return true; + + return false; +} + +static bool mount_is_bind(MountParameters *p) { + assert(p); + + if (mount_test_option(p->options, "bind")) + return true; + + if (p->fstype && streq(p->fstype, "bind")) + return true; + + return false; +} + +static bool needs_quota(MountParameters *p) { + assert(p); + + if (mount_is_network(p)) + return false; + + if (mount_is_bind(p)) + return false; + + return mount_test_option(p->options, "usrquota") || + mount_test_option(p->options, "grpquota"); +} + static int mount_add_target_links(Mount *m) { const char *target, *after = NULL; MountParameters *p; @@ -281,11 +326,7 @@ static int mount_add_target_links(Mount *m) { assert(m); - if (m->from_fragment) - p = &m->parameters_fragment; - else if (m->from_etc_fstab) - p = &m->parameters_etc_fstab; - else + if (!(p = get_mount_parameters_configured(m))) return 0; noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO); @@ -298,8 +339,7 @@ static int mount_add_target_links(Mount *m) { mount_test_option(p->options, "comment=systemd.automount") || mount_test_option(p->options, "x-systemd-automount"); - if (mount_test_option(p->options, "_netdev") || - (p->fstype && fstype_is_network(p->fstype))) { + if (mount_is_network(p)) { target = SPECIAL_REMOTE_FS_TARGET; if (m->meta.manager->running_as == MANAGER_SYSTEM) @@ -337,29 +377,13 @@ static int mount_add_target_links(Mount *m) { } } -static bool mount_is_bind(MountParameters *p) { - assert(p); - - if (p->fstype && streq(p->fstype, "bind")) - return true; - - if (mount_test_option(p->options, "bind")) - return true; - - return false; -} - static int mount_add_device_links(Mount *m) { MountParameters *p; int r; assert(m); - if (m->from_fragment) - p = &m->parameters_fragment; - else if (m->from_etc_fstab) - p = &m->parameters_etc_fstab; - else + if (!(p = get_mount_parameters_configured(m))) return 0; if (!p->what) @@ -415,20 +439,13 @@ static int mount_add_default_dependencies(Mount *m) { !path_equal(m->where, "/")) { MountParameters *p; - if (m->from_fragment) - p = &m->parameters_fragment; - else if (m->from_etc_fstab) - p = &m->parameters_etc_fstab; - else - p = NULL; + p = get_mount_parameters_configured(m); - if (!p || - (!mount_test_option(p->options, "_netdev") && - !(p->fstype && fstype_is_network(p->fstype)) && - (mount_test_option(p->options, "usrquota") || mount_test_option(p->options, "grpquota")))) + if (p && needs_quota(p)) { if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true)) < 0 || (r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true)) < 0) return r; + } if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) return r; @@ -640,12 +657,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) { assert(m); assert(f); - if (m->from_proc_self_mountinfo) - p = &m->parameters_proc_self_mountinfo; - else if (m->from_fragment) - p = &m->parameters_fragment; - else - p = &m->parameters_etc_fstab; + p = get_mount_parameters(m); fprintf(f, "%sMount State: %s\n" @@ -834,6 +846,7 @@ fail: static void mount_enter_mounting(Mount *m) { int r; + MountParameters *p; assert(m); @@ -842,9 +855,10 @@ static void mount_enter_mounting(Mount *m) { mkdir_p(m->where, m->directory_mode); - /* create the source directory for bind-mounts if needed */ - if (m->parameters_fragment.fstype && strcmp(m->parameters_fragment.fstype, "bind") == 0) - mkdir_p(m->parameters_fragment.what, m->directory_mode); + /* Create the source directory for bind-mounts if needed */ + p = get_mount_parameters_configured(m); + if (p && mount_is_bind(p)) + mkdir_p(p->what, m->directory_mode); if (m->from_fragment) r = exec_command_set( From d885ac661b74bb44691c4ac16822e93cf08e11e9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 02:09:15 +0200 Subject: [PATCH 132/200] locale: don't access misinitialized variable --- src/locale-setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale-setup.c b/src/locale-setup.c index e146746df..39b877cab 100644 --- a/src/locale-setup.c +++ b/src/locale-setup.c @@ -65,7 +65,7 @@ static const char * const variable_names[_VARIABLE_MAX] = { int locale_setup(void) { char *variables[_VARIABLE_MAX]; - int r, i; + int r = 0, i; zero(variables); From 871c44a747a8bf4465cbfda445216e9ac66d4a40 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 02:12:46 +0200 Subject: [PATCH 133/200] taint: add missing cgroups taint flag --- src/dbus-manager.c | 16 +++++++++------- src/main.c | 25 +++++++++++++++++++++---- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/dbus-manager.c b/src/dbus-manager.c index a2a25b72f..92a602219 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -20,6 +20,7 @@ ***/ #include +#include #include "dbus.h" #include "log.h" @@ -224,16 +225,17 @@ static int bus_manager_append_tainted(Manager *m, DBusMessageIter *i, const char assert(property); if (m->taint_usr) - e = stpcpy(e, "usr-separate-fs"); + e = stpcpy(e, "usr-separate-fs "); - if (readlink_malloc("/etc/mtab", &p) < 0) { - if (e != buf) - e = stpcpy(e, " "); - e = stpcpy(e, "etc-mtab-not-symlink"); - } else + if (readlink_malloc("/etc/mtab", &p) < 0) + e = stpcpy(e, "etc-mtab-not-symlink "); + else free(p); - t = buf; + if (access("/proc/cgroups", F_OK) < 0) + e = stpcpy(e, "cgroups-missing "); + + t = strstrip(buf); if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) return -ENOMEM; diff --git a/src/main.c b/src/main.c index 8d27eb426..176a4f5ec 100644 --- a/src/main.c +++ b/src/main.c @@ -985,10 +985,26 @@ static void test_usr(void) { /* Check that /usr is not a separate fs */ - if (dir_is_empty("/usr") > 0) - log_warning("/usr appears to be on a different file system than /. This is not supported anymore. " - "Some things will probably break (sometimes even silently) in mysterious ways. " - "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information."); + if (dir_is_empty("/usr") <= 0) + return; + + log_warning("/usr appears to be on a different file system than /. This is not supported anymore. " + "Some things will probably break (sometimes even silently) in mysterious ways. " + "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information."); +} + +static void test_cgroups(void) { + + if (access("/proc/cgroups", F_OK) >= 0) + return; + + log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. " + "Systems without control groups are not supported. " + "We will now sleep for 10s, and then continue boot-up. " + "Expect breakage and please do not file bugs. " + "Instead fix your kernel and enable CONFIG_CGROUPS." ); + + sleep(10); } int main(int argc, char *argv[]) { @@ -1171,6 +1187,7 @@ int main(int argc, char *argv[]) { test_mtab(); test_usr(); + test_cgroups(); } if ((r = manager_new(arg_running_as, &m)) < 0) { From 6faa11140bf776cdaeb8d22d01816e6e48296971 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 02:21:48 +0200 Subject: [PATCH 134/200] status: show status messages unconditionally if plymouth is around --- src/main.c | 7 +------ src/unit.c | 5 ++++- src/util.c | 4 ++++ src/util.h | 2 ++ 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 176a4f5ec..b43d8eca9 100644 --- a/src/main.c +++ b/src/main.c @@ -1093,11 +1093,6 @@ int main(int argc, char *argv[]) { goto finish; } - /* If Plymouth is being run make sure we show the status, so - * that there's something nice to see when people press Esc */ - if (access("/run/initramfs/plymouth", F_OK) >= 0) - arg_show_status = true; - if (arg_action == ACTION_HELP) { retval = help(); goto finish; @@ -1177,7 +1172,7 @@ int main(int argc, char *argv[]) { if (arg_running_as == MANAGER_SYSTEM && !serialization) { locale_setup(); - if (arg_show_status) + if (arg_show_status || plymouth_running()) status_welcome(); kmod_setup(); diff --git a/src/unit.c b/src/unit.c index a2953a6bc..b68464922 100644 --- a/src/unit.c +++ b/src/unit.c @@ -2254,7 +2254,10 @@ void unit_status_printf(Unit *u, const char *format, ...) { if (u->meta.manager->running_as != MANAGER_SYSTEM) return; - if (!u->meta.manager->show_status) + /* If Plymouth is running make sure we show the status, so + * that there's something nice to see when people press Esc */ + + if (!u->meta.manager->show_status && !plymouth_running()) return; if (!manager_is_booting_or_shutting_down(u->meta.manager)) diff --git a/src/util.c b/src/util.c index fada69cf1..5e101e441 100644 --- a/src/util.c +++ b/src/util.c @@ -4188,6 +4188,10 @@ bool nulstr_contains(const char*nulstr, const char *needle) { return false; } +bool plymouth_running(void) { + return access("/run/initramfs/plymouth", F_OK) >= 0; +} + 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 04afc731e..dfbfa8b04 100644 --- a/src/util.h +++ b/src/util.h @@ -392,6 +392,8 @@ int kill_and_sigcont(pid_t pid, int sig); bool nulstr_contains(const char*nulstr, const char *needle); +bool plymouth_running(void); + #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) From 39366bacda3dddbae3c6677da5c97770cff0a279 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 03:03:35 +0200 Subject: [PATCH 135/200] plymouth: don't explicitly enable status message when plymouth is up https://bugzilla.redhat.com/show_bug.cgi?id=676302 systemd now watches /run/initramfs/plymouth and generates messages exactly when that file exists. Hence we don't need the sending of the signals anymore. --- units/plymouth-start.service | 3 --- 1 file changed, 3 deletions(-) diff --git a/units/plymouth-start.service b/units/plymouth-start.service index eb336e619..6ab51f32a 100644 --- a/units/plymouth-start.service +++ b/units/plymouth-start.service @@ -19,6 +19,3 @@ ConditionPathExists=!/run/initramfs/plymouth ExecStart=/sbin/plymouthd --mode=boot ExecStartPost=-/bin/plymouth --show-splash Type=forking - -# Send SIGRTMIN+20 to systemd, i.e. enable status messages -ExecStartPost=-/usr/bin/kill -54 1 From bdbf995180771da2d3a85ea011d49461775c74a3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 20:04:20 +0200 Subject: [PATCH 136/200] unit: don't override timestamps due to state changes when deserializing --- src/unit.c | 147 ++++++++++++++++++++++++++++------------------------- 1 file changed, 78 insertions(+), 69 deletions(-) diff --git a/src/unit.c b/src/unit.c index b68464922..895e40178 100644 --- a/src/unit.c +++ b/src/unit.c @@ -1101,7 +1101,6 @@ void unit_trigger_on_failure(Unit *u) { } void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) { - dual_timestamp ts; bool unexpected; assert(u); @@ -1114,24 +1113,28 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su * behaviour here. For example: if a mount point is remounted * this function will be called too! */ - dual_timestamp_get(&ts); + if (u->meta.manager->n_deserializing <= 0) { + dual_timestamp ts; - if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns)) - u->meta.inactive_exit_timestamp = ts; - else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns)) - u->meta.inactive_enter_timestamp = ts; + dual_timestamp_get(&ts); - if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns)) - u->meta.active_enter_timestamp = ts; - else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns)) - u->meta.active_exit_timestamp = ts; + if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns)) + u->meta.inactive_exit_timestamp = ts; + else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns)) + u->meta.inactive_enter_timestamp = ts; + + if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns)) + u->meta.active_enter_timestamp = ts; + else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns)) + u->meta.active_exit_timestamp = ts; + + timer_unit_notify(u, ns); + path_unit_notify(u, ns); + } if (UNIT_IS_INACTIVE_OR_FAILED(ns)) cgroup_bonding_trim_list(u->meta.cgroup_bondings, true); - timer_unit_notify(u, ns); - path_unit_notify(u, ns); - if (u->meta.job) { unexpected = false; @@ -1198,65 +1201,73 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su } else unexpected = true; - /* If this state change happened without being requested by a - * job, then let's retroactively start or stop - * dependencies. We skip that step when deserializing, since - * we don't want to create any additional jobs just because - * something is already activated. */ + if (u->meta.manager->n_deserializing <= 0) { - if (unexpected && u->meta.manager->n_deserializing <= 0) { - if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns)) - retroactively_start_dependencies(u); - else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) - retroactively_stop_dependencies(u); - } + /* If this state change happened without being + * requested by a job, then let's retroactively start + * or stop dependencies. We skip that step when + * deserializing, since we don't want to create any + * additional jobs just because something is already + * activated. */ - if (ns != os && ns == UNIT_FAILED && u->meta.manager->n_deserializing <= 0) { - log_notice("Unit %s entered failed state.", u->meta.id); - unit_trigger_on_failure(u); - } - - /* Some names are special */ - if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) { - if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) - /* The bus just might have become available, - * hence try to connect to it, if we aren't - * yet connected. */ - bus_init(u->meta.manager, true); - - if (u->meta.type == UNIT_SERVICE && - !UNIT_IS_ACTIVE_OR_RELOADING(os)) { - /* Write audit record if we have just finished starting up */ - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, true); - u->meta.in_audit = true; + if (unexpected) { + if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns)) + retroactively_start_dependencies(u); + else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + retroactively_stop_dependencies(u); } - if (!UNIT_IS_ACTIVE_OR_RELOADING(os)) - manager_send_unit_plymouth(u->meta.manager, u); - - } else { - - /* We don't care about D-Bus here, since we'll get an - * asynchronous notification for it anyway. */ - - if (u->meta.type == UNIT_SERVICE && - UNIT_IS_INACTIVE_OR_FAILED(ns) && - !UNIT_IS_INACTIVE_OR_FAILED(os)) { - - /* Hmm, if there was no start record written - * write it now, so that we always have a nice - * pair */ - if (!u->meta.in_audit) { - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE); - - if (ns == UNIT_INACTIVE) - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, true); - } else - /* Write audit record if we have just finished shutting down */ - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE); - - u->meta.in_audit = false; + if (ns != os && ns == UNIT_FAILED) { + log_notice("Unit %s entered failed state.", u->meta.id); + unit_trigger_on_failure(u); } + + + /* Some names are special */ + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) { + + if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) + /* The bus just might have become available, + * hence try to connect to it, if we aren't + * yet connected. */ + bus_init(u->meta.manager, true); + + if (u->meta.type == UNIT_SERVICE && + !UNIT_IS_ACTIVE_OR_RELOADING(os)) { + /* Write audit record if we have just finished starting up */ + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, true); + u->meta.in_audit = true; + } + + if (!UNIT_IS_ACTIVE_OR_RELOADING(os)) + manager_send_unit_plymouth(u->meta.manager, u); + + } else { + + /* We don't care about D-Bus here, since we'll get an + * asynchronous notification for it anyway. */ + + if (u->meta.type == UNIT_SERVICE && + UNIT_IS_INACTIVE_OR_FAILED(ns) && + !UNIT_IS_INACTIVE_OR_FAILED(os)) { + + /* Hmm, if there was no start record written + * write it now, so that we always have a nice + * pair */ + if (!u->meta.in_audit) { + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE); + + if (ns == UNIT_INACTIVE) + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, true); + } else + /* Write audit record if we have just finished shutting down */ + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE); + + u->meta.in_audit = false; + } + } + + manager_recheck_syslog(u->meta.manager); } /* Maybe we finished startup and are now ready for being @@ -1265,8 +1276,6 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su unit_add_to_dbus_queue(u); unit_add_to_gc_queue(u); - - manager_recheck_syslog(u->meta.manager); } int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) { From f39133ac7fcd49c767a6ca3a491cb6c03269968a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 20:04:37 +0200 Subject: [PATCH 137/200] analyze: add systemd-analyze tool --- src/systemd-analyze | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100755 src/systemd-analyze diff --git a/src/systemd-analyze b/src/systemd-analyze new file mode 100755 index 000000000..43023297f --- /dev/null +++ b/src/systemd-analyze @@ -0,0 +1,40 @@ +#!/usr/bin/python + +import dbus, sys + +def acquire_time_data(): + bus = dbus.SystemBus() + + manager = dbus.Interface(bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1'), 'org.freedesktop.systemd1.Manager') + + units = manager.ListUnits() + + l = [] + + for i in units: + properties = dbus.Interface(bus.get_object('org.freedesktop.systemd1', i[6]), 'org.freedesktop.DBus.Properties') + + ixt = int(properties.Get('org.freedesktop.systemd1.Unit', 'InactiveExitTimestamp')) + aet = int(properties.Get('org.freedesktop.systemd1.Unit', 'ActiveEnterTimestamp')) + axt = int(properties.Get('org.freedesktop.systemd1.Unit', 'ActiveExitTimestamp')) + iet = int(properties.Get('org.freedesktop.systemd1.Unit', 'InactiveEnterTimestamp')) + + l.append((str(i[0]), ixt, aet, axt, iet)) + + return l + +data = acquire_time_data() + +if len(sys.argv) <= 1 or sys.argv[1] == 'blame': + + s = sorted(data, key = lambda i: i[2] - i[1], reverse = True) + + for i in s: + + if i[1] <= 0 or i[2] <= 0: + continue + + if i[2] <= i[1]: + continue + + sys.stdout.write("%lums\t %s\n" % ((i[2] - i[1]) / 1000, i[0])) From fac9f8df1f49117cf8b84667cb0565103e955bcb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 20:15:45 +0200 Subject: [PATCH 138/200] analyze: beautify output a bit --- src/manager.c | 2 +- src/systemd-analyze | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/manager.c b/src/manager.c index faf30dc49..fdb5beda2 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2328,7 +2328,7 @@ static int process_event(Manager *m, struct epoll_event *ev) { int manager_loop(Manager *m) { int r; - RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 1000); + RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000); assert(m); m->exit_code = MANAGER_RUNNING; diff --git a/src/systemd-analyze b/src/systemd-analyze index 43023297f..1a367e7e2 100755 --- a/src/systemd-analyze +++ b/src/systemd-analyze @@ -23,10 +23,9 @@ def acquire_time_data(): return l -data = acquire_time_data() - if len(sys.argv) <= 1 or sys.argv[1] == 'blame': + data = acquire_time_data() s = sorted(data, key = lambda i: i[2] - i[1], reverse = True) for i in s: @@ -37,4 +36,6 @@ if len(sys.argv) <= 1 or sys.argv[1] == 'blame': if i[2] <= i[1]: continue - sys.stdout.write("%lums\t %s\n" % ((i[2] - i[1]) / 1000, i[0])) + sys.stdout.write("%6lums %s\n" % ((i[2] - i[1]) / 1000, i[0])) +else: + sys.stderr.write("Unknown verb '%s'.\n" % sys.argv[1]) From 3b2775c5cea96060b2c4c44fee18b87b5d51cb02 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Mar 2011 20:16:07 +0200 Subject: [PATCH 139/200] unit: when deserializing do reconnect to dbus/syslog when they show up --- src/unit.c | 85 +++++++++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/src/unit.c b/src/unit.c index 895e40178..4f83778c5 100644 --- a/src/unit.c +++ b/src/unit.c @@ -1221,55 +1221,56 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su log_notice("Unit %s entered failed state.", u->meta.id); unit_trigger_on_failure(u); } + } + /* Some names are special */ + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) { - /* Some names are special */ - if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) { + if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) + /* The bus just might have become available, + * hence try to connect to it, if we aren't + * yet connected. */ + bus_init(u->meta.manager, true); - if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) - /* The bus just might have become available, - * hence try to connect to it, if we aren't - * yet connected. */ - bus_init(u->meta.manager, true); - - if (u->meta.type == UNIT_SERVICE && - !UNIT_IS_ACTIVE_OR_RELOADING(os)) { - /* Write audit record if we have just finished starting up */ - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, true); - u->meta.in_audit = true; - } - - if (!UNIT_IS_ACTIVE_OR_RELOADING(os)) - manager_send_unit_plymouth(u->meta.manager, u); - - } else { - - /* We don't care about D-Bus here, since we'll get an - * asynchronous notification for it anyway. */ - - if (u->meta.type == UNIT_SERVICE && - UNIT_IS_INACTIVE_OR_FAILED(ns) && - !UNIT_IS_INACTIVE_OR_FAILED(os)) { - - /* Hmm, if there was no start record written - * write it now, so that we always have a nice - * pair */ - if (!u->meta.in_audit) { - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE); - - if (ns == UNIT_INACTIVE) - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, true); - } else - /* Write audit record if we have just finished shutting down */ - manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE); - - u->meta.in_audit = false; - } + if (u->meta.type == UNIT_SERVICE && + !UNIT_IS_ACTIVE_OR_RELOADING(os) && + u->meta.manager->n_deserializing <= 0) { + /* Write audit record if we have just finished starting up */ + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, true); + u->meta.in_audit = true; } - manager_recheck_syslog(u->meta.manager); + if (!UNIT_IS_ACTIVE_OR_RELOADING(os)) + manager_send_unit_plymouth(u->meta.manager, u); + + } else { + + /* We don't care about D-Bus here, since we'll get an + * asynchronous notification for it anyway. */ + + if (u->meta.type == UNIT_SERVICE && + UNIT_IS_INACTIVE_OR_FAILED(ns) && + !UNIT_IS_INACTIVE_OR_FAILED(os) && + u->meta.manager->n_deserializing <= 0) { + + /* Hmm, if there was no start record written + * write it now, so that we always have a nice + * pair */ + if (!u->meta.in_audit) { + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE); + + if (ns == UNIT_INACTIVE) + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, true); + } else + /* Write audit record if we have just finished shutting down */ + manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE); + + u->meta.in_audit = false; + } } + manager_recheck_syslog(u->meta.manager); + /* Maybe we finished startup and are now ready for being * stopped because unneeded? */ unit_check_unneeded(u); From 8e028bb1edf33da3ced2d353fbfafac7ad75e6be Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 01:19:12 +0200 Subject: [PATCH 140/200] analyze: add plotter --- TODO | 4 ++ src/systemd-analyze | 136 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 1074d63c6..a1448d211 100644 --- a/TODO +++ b/TODO @@ -29,6 +29,10 @@ F15: * disable /dev/console status messages after plymouth went down +* plymouth pid file + +* selinux issue http://people.gnome.org/~cosimoc/selinux.jpg + Features: * when key file cannot be found, read it from kbd in cryptsetup diff --git a/src/systemd-analyze b/src/systemd-analyze index 1a367e7e2..4ffa3bb95 100755 --- a/src/systemd-analyze +++ b/src/systemd-analyze @@ -3,10 +3,8 @@ import dbus, sys def acquire_time_data(): - bus = dbus.SystemBus() manager = dbus.Interface(bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1'), 'org.freedesktop.systemd1.Manager') - units = manager.ListUnits() l = [] @@ -23,19 +21,145 @@ def acquire_time_data(): return l +def acquire_start_time(): + properties = dbus.Interface(bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1'), 'org.freedesktop.DBus.Properties') + + startup_time = int(properties.Get('org.freedesktop.systemd1.Manager', 'StartupTimestamp')) + finish_time = int(properties.Get('org.freedesktop.systemd1.Manager', 'FinishTimestamp')) + + assert startup_time <= finish_time + + return startup_time, finish_time + +def draw_box(context, j, k, l, m, r = 0, g = 0, b = 0): + context.save() + context.set_source_rgb(r, g, b) + context.rectangle(j, k, l, m) + context.fill() + context.restore() + +def draw_text(context, x, y, text, size = 12, r = 0, g = 0, b = 0, center = True): + context.save() + + context.set_source_rgb(r, g, b) + context.select_font_face("Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) + context.set_font_size(size) + + if center: + x_bearing, y_bearing, width, height = context.text_extents(text)[:4] +# context.move_to(x - width / 2 - x_bearing, y - height / 2 - y_bearing) + context.move_to(x, y - height / 2 - y_bearing) + else: + context.move_to(x, y) + context.show_text(text) + + context.restore() + +bus = dbus.SystemBus() + if len(sys.argv) <= 1 or sys.argv[1] == 'blame': data = acquire_time_data() s = sorted(data, key = lambda i: i[2] - i[1], reverse = True) - for i in s: + for name, ixt, aet, axt, iet in s: - if i[1] <= 0 or i[2] <= 0: + if ixt <= 0 or aet <= 0: continue - if i[2] <= i[1]: + if aet <= ixt: continue - sys.stdout.write("%6lums %s\n" % ((i[2] - i[1]) / 1000, i[0])) + sys.stdout.write("%6lums %s\n" % ((aet - ixt) / 1000, name)) + +elif sys.argv[1] == 'plot': + import cairo + + start_time, finish_time = acquire_start_time() + data = acquire_time_data() + s = sorted(data, key = lambda i: i[1]) + + # 1000px = 10s, 1px = 10ms + border = 100 + width = (finish_time - start_time)/10000 + border*2 + height = 3000 + + bar_height = 20 + bar_space = bar_height * 0.1 + + surface = cairo.SVGSurface(sys.stdout, width, height) + context = cairo.Context(surface) + + draw_box(context, 0, 0, width, height, 1, 1, 1) + + context.translate(border + 0.5, border + 0.5) + + context.save() + context.set_line_width(1) + context.set_source_rgb(0.7, 0.7, 0.7) + + for x in range(0, (finish_time - start_time)/10000, 100): + context.move_to(x, 0) + context.line_to(x, height-border*2) + + context.move_to(0, 0) + context.line_to(width-border*2, 0) + + context.move_to(0, height-border*2) + context.line_to(width-border*2, height-border*2) + + context.stroke() + context.restore() + + for x in range(0, (finish_time - start_time)/10000, 100): + draw_text(context, x, -5, "%lus" % (x/100), center = False) + + y = 0 + + for name, ixt, aet, axt, iet in s: + + drawn = False + left = -1 + + if ixt >= start_time and aet > ixt: + + # Activating + a = ixt - start_time + b = aet - ixt + draw_box(context, a/10000, y, b/10000, bar_height, 1, 0, 0) + drawn = True + + if left < 0: + left = a + + if aet >= start_time and axt > aet: + + # Active + a = aet - start_time + b = axt - aet + draw_box(context, a/10000, y, b/10000, bar_height, .7, .5, .5) + drawn = True + + if left < 0: + left = a + + if axt >= start_time and iet > axt: + + # Deactivating + a = axt - start_time + b = iet - axt + draw_box(context, a/10000, y, b/10000, bar_height, .6, .4, .4) + drawn = True + + if left < 0: + left = a + + if drawn: + draw_text(context, left/10000 + 10, y + bar_height/2, name) + + y += bar_height + bar_space + + surface.finish() + else: sys.stderr.write("Unknown verb '%s'.\n" % sys.argv[1]) From 3f7a8c4e9f1d3ce48919e24eb2c9d56dd6fd88d8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 31 Mar 2011 02:36:32 +0200 Subject: [PATCH 141/200] update TODO --- TODO | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index a1448d211..215a73601 100644 --- a/TODO +++ b/TODO @@ -35,13 +35,17 @@ F15: Features: +* Find a way to replace /var/run, /var/lock directories with + symlinks during an RPM package upgrade (filesystem.rpm or systemd.rpm). + We soon want to get rid of var-run.mount var-lock.mount units. + * when key file cannot be found, read it from kbd in cryptsetup * get rid of random file name in generator directory? /run/systemd/generator-IH1vFu * fix SD_WARNING syslog stuff in src/sd-daemon.h to include the - facility + LOG_DAEMON(3) facility value. Never use the LOG_KERNEL(0) facility. * add switch to systemctl to show enabled but not running services. Or another switch that shows service that have been running since @@ -49,12 +53,13 @@ Features: * reuse mkdtemp namespace dirs in /tmp? -* don't strip facility from kmsg log messages as soon as that is possible. +* don't strip facility from kmsg log messages as soon as that is possible: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=9d90c8d9cde929cbc575098e825d7c29d9f45054 * recreate systemd's D-Bus private socket file on SIGUSR2 * be more specific what failed: + ... Unmounting file systems. Not all file systems unmounted, 1 left. Disabling swaps. @@ -64,6 +69,7 @@ Features: Unmounting file systems. Not all file systems unmounted, 1 left. Cannot finalize remaining file systems and devices, giving up. + ... * check for compiled-in, but not active selinux, and don't print any warnings about policy loading. Probably check for available selinux in /proc/filesystems, From fe8954ab47b57703d2fb3116f5dbe389426e99bc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 03:17:13 +0200 Subject: [PATCH 142/200] analyze: improve output --- src/systemd-analyze | 81 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/src/systemd-analyze b/src/systemd-analyze index 4ffa3bb95..5e3a087e9 100755 --- a/src/systemd-analyze +++ b/src/systemd-analyze @@ -10,6 +10,9 @@ def acquire_time_data(): l = [] for i in units: + if i[5] != "": + continue + properties = dbus.Interface(bus.get_object('org.freedesktop.systemd1', i[6]), 'org.freedesktop.DBus.Properties') ixt = int(properties.Get('org.freedesktop.systemd1.Unit', 'InactiveExitTimestamp')) @@ -38,23 +41,37 @@ def draw_box(context, j, k, l, m, r = 0, g = 0, b = 0): context.fill() context.restore() -def draw_text(context, x, y, text, size = 12, r = 0, g = 0, b = 0, center = True): +def draw_text(context, x, y, text, size = 12, r = 0, g = 0, b = 0, vcenter = 0.5, hcenter = 0.5): context.save() context.set_source_rgb(r, g, b) context.select_font_face("Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) context.set_font_size(size) - if center: + if vcenter or hcenter: x_bearing, y_bearing, width, height = context.text_extents(text)[:4] -# context.move_to(x - width / 2 - x_bearing, y - height / 2 - y_bearing) - context.move_to(x, y - height / 2 - y_bearing) - else: - context.move_to(x, y) + + if hcenter: + x = x - width*hcenter - x_bearing + + if vcenter: + y = y - height*vcenter - y_bearing + + context.move_to(x, y) context.show_text(text) context.restore() +def help(): + sys.stdout.write("""systemd-analyze blame +systemd-analyze plot + +Process systemd profiling information + + -h --help Show this help +""") + + bus = dbus.SystemBus() if len(sys.argv) <= 1 or sys.argv[1] == 'blame': @@ -79,14 +96,26 @@ elif sys.argv[1] == 'plot': data = acquire_time_data() s = sorted(data, key = lambda i: i[1]) - # 1000px = 10s, 1px = 10ms - border = 100 - width = (finish_time - start_time)/10000 + border*2 - height = 3000 + count = 0 + for name, ixt, aet, axt, iet in s: + + if (ixt >= start_time and ixt <= finish_time) or \ + (aet >= start_time and aet <= finish_time) or \ + (axt >= start_time and axt <= finish_time): + count += 1 + + border = 100 bar_height = 20 bar_space = bar_height * 0.1 + # 1000px = 10s, 1px = 10ms + width = (finish_time - start_time)/10000 + border*2 + height = count * (bar_height + bar_space) + border * 2 + + if width < 1000: + width = 1000 + surface = cairo.SVGSurface(sys.stdout, width, height) context = cairo.Context(surface) @@ -112,7 +141,7 @@ elif sys.argv[1] == 'plot': context.restore() for x in range(0, (finish_time - start_time)/10000, 100): - draw_text(context, x, -5, "%lus" % (x/100), center = False) + draw_text(context, x, -5, "%lus" % (x/100), vcenter = 0, hcenter = 0) y = 0 @@ -121,33 +150,36 @@ elif sys.argv[1] == 'plot': drawn = False left = -1 - if ixt >= start_time and aet > ixt: + if ixt >= start_time and ixt <= finish_time: # Activating a = ixt - start_time - b = aet - ixt + b = min(filter(lambda x: x >= ixt, (aet, axt, iet, finish_time))) - ixt + draw_box(context, a/10000, y, b/10000, bar_height, 1, 0, 0) drawn = True if left < 0: left = a - if aet >= start_time and axt > aet: + if aet >= start_time and aet <= finish_time: # Active a = aet - start_time - b = axt - aet - draw_box(context, a/10000, y, b/10000, bar_height, .7, .5, .5) + b = min(filter(lambda x: x >= aet, (axt, iet, finish_time))) - aet + + draw_box(context, a/10000, y, b/10000, bar_height, .8, .6, .6) drawn = True if left < 0: left = a - if axt >= start_time and iet > axt: + if axt >= start_time and axt <= finish_time: # Deactivating a = axt - start_time - b = iet - axt + b = min(filter(lambda x: x >= axt, (iet, finish_time))) - axt + draw_box(context, a/10000, y, b/10000, bar_height, .6, .4, .4) drawn = True @@ -155,11 +187,20 @@ elif sys.argv[1] == 'plot': left = a if drawn: - draw_text(context, left/10000 + 10, y + bar_height/2, name) + x = left/10000 + + if x < width/2-border: + draw_text(context, x + 10, y + bar_height/2, name, hcenter = 0) + else: + draw_text(context, x - 10, y + bar_height/2, name, hcenter = 1) y += bar_height + bar_space - surface.finish() + draw_text(context, 0, height-border*2, "Legend: Red = Activating; Pink = Active; Dark Pink = Deactivating", hcenter = 0, vcenter = -1) + surface.finish() +elif sys.argv[1] in ("help", "--help", "-h"): + help() else: sys.stderr.write("Unknown verb '%s'.\n" % sys.argv[1]) + sys.exit(1) From f695b3b09b672c327c5b525ed7a2390c4b99a67e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 03:25:30 +0200 Subject: [PATCH 143/200] build-sys: install systemd-analyze by default --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 130e76c45..bc713fc21 100644 --- a/Makefile.am +++ b/Makefile.am @@ -114,6 +114,9 @@ bin_PROGRAMS = \ systemd-stdio-bridge \ systemd-nspawn +dist_bin_SCRIPTS = \ + src/systemd-analyze + if HAVE_GTK bin_PROGRAMS += \ systemadm \ From 9408a2d295a312a5472345090e28e0502570494b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 04:26:40 +0200 Subject: [PATCH 144/200] plymouth: use PID file to detect whether ply is running --- TODO | 4 ++++ src/util.c | 2 +- units/plymouth-start.service | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 215a73601..803c6a8ec 100644 --- a/TODO +++ b/TODO @@ -33,6 +33,10 @@ F15: * selinux issue http://people.gnome.org/~cosimoc/selinux.jpg +* do not print errors when random seed is not around + +* fix alsa mixer restore to not print error when no config is stored + Features: * Find a way to replace /var/run, /var/lock directories with diff --git a/src/util.c b/src/util.c index 5e101e441..a44fea09c 100644 --- a/src/util.c +++ b/src/util.c @@ -4189,7 +4189,7 @@ bool nulstr_contains(const char*nulstr, const char *needle) { } bool plymouth_running(void) { - return access("/run/initramfs/plymouth", F_OK) >= 0; + return access("/run/plymouth/pid", F_OK) >= 0; } static const char *const ioprio_class_table[] = { diff --git a/units/plymouth-start.service b/units/plymouth-start.service index 6ab51f32a..10d03c6c6 100644 --- a/units/plymouth-start.service +++ b/units/plymouth-start.service @@ -13,9 +13,9 @@ After=systemd-vconsole-setup.service udev-settle.service Before=systemd-ask-password-plymouth.service # Dracut informs us with this flag file if plymouth is already running -ConditionPathExists=!/run/initramfs/plymouth +ConditionPathExists=!/run/plymouth/pid [Service] -ExecStart=/sbin/plymouthd --mode=boot +ExecStart=/sbin/plymouthd --mode=boot --pid-file=/run/plymouth/pid ExecStartPost=-/bin/plymouth --show-splash Type=forking From ba1a55152c50dfbcd3d4a64353b95f4a2f37985e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 04:40:02 +0200 Subject: [PATCH 145/200] random: do not print warning if random seed doesn't exist yet --- TODO | 22 +++++++++------------- src/random-seed.c | 8 +++++--- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 803c6a8ec..aa4c37f3c 100644 --- a/TODO +++ b/TODO @@ -10,8 +10,6 @@ F15: * hook emergency.target into local-fs.target in some way as OnFailure with isolate -* teach dbus to activate all services it finds in /etc/systemd/services/org-*.service - * save/restore tool for SysV as requested by FPC (PENDING) * bind mounts are ignored @@ -21,24 +19,22 @@ F15: * NM should pull in network.target, ntpd should pull in rtc-set.target. -* document default dependencies - * kernel patch wegen kmsg prio nach f15 -* LOG_DAEMON/LOG_USER für kmsg messages schreiben - -* disable /dev/console status messages after plymouth went down - -* plymouth pid file - * selinux issue http://people.gnome.org/~cosimoc/selinux.jpg -* do not print errors when random seed is not around - * fix alsa mixer restore to not print error when no config is stored +* ply should do mkdir before writing pid file + Features: +* teach dbus to activate all services it finds in /etc/systemd/services/org-*.service + +* document default dependencies + +* LOG_DAEMON/LOG_USER für kmsg messages schreiben + * Find a way to replace /var/run, /var/lock directories with symlinks during an RPM package upgrade (filesystem.rpm or systemd.rpm). We soon want to get rid of var-run.mount var-lock.mount units. @@ -118,7 +114,7 @@ Features: * Patch systemd-fsck to use -C and pass console fd to it -* support remote/ssh systemctl/systemadm, and local privileged access +* support remote/ssh systemctl/systemadm, and local privileged access → dbus patches need to be merged * configurable jitter for timer events diff --git a/src/random-seed.c b/src/random-seed.c index 8eab2b4e1..054233e66 100644 --- a/src/random-seed.c +++ b/src/random-seed.c @@ -86,9 +86,11 @@ int main(int argc, char *argv[]) { } } - if ((r = loop_read(seed_fd, buf, buf_size, false)) <= 0) - log_error("Failed to read seed file: %s", r < 0 ? strerror(errno) : "EOF"); - else { + if ((r = loop_read(seed_fd, buf, buf_size, false)) <= 0) { + + if (r != 0) + log_error("Failed to read seed file: %m"); + } else { lseek(seed_fd, 0, SEEK_SET); if ((r = loop_write(random_fd, buf, (size_t) r, false)) <= 0) From da19d5c19f60ec80e1733b1e994311c59c6eda73 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 15:35:40 +0200 Subject: [PATCH 146/200] src: our lord is coverity --- TODO | 2 ++ src/condition.c | 4 +++- src/dbus-manager.c | 8 +++++--- src/dbus-unit.c | 4 ++-- src/dbus.c | 6 +++--- src/execute.c | 2 +- src/manager.c | 2 +- src/modules-load.c | 8 ++++++-- src/mount.c | 1 + src/readahead-replay.c | 3 ++- src/service.c | 5 +++-- src/shutdownd.c | 2 +- src/socket.c | 2 ++ src/strv.c | 6 +++++- src/swap.c | 1 + src/unit.c | 3 +-- src/util.c | 1 - 17 files changed, 39 insertions(+), 21 deletions(-) diff --git a/TODO b/TODO index aa4c37f3c..c8e964a68 100644 --- a/TODO +++ b/TODO @@ -27,6 +27,8 @@ F15: * ply should do mkdir before writing pid file +* ConditionDirectoryNotEmpty= needs to be documented + Features: * teach dbus to activate all services it finds in /etc/systemd/services/org-*.service diff --git a/src/condition.c b/src/condition.c index 61812c257..b404b49c9 100644 --- a/src/condition.c +++ b/src/condition.c @@ -30,7 +30,9 @@ Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) { Condition *c; - c = new0(Condition, 1); + if (!(c = new0(Condition, 1))) + return NULL; + c->type = type; c->trigger = trigger; c->negate = negate; diff --git a/src/dbus-manager.c b/src/dbus-manager.c index 92a602219..2f755bcc6 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -1020,8 +1020,10 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, if (!e) goto oom; - if (!(reply = dbus_message_new_method_return(message))) + if (!(reply = dbus_message_new_method_return(message))) { + strv_free(e); goto oom; + } strv_free(m->environment); m->environment = e; @@ -1108,8 +1110,6 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, goto oom; } - free(path); - if (reply) { if (!dbus_connection_send(connection, reply, NULL)) goto oom; @@ -1117,6 +1117,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, dbus_message_unref(reply); } + free(path); + return DBUS_HANDLER_RESULT_HANDLED; oom: diff --git a/src/dbus-unit.c b/src/dbus-unit.c index 563ef7079..b5daa66b5 100644 --- a/src/dbus-unit.c +++ b/src/dbus-unit.c @@ -455,8 +455,6 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn goto oom; } - free(path); - if (reply) { if (!dbus_connection_send(connection, reply, NULL)) goto oom; @@ -464,6 +462,8 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn dbus_message_unref(reply); } + free(path); + return DBUS_HANDLER_RESULT_HANDLED; oom: diff --git a/src/dbus.c b/src/dbus.c index 31b1ce6ee..6f43c4108 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -176,8 +176,8 @@ static dbus_bool_t bus_add_watch(DBusWatch *bus_watch, void *data) { } if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) { - free(w); close_nointr_nofail(w->fd); + free(w); return FALSE; } @@ -236,7 +236,7 @@ static int bus_timeout_arm(Manager *m, Watch *w) { if (dbus_timeout_get_enabled(w->data.bus_timeout)) { timespec_store(&its.it_value, dbus_timeout_get_interval(w->data.bus_timeout) * USEC_PER_MSEC); - its.it_interval = its.it_interval; + its.it_interval = its.it_value; } if (timerfd_settime(w->fd, 0, &its, NULL) < 0) @@ -269,7 +269,7 @@ static dbus_bool_t bus_add_timeout(DBusTimeout *timeout, void *data) { if (!(w = new0(Watch, 1))) return FALSE; - if (!(w->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) + if ((w->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) goto fail; w->type = WATCH_DBUS_TIMEOUT; diff --git a/src/execute.c b/src/execute.c index cd44640a5..b7ae52269 100644 --- a/src/execute.c +++ b/src/execute.c @@ -646,7 +646,7 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_ char **i; /* Final step, initialize any manually set supplementary groups */ - ngroups_max = (int) sysconf(_SC_NGROUPS_MAX); + assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0); if (!(gids = new(gid_t, ngroups_max))) return -ENOMEM; diff --git a/src/manager.c b/src/manager.c index fdb5beda2..dae746cae 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2615,7 +2615,7 @@ int manager_open_serialization(Manager *m, FILE **_f) { log_debug("Serializing state to %s", path); free(path); - if (!(f = fdopen(fd, "w+")) < 0) + if (!(f = fdopen(fd, "w+"))) return -errno; *_f = f; diff --git a/src/modules-load.c b/src/modules-load.c index 2dd432695..3824b57de 100644 --- a/src/modules-load.c +++ b/src/modules-load.c @@ -99,17 +99,21 @@ int main(int argc, char *argv[]) { } f = fopen(fn, "re"); - free(fn); if (!f) { - if (errno == ENOENT) + if (errno == ENOENT) { + free(fn); continue; + } log_error("Failed to open %s: %m", fn); + free(fn); r = EXIT_FAILURE; continue; } + free(fn); + for (;;) { char line[LINE_MAX], *l, *t; diff --git a/src/mount.c b/src/mount.c index 209e19c17..2d8542d9d 100644 --- a/src/mount.c +++ b/src/mount.c @@ -785,6 +785,7 @@ static void mount_enter_signal(Mount *m, MountState state, bool success) { wait_for_exit = true; set_free(pid_set); + pid_set = NULL; } } diff --git a/src/readahead-replay.c b/src/readahead-replay.c index fee2171dd..0b84528b0 100644 --- a/src/readahead-replay.c +++ b/src/readahead-replay.c @@ -122,7 +122,8 @@ static int replay(const char *root) { FILE *pack = NULL; char line[LINE_MAX]; int r = 0; - char *pack_fn = NULL, c; + char *pack_fn = NULL; + int c; bool on_ssd, ready = false; int prio; int inotify_fd = -1; diff --git a/src/service.c b/src/service.c index c74e8a009..728ca0b01 100644 --- a/src/service.c +++ b/src/service.c @@ -406,7 +406,7 @@ static int sysv_fix_order(Service *s) { /* FIXME: Maybe we should compare the name here lexicographically? */ - if (!(r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) + if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) return r; } @@ -1024,7 +1024,7 @@ static int fsck_fix_order(Service *s) { else continue; - if (!(r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) + if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) return r; } @@ -1882,6 +1882,7 @@ static void service_enter_signal(Service *s, ServiceState state, bool success) { wait_for_exit = true; set_free(pid_set); + pid_set = NULL; } } diff --git a/src/shutdownd.c b/src/shutdownd.c index 143fa8d82..6b92ceeb1 100644 --- a/src/shutdownd.c +++ b/src/shutdownd.c @@ -227,7 +227,7 @@ int main(int argc, char *argv[]) { if ((pollfd[i].fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) { log_error("timerfd_create(): %m"); - failed = false; + failed = true; } } diff --git a/src/socket.c b/src/socket.c index 72be0e223..beb328657 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1066,6 +1066,7 @@ static void socket_enter_signal(Socket *s, SocketState state, bool success) { wait_for_exit = true; set_free(pid_set); + pid_set = NULL; } } @@ -1695,6 +1696,7 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) { case SOCKET_START_PRE: log_warning("%s starting timed out. Terminating.", u->meta.id); socket_enter_signal(s, SOCKET_FINAL_SIGTERM, false); + break; case SOCKET_START_POST: log_warning("%s starting timed out. Stopping.", u->meta.id); diff --git a/src/strv.c b/src/strv.c index c8ff5745e..c5f8df06d 100644 --- a/src/strv.c +++ b/src/strv.c @@ -78,9 +78,11 @@ char **strv_copy(char **l) { return r; fail: - for (k--, l--; k >= r; k--, l--) + for (k--; k >= r; k--) free(*k); + free(r); + return NULL; } @@ -435,6 +437,8 @@ char **strv_env_merge(unsigned n_lists, ...) { return r; fail: + va_end(ap); + for (k--; k >= r; k--) free(*k); diff --git a/src/swap.c b/src/swap.c index 66bf5c2bf..c32f60810 100644 --- a/src/swap.c +++ b/src/swap.c @@ -687,6 +687,7 @@ static void swap_enter_signal(Swap *s, SwapState state, bool success) { wait_for_exit = true; set_free(pid_set); + pid_set = NULL; } } diff --git a/src/unit.c b/src/unit.c index 4f83778c5..6fd4dc6cb 100644 --- a/src/unit.c +++ b/src/unit.c @@ -2035,8 +2035,7 @@ char **unit_full_printf_strv(Unit *u, char **l) { return r; fail: - j--; - while (j >= r) + for (j--; j >= r; j--) free(*j); free(r); diff --git a/src/util.c b/src/util.c index a44fea09c..5a5cdceab 100644 --- a/src/util.c +++ b/src/util.c @@ -3582,7 +3582,6 @@ char *normalize_env_assignment(const char *s) { free(p); if (!value) { - free(p); free(name); return NULL; } From 7ebdfc936e7c9697b9fa9441a502ad40abb7b245 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 18:17:29 +0200 Subject: [PATCH 147/200] build-sys: create a number of drop-in config dirs --- Makefile.am | 7 +++++++ TODO | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/Makefile.am b/Makefile.am index bc713fc21..f6d344569 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1229,6 +1229,13 @@ CLEANFILES += \ $(dbusinterface_DATA) install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(sysconfdir)/modules-load.d \ + $(DESTDIR)$(tmpfilesdir) \ + $(DESTDIR)$(sysconfdir)/sysctl.d \ + $(DESTDIR)$(systemshutdowndir) \ + $(DESTDIR)$(systemgeneratordir) \ + $(DESTDIR)$(usergeneratordir) $(MKDIR_P) -m 0755 \ $(DESTDIR)$(systemunitdir) \ $(DESTDIR)$(userunitdir) \ diff --git a/TODO b/TODO index c8e964a68..1152927ca 100644 --- a/TODO +++ b/TODO @@ -29,8 +29,13 @@ F15: * ConditionDirectoryNotEmpty= needs to be documented +* add /etc/modules-load.d to rpm + Features: +* tmpfiles should allow two identical lines + https://bugzilla.redhat.com/show_bug.cgi?id=690253 + * teach dbus to activate all services it finds in /etc/systemd/services/org-*.service * document default dependencies From 7602c46fe6c48792b5eb4d157233066c68be9c9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 18:19:59 +0200 Subject: [PATCH 148/200] man: uinput.ko is a bad example --- man/modules-load.d.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/modules-load.d.xml b/man/modules-load.d.xml index 77a286055..31ffd74bb 100644 --- a/man/modules-load.d.xml +++ b/man/modules-load.d.xml @@ -77,10 +77,10 @@ Example - /etc/modules-load.d/uinput.conf example: + /etc/modules-load.d/virtio-net.conf example: - # Load uinput.ko at boot -uinput + # Load virtio-net.ko at boot +virtio-net From 29db583471f019ed9939a90966b3e194a9560e7e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 19:49:04 +0200 Subject: [PATCH 149/200] log: don't strip facility when writing to kmsg --- TODO | 10 ---------- src/log.c | 8 ++++++-- src/logger.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index 1152927ca..c1cdf1c6c 100644 --- a/TODO +++ b/TODO @@ -19,18 +19,10 @@ F15: * NM should pull in network.target, ntpd should pull in rtc-set.target. -* kernel patch wegen kmsg prio nach f15 - -* selinux issue http://people.gnome.org/~cosimoc/selinux.jpg - * fix alsa mixer restore to not print error when no config is stored -* ply should do mkdir before writing pid file - * ConditionDirectoryNotEmpty= needs to be documented -* add /etc/modules-load.d to rpm - Features: * tmpfiles should allow two identical lines @@ -40,8 +32,6 @@ Features: * document default dependencies -* LOG_DAEMON/LOG_USER für kmsg messages schreiben - * Find a way to replace /var/run, /var/lock directories with symlinks during an RPM package upgrade (filesystem.rpm or systemd.rpm). We soon want to get rid of var-run.mount var-lock.mount units. diff --git a/src/log.c b/src/log.c index b6d4bf9c1..4ec6b7388 100644 --- a/src/log.c +++ b/src/log.c @@ -289,7 +289,7 @@ static int write_to_syslog( if (syslog_fd < 0) return 0; - snprintf(header_priority, sizeof(header_priority), "<%i>", LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(level))); + snprintf(header_priority, sizeof(header_priority), "<%i>", level); char_array_0(header_priority); t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC); @@ -346,7 +346,7 @@ static int write_to_kmsg( if (kmsg_fd < 0) return 0; - snprintf(header_priority, sizeof(header_priority), "<%i>", LOG_PRI(level)); + snprintf(header_priority, sizeof(header_priority), "<%i>", level); char_array_0(header_priority); snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid()); @@ -377,6 +377,10 @@ static int log_dispatch( if (log_target == LOG_TARGET_NULL) return 0; + /* Patch in LOG_DAEMON facility if necessary */ + if (LOG_FAC(level) == 0) + level = LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(level)); + do { char *e; int k = 0; diff --git a/src/logger.c b/src/logger.c index 104d7c385..710dfed33 100644 --- a/src/logger.c +++ b/src/logger.c @@ -93,6 +93,42 @@ struct Stream { LIST_FIELDS(Stream, stream); }; +static void parse_priority(char **p, int *priority) { + int a = 0, b = 0, c = 0; + int k; + + assert(p); + assert(*p); + assert(priority); + + if ((*p)[0] != '<') + return; + + if (!strchr(*p, '>')) + return; + + if ((*p)[2] == '>') { + c = undecchar((*p)[1]); + k = 3; + } else if ((*p)[3] == '>') { + b = undecchar((*p)[1]); + c = undecchar((*p)[2]); + k = 4; + } else if ((*p)[4] == '>') { + a = undecchar((*p)[1]); + b = undecchar((*p)[2]); + c = undecchar((*p)[3]); + k = 5; + } else + return; + + if (a < 0 || b < 0 || c < 0) + return; + + *priority = a*100+b*10+c; + *p += k; +} + static int stream_log(Stream *s, char *p, usec_t ts) { char header_priority[16], header_time[64], header_pid[16]; @@ -104,6 +140,9 @@ static int stream_log(Stream *s, char *p, usec_t ts) { priority = s->priority; + if (s->prefix) + parse_priority(&p, &priority); + if (s->prefix && p[0] == '<' && p[1] >= '0' && p[1] <= '7' && @@ -118,6 +157,10 @@ static int stream_log(Stream *s, char *p, usec_t ts) { if (*p == 0) return 0; + /* Patch in LOG_USER facility if necessary */ + if (LOG_FAC(priority) == 0) + priority = LOG_MAKEPRI(LOG_USER, LOG_PRI(priority)); + /* * The format glibc uses to talk to the syslog daemon is: * @@ -130,8 +173,7 @@ static int stream_log(Stream *s, char *p, usec_t ts) { * We extend the latter to include the process name and pid. */ - snprintf(header_priority, sizeof(header_priority), "<%i>", - s->target == STREAM_SYSLOG ? priority : LOG_PRI(priority)); + snprintf(header_priority, sizeof(header_priority), "<%i>", priority); char_array_0(header_priority); if (s->target == STREAM_SYSLOG) { From 7d76f312889d54dcfe6fdde6eb055e890e7a615b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 21:22:44 +0200 Subject: [PATCH 150/200] log: fix shifting of facilities --- TODO | 2 ++ src/execute.c | 2 +- src/load-fragment.c | 6 +++--- src/log.c | 4 ++-- src/logger.c | 15 ++------------- src/util.c | 4 ++-- src/util.h | 4 ++-- 7 files changed, 14 insertions(+), 23 deletions(-) diff --git a/TODO b/TODO index c1cdf1c6c..c5222baaf 100644 --- a/TODO +++ b/TODO @@ -19,6 +19,8 @@ F15: * NM should pull in network.target, ntpd should pull in rtc-set.target. +* bluetooth should be possible to disable + * fix alsa mixer restore to not print error when no config is stored * ConditionDirectoryNotEmpty= needs to be documented diff --git a/src/execute.c b/src/execute.c index b7ae52269..80c649f1c 100644 --- a/src/execute.c +++ b/src/execute.c @@ -1650,7 +1650,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { fprintf(f, "%sSyslogFacility: %s\n" "%sSyslogLevel: %s\n", - prefix, log_facility_to_string(LOG_FAC(c->syslog_priority)), + prefix, log_facility_unshifted_to_string(c->syslog_priority >> 3), prefix, log_level_to_string(LOG_PRI(c->syslog_priority))); if (c->capabilities) { diff --git a/src/load-fragment.c b/src/load-fragment.c index 343525665..05d858e86 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -584,12 +584,12 @@ static int config_parse_facility( assert(rvalue); assert(data); - if ((x = log_facility_from_string(rvalue)) < 0) { + if ((x = log_facility_unshifted_from_string(rvalue)) < 0) { log_error("[%s:%u] Failed to parse log facility, ignoring: %s", filename, line, rvalue); return 0; } - *o = LOG_MAKEPRI(x, LOG_PRI(*o)); + *o = (x << 3) | LOG_PRI(*o); return 0; } @@ -617,7 +617,7 @@ static int config_parse_level( return 0; } - *o = LOG_MAKEPRI(LOG_FAC(*o), x); + *o = (*o & LOG_FACMASK) | x; return 0; } diff --git a/src/log.c b/src/log.c index 4ec6b7388..95c27656b 100644 --- a/src/log.c +++ b/src/log.c @@ -378,8 +378,8 @@ static int log_dispatch( return 0; /* Patch in LOG_DAEMON facility if necessary */ - if (LOG_FAC(level) == 0) - level = LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(level)); + if ((level & LOG_FACMASK) == 0) + level = LOG_DAEMON | LOG_PRI(level); do { char *e; diff --git a/src/logger.c b/src/logger.c index 710dfed33..eb62688f4 100644 --- a/src/logger.c +++ b/src/logger.c @@ -143,23 +143,12 @@ static int stream_log(Stream *s, char *p, usec_t ts) { if (s->prefix) parse_priority(&p, &priority); - if (s->prefix && - p[0] == '<' && - p[1] >= '0' && p[1] <= '7' && - p[2] == '>') { - - /* Detected priority prefix */ - priority = LOG_MAKEPRI(LOG_FAC(priority), (p[1] - '0')); - - p += 3; - } - if (*p == 0) return 0; /* Patch in LOG_USER facility if necessary */ - if (LOG_FAC(priority) == 0) - priority = LOG_MAKEPRI(LOG_USER, LOG_PRI(priority)); + if ((priority & LOG_FACMASK) == 0) + priority = LOG_USER | LOG_PRI(priority); /* * The format glibc uses to talk to the syslog daemon is: diff --git a/src/util.c b/src/util.c index 5a5cdceab..2a5f3074b 100644 --- a/src/util.c +++ b/src/util.c @@ -4211,7 +4211,7 @@ static const char *const sigchld_code_table[] = { DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int); -static const char *const log_facility_table[LOG_NFACILITIES] = { +static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = { [LOG_FAC(LOG_KERN)] = "kern", [LOG_FAC(LOG_USER)] = "user", [LOG_FAC(LOG_MAIL)] = "mail", @@ -4234,7 +4234,7 @@ static const char *const log_facility_table[LOG_NFACILITIES] = { [LOG_FAC(LOG_LOCAL7)] = "local7" }; -DEFINE_STRING_TABLE_LOOKUP(log_facility, int); +DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int); static const char *const log_level_table[] = { [LOG_EMERG] = "emerg", diff --git a/src/util.h b/src/util.h index dfbfa8b04..cc63dd1a8 100644 --- a/src/util.h +++ b/src/util.h @@ -406,8 +406,8 @@ int ioprio_class_from_string(const char *s); const char *sigchld_code_to_string(int i); int sigchld_code_from_string(const char *s); -const char *log_facility_to_string(int i); -int log_facility_from_string(const char *s); +const char *log_facility_unshifted_to_string(int i); +int log_facility_unshifted_from_string(const char *s); const char *log_level_to_string(int i); int log_level_from_string(const char *s); From 43515ba0cecda2be8244a9f75078ac4a561092d9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Mar 2011 21:40:10 +0200 Subject: [PATCH 151/200] mount: also relabel pre-mounted API dirs --- src/mount-setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mount-setup.c b/src/mount-setup.c index 056e4a1c6..49eab0bfa 100644 --- a/src/mount-setup.c +++ b/src/mount-setup.c @@ -101,7 +101,7 @@ static int mount_one(const MountPoint *p) { return r; if (r > 0) - return 0; + goto finish; /* The access mode here doesn't really matter too much, since * the mounted file system will take precedence anyway. */ @@ -122,6 +122,7 @@ static int mount_one(const MountPoint *p) { return p->fatal ? -errno : 0; } +finish: label_fix(p->where, false); return 0; From c61e77d3eab2385fc7bbae0edef6b3c583a70ca8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 1 Apr 2011 00:42:57 +0200 Subject: [PATCH 152/200] man: document ConditionPathIsDirectory= --- TODO | 2 -- man/systemd.unit.xml | 10 ++++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index c5222baaf..651e646d3 100644 --- a/TODO +++ b/TODO @@ -23,8 +23,6 @@ F15: * fix alsa mixer restore to not print error when no config is stored -* ConditionDirectoryNotEmpty= needs to be documented - Features: * tmpfiles should allow two identical lines diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index d447c3a0a..47ddece31 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -561,6 +561,7 @@ ConditionPathExists= + ConditionPathIsDirectory= ConditionDirectoryNotEmpty= ConditionKernelCommandLine= ConditionVirtualization= @@ -584,10 +585,15 @@ is prefixed with an exclamation mark (!), the test is negated, and the unit only started if the path does not - exist. ConditionDirectoryNotEmpty= + exist. ConditionPathIsDirectory= is similar to ConditionPathExists= - but verifies whether a certain path is + but verifies whether a certain path + exists and is a directory. + ConditionDirectoryNotEmpty= + is similar to + ConditionPathExists= + but verifies whether a certain path exists and is a non-empty directory. Similarly ConditionKernelCommandLine= From e1ab991283ca1072d29e21d8af76e992b663ad9b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 1 Apr 2011 00:43:28 +0200 Subject: [PATCH 153/200] tmpfiles: enforce new /var/lock semantics http://lists.freedesktop.org/archives/systemd-devel/2011-March/001823.html --- tmpfiles.d/systemd.conf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index e77cf7d20..31fd97f0b 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -7,10 +7,13 @@ # See tmpfiles.d(5) for details -d /run/lock 0775 root lock - +d /run/lock 0755 root root - d /run/lock/subsys 0755 root root - +d /run/lock/lockdev 0775 root lock - + d /run/user 0755 root root 10d F /run/utmp 0664 root utmp - + f /var/log/wtmp 0664 root utmp - f /var/log/btmp 0600 root utmp - From a9f470b802f95e6bf42e19ed300dfde63204797d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 1 Apr 2011 01:35:27 +0200 Subject: [PATCH 154/200] build-sys: bump version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 73764712f..58493511f 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.63) -AC_INIT([systemd],[21],[systemd-devel@lists.freedesktop.org]) +AC_INIT([systemd],[22],[systemd-devel@lists.freedesktop.org]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) From bb29785e0df6a7cf07db0259a60bc1f3b4814cb4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 1 Apr 2011 15:25:46 +0200 Subject: [PATCH 155/200] general: replace a few uses of /var/run by /run --- Makefile.am | 2 +- man/pam_systemd.xml | 2 +- man/systemd.xml | 31 ++++++++++++++----------------- man/tmpfiles.d.xml | 4 ++-- src/gnome-ask-password-agent.vala | 2 +- src/pam-module.c | 11 +++++------ src/tmpfiles.c | 2 +- 7 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Makefile.am b/Makefile.am index f6d344569..7f8e22a6a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,7 +59,7 @@ AM_CPPFLAGS = \ -DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \ -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \ -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ - -DRUNTIME_DIR=\"$(localstatedir)/run\" \ + -DRUNTIME_DIR=\"/run\" \ -DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \ -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \ -DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \ diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index 43d239f49..11852eb02 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -65,7 +65,7 @@ If it does not exist yet, the user runtime directory - /var/run/user/$USER is + /run/user/$USER is created and its ownership changed to the user that is logging in. diff --git a/man/systemd.xml b/man/systemd.xml index 5a4c4ab9c..a7dc4530e 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -1024,20 +1024,19 @@ - /var/run/systemd/notify + /run/systemd/notify Daemon status - notification socket. This is an AF_UNIX - datagram socket in the Linux abstract - namespace, and is used to implement - the daemon notification logic as - implemented by + notification socket. This is an + AF_UNIX datagram socket and is used to + implement the daemon notification + logic as implemented by sd_notify3. - /var/run/systemd/logger + /run/systemd/logger Used internally by the systemd-logger.service @@ -1045,32 +1044,30 @@ of spawned processes to syslog3 or the kernel log buffer. This is an - AF_UNIX stream socket in the Linux - abstract namespace. + AF_UNIX stream + socket. - /var/run/systemd/shutdownd + /run/systemd/shutdownd Used internally by the shutdown8 tool to implement delayed shutdowns. This is an AF_UNIX datagram - socket in the Linux abstract - namespace. + socket. - /var/run/systemd/private + /run/systemd/private Used internally as communication channel between systemctl1 and the systemd process. This is an - AF_UNIX stream socket in the Linux - abstract namespace. This interface is - private to systemd and should not be - used in external + AF_UNIX stream socket. This interface + is private to systemd and should not + be used in external projects. diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 868b57e93..8568fcd59 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -58,7 +58,7 @@ /etc/tmpfiles.d/ to describe the creation, cleaning and removal of volatile and temporary files and directories which usually reside - in directories such as /var/run + in directories such as /run or /tmp. Each configuration file is named in the style of /etc/tmpfiles.d/<program>.conf. @@ -72,7 +72,7 @@ fields: Type Path Mode UID GID Age -d /var/run/user 0755 root root 10d +d /run/user 0755 root root 10d Type diff --git a/src/gnome-ask-password-agent.vala b/src/gnome-ask-password-agent.vala index 4f89a3e6d..2bfc6a9c8 100644 --- a/src/gnome-ask-password-agent.vala +++ b/src/gnome-ask-password-agent.vala @@ -91,7 +91,7 @@ public class MyStatusIcon : StatusIcon { GLib.Object(icon_name : "dialog-password"); set_title("System Password Request"); - directory = File.new_for_path("/var/run/systemd/ask-password/"); + directory = File.new_for_path("/run/systemd/ask-password/"); file_monitor = directory.monitor_directory(0); file_monitor.changed.connect(file_monitor_changed); diff --git a/src/pam-module.c b/src/pam-module.c index 3a5404db4..6486546e6 100644 --- a/src/pam-module.c +++ b/src/pam-module.c @@ -239,11 +239,10 @@ static uint64_t get_session_id(int *mode) { ssize_t r; /* We do a bit of endianess swapping here, just to be - * sure. /var should be machine specific anyway, and - * /var/run even mounted from tmpfs, so this - * byteswapping should really not be necessary. But - * then again, you never know, so let's avoid any - * risk. */ + * sure. /run should be machine specific anyway, and + * even mounted from tmpfs, so this byteswapping + * should really not be necessary. But then again, you + * never know, so let's avoid any risk. */ if (loop_read(fd, &counter, sizeof(counter), false) != sizeof(counter)) counter = 1; @@ -435,7 +434,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( goto finish; } - /* Create /var/run/$USER */ + /* Create /run/user/$USER */ free(buf); if (asprintf(&buf, RUNTIME_DIR "/user/%s", username) < 0) { r = PAM_BUF_ERR; diff --git a/src/tmpfiles.c b/src/tmpfiles.c index 68af37aab..e92b1123c 100644 --- a/src/tmpfiles.c +++ b/src/tmpfiles.c @@ -47,7 +47,7 @@ /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates * them in the file system. This is intended to be used to create - * properly owned directories beneath /tmp, /var/tmp, /var/run and + * properly owned directories beneath /tmp, /var/tmp, /run and * /var/lock which are volatile and hence need to be recreated on * bootup. */ From cca4aeeead1985f503d175eb1fcad9ed66f2e25d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 2 Apr 2011 01:08:31 +0200 Subject: [PATCH 156/200] tmpfiles: split off rules for legacy systems into legacy.conf --- Makefile.am | 5 +++++ TODO | 2 ++ configure.ac | 1 + tmpfiles.d/legacy.conf | 21 +++++++++++++++++++++ tmpfiles.d/systemd.conf | 3 --- 5 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 tmpfiles.d/legacy.conf diff --git a/Makefile.am b/Makefile.am index 7f8e22a6a..12118b1cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -207,6 +207,11 @@ dist_tmpfiles_DATA = \ tmpfiles.d/systemd.conf \ tmpfiles.d/x11.conf +if HAVE_SYSV_COMPAT +dist_tmpfiles_DATA += \ + tmpfiles.d/legacy.conf +endif + dist_systemunit_DATA = \ units/graphical.target \ units/multi-user.target \ diff --git a/TODO b/TODO index 651e646d3..12634744b 100644 --- a/TODO +++ b/TODO @@ -25,6 +25,8 @@ F15: Features: +* take BSD file lock on tty devices when using them? + * tmpfiles should allow two identical lines https://bugzilla.redhat.com/show_bug.cgi?id=690253 diff --git a/configure.ac b/configure.ac index 58493511f..0821e7235 100644 --- a/configure.ac +++ b/configure.ac @@ -411,6 +411,7 @@ AM_CONDITIONAL(TARGET_ALTLINUX, test x"$with_distro" = xaltlinux) AM_CONDITIONAL(TARGET_MANDRIVA, test x"$with_distro" = xmandriva) AM_CONDITIONAL(HAVE_PLYMOUTH, test -n "$have_plymouth") +AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes") AC_ARG_WITH([dbuspolicydir], AS_HELP_STRING([--with-dbuspolicydir=DIR], [D-Bus policy directory]), diff --git a/tmpfiles.d/legacy.conf b/tmpfiles.d/legacy.conf new file mode 100644 index 000000000..fff2779e6 --- /dev/null +++ b/tmpfiles.d/legacy.conf @@ -0,0 +1,21 @@ +# 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 tmpfiles.d(5) for details + +# These files are considered legacy and are unnecessary on legacy-free +# systems. /run/lock/subsys is used for serializing SysV service +# execution, and hence without use on SysV-less systems. +# +# /run/lock/lockdev is used to serialize access to tty devices via +# LCK..xxx style lock files, For more information see: +# http://lists.freedesktop.org/archives/systemd-devel/2011-March/001823.html +# On modern systems a BSD file lock is a better choice if +# serialization is needed on those devices. + +d /run/lock/subsys 0755 root root - +d /run/lock/lockdev 0775 root lock - diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index 31fd97f0b..ab6f20116 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -8,9 +8,6 @@ # See tmpfiles.d(5) for details d /run/lock 0755 root root - -d /run/lock/subsys 0755 root root - -d /run/lock/lockdev 0775 root lock - - d /run/user 0755 root root 10d F /run/utmp 0664 root utmp - From 16b879e3eeb25f7b0d517682a4e8b62f39c149f2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 3 Apr 2011 17:08:46 +0200 Subject: [PATCH 157/200] update TODO --- TODO | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TODO b/TODO index 12634744b..b3d8e1afc 100644 --- a/TODO +++ b/TODO @@ -30,6 +30,11 @@ Features: * tmpfiles should allow two identical lines https://bugzilla.redhat.com/show_bug.cgi?id=690253 +* tmpfiles should create leading directories for d,D,f,F? + +* avoid any flag files, or readahead files in /, we need to support r/o / + or / on tmpfs like Android setups. + * teach dbus to activate all services it finds in /etc/systemd/services/org-*.service * document default dependencies From 5b754353282e3ba3cf9c4ffc50579aff4b7d72db Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 3 Apr 2011 22:09:25 +0200 Subject: [PATCH 158/200] move /var/lock to HAVE_SYSV_COMPAT --- Makefile.am | 45 +++++++++++++++++++++++------------------ tmpfiles.d/legacy.conf | 1 + tmpfiles.d/systemd.conf | 1 - 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Makefile.am b/Makefile.am index 12118b1cc..7bf32aa83 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,7 +58,7 @@ AM_CPPFLAGS = \ -DSYSTEMD_SHUTDOWN_BINARY_PATH=\"$(rootlibexecdir)/systemd-shutdown\" \ -DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \ -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \ - -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ + -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ -DRUNTIME_DIR=\"/run\" \ -DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \ -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \ @@ -112,10 +112,10 @@ rootbin_PROGRAMS = \ bin_PROGRAMS = \ systemd-cgls \ systemd-stdio-bridge \ - systemd-nspawn + systemd-nspawn dist_bin_SCRIPTS = \ - src/systemd-analyze + src/systemd-analyze if HAVE_GTK bin_PROGRAMS += \ @@ -147,7 +147,7 @@ rootlibexec_PROGRAMS = \ systemd-sysctl systemgenerator_PROGRAMS = \ - systemd-getty-generator + systemd-getty-generator if HAVE_LIBCRYPTSETUP rootlibexec_PROGRAMS += \ @@ -201,7 +201,7 @@ dbusinterface_DATA = \ org.freedesktop.systemd1.Path.xml dist_bashcompletion_DATA = \ - src/systemctl-bash-completion.sh + src/systemctl-bash-completion.sh dist_tmpfiles_DATA = \ tmpfiles.d/systemd.conf \ @@ -209,7 +209,7 @@ dist_tmpfiles_DATA = \ if HAVE_SYSV_COMPAT dist_tmpfiles_DATA += \ - tmpfiles.d/legacy.conf + tmpfiles.d/legacy.conf endif dist_systemunit_DATA = \ @@ -253,7 +253,6 @@ dist_systemunit_DATA = \ units/sys-kernel-debug.mount \ units/sys-kernel-security.automount \ units/sys-kernel-security.mount \ - units/var-lock.mount \ units/var-run.mount \ units/media.mount \ units/hwclock-load.service \ @@ -270,10 +269,16 @@ dist_systemunit_DATA = \ units/systemd-ask-password-console.path \ units/syslog.target +if HAVE_SYSV_COMPAT +dist_systemunit_DATA += \ + units/var-lock.mount +endif + + nodist_systemunit_DATA = \ units/getty@.service \ units/serial-getty@.service \ - units/console-shell.service \ + units/console-shell.service \ units/remote-fs.target \ units/systemd-initctl.service \ units/systemd-logger.service \ @@ -315,7 +320,7 @@ nodist_userunit_DATA = \ EXTRA_DIST = \ units/getty@.service.m4 \ units/serial-getty@.service.m4 \ - units/console-shell.service.m4 \ + units/console-shell.service.m4 \ units/remote-fs.target.m4 \ units/rescue.service.m4 \ units/systemd-initctl.service.in \ @@ -505,7 +510,7 @@ EXTRA_DIST += \ ${libsystemd_core_la_SOURCES:.c=.h} \ ${libsystemd_daemon_la_SOURCES:.c=.h} \ src/macro.h \ - src/def.h \ + src/def.h \ src/ioprio.h \ src/missing.h \ src/list.h \ @@ -1105,8 +1110,8 @@ pam_systemd_la_LIBADD = \ SED_PROCESS = \ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ $(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \ - -e 's,@rootbindir\@,$(rootbindir),g' \ - -e 's,@bindir\@,$(bindir),g' \ + -e 's,@rootbindir\@,$(rootbindir),g' \ + -e 's,@bindir\@,$(bindir),g' \ -e 's,@SYSTEMCTL\@,$(rootbindir)/systemctl,g' \ -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \ -e 's,@pkgsysconfdir\@,$(pkgsysconfdir),g' \ @@ -1235,12 +1240,12 @@ CLEANFILES += \ install-data-hook: $(MKDIR_P) -m 0755 \ - $(DESTDIR)$(sysconfdir)/modules-load.d \ - $(DESTDIR)$(tmpfilesdir) \ - $(DESTDIR)$(sysconfdir)/sysctl.d \ - $(DESTDIR)$(systemshutdowndir) \ - $(DESTDIR)$(systemgeneratordir) \ - $(DESTDIR)$(usergeneratordir) + $(DESTDIR)$(sysconfdir)/modules-load.d \ + $(DESTDIR)$(tmpfilesdir) \ + $(DESTDIR)$(sysconfdir)/sysctl.d \ + $(DESTDIR)$(systemshutdowndir) \ + $(DESTDIR)$(systemgeneratordir) \ + $(DESTDIR)$(usergeneratordir) $(MKDIR_P) -m 0755 \ $(DESTDIR)$(systemunitdir) \ $(DESTDIR)$(userunitdir) \ @@ -1421,7 +1426,7 @@ if TARGET_FEDORA ( cd $(DESTDIR)$(systemunitdir) && \ rm -f display-manager.service single.service && \ $(LN_S) prefdm.service display-manager.service && \ - $(LN_S) rescue.service single.service ) + $(LN_S) rescue.service single.service ) ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ rm -f display-manager.service && \ $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) @@ -1439,7 +1444,7 @@ if TARGET_MANDRIVA rm -f display-manager.service dm.service single.service && \ $(LN_S) prefdm.service display-manager.service && \ $(LN_S) prefdm.service dm.service && \ - $(LN_S) rescue.service single.service ) + $(LN_S) rescue.service single.service ) ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ rm -f display-manager.service && \ $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) diff --git a/tmpfiles.d/legacy.conf b/tmpfiles.d/legacy.conf index fff2779e6..9198e89dd 100644 --- a/tmpfiles.d/legacy.conf +++ b/tmpfiles.d/legacy.conf @@ -17,5 +17,6 @@ # On modern systems a BSD file lock is a better choice if # serialization is needed on those devices. +d /run/lock 0755 root root - d /run/lock/subsys 0755 root root - d /run/lock/lockdev 0775 root lock - diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index ab6f20116..2ab8e2bba 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -7,7 +7,6 @@ # See tmpfiles.d(5) for details -d /run/lock 0755 root root - d /run/user 0755 root root 10d F /run/utmp 0664 root utmp - From 7c3b203c5c69fc37c8d143851cd395cbf8920786 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 3 Apr 2011 22:14:34 +0200 Subject: [PATCH 159/200] kmsg-syslogd: pass facility value into kmsg --- src/kmsg-syslogd.c | 57 +++++++++------------------------------------- src/logger.c | 38 +------------------------------ src/util.c | 36 +++++++++++++++++++++++++++++ src/util.h | 2 ++ 4 files changed, 50 insertions(+), 83 deletions(-) diff --git a/src/kmsg-syslogd.c b/src/kmsg-syslogd.c index c78011fe2..60d3244b3 100644 --- a/src/kmsg-syslogd.c +++ b/src/kmsg-syslogd.c @@ -154,50 +154,6 @@ fail: 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, @@ -334,17 +290,26 @@ static void skip_pid(const char **buf) { static int write_message(Server *s, const char *buf, struct ucred *ucred) { ssize_t k; - char priority[4], pid[16]; + char priority[6], pid[16]; struct iovec iovec[5]; unsigned i = 0; char *process = NULL; int r = 0; + int prio = LOG_USER | LOG_INFO; assert(s); assert(buf); + parse_syslog_priority((char**) &buf, &prio); + + if (*buf == 0) + return 0; + + if ((prio & LOG_FACMASK) == 0) + prio = LOG_USER | LOG_PRI(prio); + /* First, set priority field */ - snprintf(priority, sizeof(priority), "<%i>", read_priority(&buf)); + snprintf(priority, sizeof(priority), "<%i>", prio); char_array_0(priority); IOVEC_SET_STRING(iovec[i++], priority); diff --git a/src/logger.c b/src/logger.c index eb62688f4..faa6c9721 100644 --- a/src/logger.c +++ b/src/logger.c @@ -93,42 +93,6 @@ struct Stream { LIST_FIELDS(Stream, stream); }; -static void parse_priority(char **p, int *priority) { - int a = 0, b = 0, c = 0; - int k; - - assert(p); - assert(*p); - assert(priority); - - if ((*p)[0] != '<') - return; - - if (!strchr(*p, '>')) - return; - - if ((*p)[2] == '>') { - c = undecchar((*p)[1]); - k = 3; - } else if ((*p)[3] == '>') { - b = undecchar((*p)[1]); - c = undecchar((*p)[2]); - k = 4; - } else if ((*p)[4] == '>') { - a = undecchar((*p)[1]); - b = undecchar((*p)[2]); - c = undecchar((*p)[3]); - k = 5; - } else - return; - - if (a < 0 || b < 0 || c < 0) - return; - - *priority = a*100+b*10+c; - *p += k; -} - static int stream_log(Stream *s, char *p, usec_t ts) { char header_priority[16], header_time[64], header_pid[16]; @@ -141,7 +105,7 @@ static int stream_log(Stream *s, char *p, usec_t ts) { priority = s->priority; if (s->prefix) - parse_priority(&p, &priority); + parse_syslog_priority(&p, &priority); if (*p == 0) return 0; diff --git a/src/util.c b/src/util.c index 2a5f3074b..a1686ed38 100644 --- a/src/util.c +++ b/src/util.c @@ -4191,6 +4191,42 @@ bool plymouth_running(void) { return access("/run/plymouth/pid", F_OK) >= 0; } +void parse_syslog_priority(char **p, int *priority) { + int a = 0, b = 0, c = 0; + int k; + + assert(p); + assert(*p); + assert(priority); + + if ((*p)[0] != '<') + return; + + if (!strchr(*p, '>')) + return; + + if ((*p)[2] == '>') { + c = undecchar((*p)[1]); + k = 3; + } else if ((*p)[3] == '>') { + b = undecchar((*p)[1]); + c = undecchar((*p)[2]); + k = 4; + } else if ((*p)[4] == '>') { + a = undecchar((*p)[1]); + b = undecchar((*p)[2]); + c = undecchar((*p)[3]); + k = 5; + } else + return; + + if (a < 0 || b < 0 || c < 0) + return; + + *priority = a*100+b*10+c; + *p += k; +} + 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 cc63dd1a8..ff38b3580 100644 --- a/src/util.h +++ b/src/util.h @@ -394,6 +394,8 @@ bool nulstr_contains(const char*nulstr, const char *needle); bool plymouth_running(void); +void parse_syslog_priority(char **p, int *priority); + #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) From 99ee2e92956b5f31a55172acffea0c2b5745fa81 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 3 Apr 2011 22:14:56 +0200 Subject: [PATCH 160/200] initctl: /dev/initctl is a named pipe, not a socket --- units/systemd-initctl.socket | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/systemd-initctl.socket b/units/systemd-initctl.socket index 403b322c3..7a3a0236e 100644 --- a/units/systemd-initctl.socket +++ b/units/systemd-initctl.socket @@ -8,7 +8,7 @@ # See systemd.special(7) for details [Unit] -Description=/dev/initctl Compatibility Socket +Description=/dev/initctl Compatibility Named Pipe DefaultDependencies=no Before=sockets.target From 8fb81fa7844387377f79cf11d1bf48224a928ba7 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Sun, 3 Apr 2011 18:16:48 +0200 Subject: [PATCH 161/200] condition: fix dumping of conditions Several condition types were missing their strings, they were showing as "(null)" in systemctl dump. Indentation was missing too. --- src/condition.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/condition.c b/src/condition.c index b404b49c9..5ab77d80f 100644 --- a/src/condition.c +++ b/src/condition.c @@ -199,7 +199,7 @@ void condition_dump(Condition *c, FILE *f, const char *prefix) { prefix = ""; fprintf(f, - "%s%s: %s%s%s\n", + "%s\t%s: %s%s%s\n", prefix, condition_type_to_string(c->type), c->trigger ? "|" : "", @@ -215,8 +215,11 @@ 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_IS_DIRECTORY] = "ConditionPathIsDirectory", + [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty", + [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine", + [CONDITION_VIRTUALIZATION] = "ConditionVirtualization", [CONDITION_NULL] = "ConditionNull" }; From 41584525cf0a9d3a8bfb76008a3fc663b86bfdde Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Sun, 3 Apr 2011 18:16:54 +0200 Subject: [PATCH 162/200] load-fragment: unify config_parse_condition_{kernel, virt} They only differ in the condition type, otherwise the code is identical. Replace them with a more generic config_parse_condition_string(). --- src/load-fragment.c | 44 ++++++-------------------------------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/src/load-fragment.c b/src/load-fragment.c index 05d858e86..cb8c25089 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1479,7 +1479,7 @@ static int config_parse_condition_path( return 0; } -static int config_parse_condition_kernel( +static int config_parse_condition_string( const char *filename, unsigned line, const char *section, @@ -1489,6 +1489,7 @@ static int config_parse_condition_kernel( void *data, void *userdata) { + ConditionType cond = ltype; Unit *u = data; bool trigger, negate; Condition *c; @@ -1504,39 +1505,7 @@ static int config_parse_condition_kernel( if ((negate = rvalue[0] == '!')) rvalue++; - if (!(c = condition_new(CONDITION_KERNEL_COMMAND_LINE, rvalue, trigger, negate))) - return -ENOMEM; - - LIST_PREPEND(Condition, conditions, u->meta.conditions, c); - return 0; -} - -static int config_parse_condition_virt( - const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Unit *u = data; - bool trigger, negate; - Condition *c; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - if ((trigger = rvalue[0] == '|')) - rvalue++; - - if ((negate = rvalue[0] == '!')) - rvalue++; - - if (!(c = condition_new(CONDITION_VIRTUALIZATION, rvalue, trigger, negate))) + if (!(c = condition_new(cond, rvalue, trigger, negate))) return -ENOMEM; LIST_PREPEND(Condition, conditions, u->meta.conditions, c); @@ -1756,9 +1725,8 @@ static void dump_items(FILE *f, const ConfigItem *items) { { config_parse_notify_access, "ACCESS" }, { config_parse_ip_tos, "TOS" }, { config_parse_condition_path, "CONDITION" }, - { config_parse_condition_kernel, "CONDITION" }, + { config_parse_condition_string, "CONDITION" }, { config_parse_condition_null, "CONDITION" }, - { config_parse_condition_virt, "CONDITION" }, }; assert(f); @@ -1883,8 +1851,8 @@ static int load_from_path(Unit *u, const char *path) { { "ConditionPathExists", config_parse_condition_path, CONDITION_PATH_EXISTS, u, "Unit" }, { "ConditionPathIsDirectory", config_parse_condition_path, CONDITION_PATH_IS_DIRECTORY, u, "Unit" }, { "ConditionDirectoryNotEmpty", config_parse_condition_path, CONDITION_DIRECTORY_NOT_EMPTY, u, "Unit" }, - { "ConditionKernelCommandLine", config_parse_condition_kernel, 0, u, "Unit" }, - { "ConditionVirtualization",config_parse_condition_virt, 0, u, "Unit" }, + { "ConditionKernelCommandLine", config_parse_condition_string, CONDITION_KERNEL_COMMAND_LINE, u, "Unit" }, + { "ConditionVirtualization", config_parse_condition_string, CONDITION_VIRTUALIZATION, u, "Unit" }, { "ConditionNull", config_parse_condition_null, 0, u, "Unit" }, { "PIDFile", config_parse_path, 0, &u->service.pid_file, "Service" }, From 07e833bc1d60e282b062eb205bb13215dc0e8cdf Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Sun, 3 Apr 2011 18:16:59 +0200 Subject: [PATCH 163/200] condition: add ConditionSecurity Using ConditionSecurity a unit can depend on a security module being enabled/disabled. For now the only recognized security module is SELinux. I'd like to use this feature for a unit that creates /.autorelabel if SELinux is disabled, to ensure a relabel is done automatically when the system is later rebooted with SELinux enabled. --- src/condition.c | 16 ++++++++++++++++ src/condition.h | 1 + src/load-fragment.c | 1 + 3 files changed, 18 insertions(+) diff --git a/src/condition.c b/src/condition.c index 5ab77d80f..ee0809f76 100644 --- a/src/condition.c +++ b/src/condition.c @@ -24,6 +24,10 @@ #include #include +#ifdef HAVE_SELINUX +#include +#endif + #include "util.h" #include "condition.h" @@ -128,6 +132,14 @@ static bool test_virtualization(const char *parameter) { return streq(parameter, id); } +static bool test_security(const char *parameter) { +#ifdef HAVE_SELINUX + if (!strcasecmp(parameter, "SELinux")) + return is_selinux_enabled() > 0; +#endif + return false; +} + bool condition_test(Condition *c) { assert(c); @@ -157,6 +169,9 @@ bool condition_test(Condition *c) { case CONDITION_VIRTUALIZATION: return test_virtualization(c->parameter) == !c->negate; + case CONDITION_SECURITY: + return test_security(c->parameter) == !c->negate; + case CONDITION_NULL: return !c->negate; @@ -220,6 +235,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty", [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine", [CONDITION_VIRTUALIZATION] = "ConditionVirtualization", + [CONDITION_SECURITY] = "ConditionSecurity", [CONDITION_NULL] = "ConditionNull" }; diff --git a/src/condition.h b/src/condition.h index 9913c8c84..84028028c 100644 --- a/src/condition.h +++ b/src/condition.h @@ -32,6 +32,7 @@ typedef enum ConditionType { CONDITION_DIRECTORY_NOT_EMPTY, CONDITION_KERNEL_COMMAND_LINE, CONDITION_VIRTUALIZATION, + CONDITION_SECURITY, CONDITION_NULL, _CONDITION_TYPE_MAX, _CONDITION_TYPE_INVALID = -1 diff --git a/src/load-fragment.c b/src/load-fragment.c index cb8c25089..eea545c8d 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1853,6 +1853,7 @@ static int load_from_path(Unit *u, const char *path) { { "ConditionDirectoryNotEmpty", config_parse_condition_path, CONDITION_DIRECTORY_NOT_EMPTY, u, "Unit" }, { "ConditionKernelCommandLine", config_parse_condition_string, CONDITION_KERNEL_COMMAND_LINE, u, "Unit" }, { "ConditionVirtualization", config_parse_condition_string, CONDITION_VIRTUALIZATION, u, "Unit" }, + { "ConditionSecurity", config_parse_condition_string, CONDITION_SECURITY, u, "Unit" }, { "ConditionNull", config_parse_condition_null, 0, u, "Unit" }, { "PIDFile", config_parse_path, 0, &u->service.pid_file, "Service" }, From 69528c31c64963a1279123fb17d00334c1655cd1 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Sun, 3 Apr 2011 18:17:05 +0200 Subject: [PATCH 164/200] man: document ConditionSecurity --- man/systemd.unit.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 47ddece31..73968067a 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -565,6 +565,7 @@ ConditionDirectoryNotEmpty= ConditionKernelCommandLine= ConditionVirtualization= + ConditionSecurity= ConditionNull= Before starting a unit @@ -628,6 +629,13 @@ openvz to test against a specific implementation. The test may be negated by prepending an + exclamation mark. + ConditionSecurity= + may be used to check whether the given security + module is enabled on the system. + Currently the only recognized value is + SELinux. + The test may be negated by prepending an exclamation mark. Finally, ConditionNull= may be used to add a constant condition From d24e1b4806e7e96b0c5bc0950ce79e8f76c2ab71 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 3 Apr 2011 22:18:35 +0200 Subject: [PATCH 165/200] condition: use 'selinux' rather than 'SELinux' as preferred spelling The virtualization condition and others use lowercase identifiers, so for the sake of keeping things least surprising, use lowercase identifiers here too. --- man/systemd.unit.xml | 2 +- src/condition.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 73968067a..5460ebeb2 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -634,7 +634,7 @@ may be used to check whether the given security module is enabled on the system. Currently the only recognized value is - SELinux. + selinux. The test may be negated by prepending an exclamation mark. Finally, ConditionNull= may diff --git a/src/condition.c b/src/condition.c index ee0809f76..a520e4343 100644 --- a/src/condition.c +++ b/src/condition.c @@ -134,7 +134,7 @@ static bool test_virtualization(const char *parameter) { static bool test_security(const char *parameter) { #ifdef HAVE_SELINUX - if (!strcasecmp(parameter, "SELinux")) + if (streq(parameter, "selinux")) return is_selinux_enabled() > 0; #endif return false; From 3336686286cb0eab725190c14bc990b38fe57125 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 3 Apr 2011 22:21:21 +0200 Subject: [PATCH 166/200] tmpfiles: create leading directories for d/D instructions --- TODO | 2 -- src/tmpfiles.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/TODO b/TODO index b3d8e1afc..8e822e782 100644 --- a/TODO +++ b/TODO @@ -30,8 +30,6 @@ Features: * tmpfiles should allow two identical lines https://bugzilla.redhat.com/show_bug.cgi?id=690253 -* tmpfiles should create leading directories for d,D,f,F? - * avoid any flag files, or readahead files in /, we need to support r/o / or / on tmpfs like Android setups. diff --git a/src/tmpfiles.c b/src/tmpfiles.c index e92b1123c..70a9ebd83 100644 --- a/src/tmpfiles.c +++ b/src/tmpfiles.c @@ -466,6 +466,7 @@ static int create_item(Item *i) { case CREATE_DIRECTORY: u = umask(0); + mkdir_parents(i->path, 0755); r = mkdir(i->path, i->mode); umask(u); From d7cc2987a50e62af6b806f1f56f526cf219a0d97 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 3 Apr 2011 23:55:40 +0200 Subject: [PATCH 167/200] update TODO --- TODO | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/TODO b/TODO index 8e822e782..f4026c3fd 100644 --- a/TODO +++ b/TODO @@ -25,6 +25,10 @@ F15: Features: +* add bimft_misc client tools + +* in pam_systemd: don't rely on /proc/self/loginuid in a container + * take BSD file lock on tty devices when using them? * tmpfiles should allow two identical lines @@ -37,6 +41,9 @@ Features: * document default dependencies +* support systemd.whitelist=/systemd.blacklist= on the kernel command + line. + * Find a way to replace /var/run, /var/lock directories with symlinks during an RPM package upgrade (filesystem.rpm or systemd.rpm). We soon want to get rid of var-run.mount var-lock.mount units. From 151b190e79e64824552e01849352ca8f6ac7dedb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 03:36:42 +0200 Subject: [PATCH 168/200] binfmt: add binfmt tool to set up binfmt_misc at boot --- .gitignore | 1 + Makefile.am | 22 +++- man/binfmt.d.xml | 103 ++++++++++++++++++ src/binfmt.c | 187 ++++++++++++++++++++++++++++++++ src/util.c | 11 +- units/.gitignore | 1 + units/systemd-binfmt.service.in | 19 ++++ 7 files changed, 340 insertions(+), 4 deletions(-) create mode 100644 man/binfmt.d.xml create mode 100644 src/binfmt.c create mode 100644 units/systemd-binfmt.service.in diff --git a/.gitignore b/.gitignore index 7213a8ba9..be44cb60b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +systemd-binfmt systemd-getty-generator systemd-nspawn systemd-stdio-bridge diff --git a/Makefile.am b/Makefile.am index 7bf32aa83..4fd3e6257 100644 --- a/Makefile.am +++ b/Makefile.am @@ -144,7 +144,8 @@ rootlibexec_PROGRAMS = \ systemd-timestamp \ systemd-ac-power \ systemd-detect-virt \ - systemd-sysctl + systemd-sysctl \ + systemd-binfmt systemgenerator_PROGRAMS = \ systemd-getty-generator @@ -300,6 +301,7 @@ nodist_systemunit_DATA = \ units/systemd-ask-password-wall.service \ units/systemd-ask-password-console.service \ units/systemd-sysctl.service \ + units/systemd-binfmt.service \ units/halt.service \ units/poweroff.service \ units/reboot.service \ @@ -343,6 +345,7 @@ EXTRA_DIST = \ units/systemd-ask-password-wall.service.in \ units/systemd-ask-password-console.service.in \ units/systemd-sysctl.service.in \ + units/systemd-binfmt.service.in \ units/halt.service.in \ units/poweroff.service.in \ units/reboot.service.in \ @@ -569,7 +572,8 @@ MANPAGES = \ man/vconsole.conf.5 \ man/locale.conf.5 \ man/os-release.5 \ - man/modules-load.d.5 + man/modules-load.d.5 \ + man/binfmt.d.5 MANPAGES_ALIAS = \ man/reboot.8 \ @@ -799,6 +803,15 @@ systemd_sysctl_CFLAGS = \ systemd_sysctl_LDADD = \ libsystemd-basic.la +systemd_binfmt_SOURCES = \ + src/binfmt.c + +systemd_binfmt_CFLAGS = \ + $(AM_CFLAGS) + +systemd_binfmt_LDADD = \ + libsystemd-basic.la + systemd_fsck_SOURCES = \ src/fsck.c \ src/dbus-common.c @@ -1240,9 +1253,10 @@ CLEANFILES += \ install-data-hook: $(MKDIR_P) -m 0755 \ - $(DESTDIR)$(sysconfdir)/modules-load.d \ $(DESTDIR)$(tmpfilesdir) \ + $(DESTDIR)$(sysconfdir)/modules-load.d \ $(DESTDIR)$(sysconfdir)/sysctl.d \ + $(DESTDIR)$(sysconfdir)/binfmt.d \ $(DESTDIR)$(systemshutdowndir) \ $(DESTDIR)$(systemgeneratordir) \ $(DESTDIR)$(usergeneratordir) @@ -1364,6 +1378,7 @@ install-data-hook: systemd-random-seed-load.service \ systemd-tmpfiles-setup.service \ systemd-sysctl.service \ + systemd-binfmt.service \ systemd-ask-password-console.path \ systemd-kmsg-syslogd.service \ cryptsetup.target && \ @@ -1377,6 +1392,7 @@ install-data-hook: $(LN_S) ../systemd-random-seed-load.service systemd-random-seed-load.service && \ $(LN_S) ../systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \ $(LN_S) ../systemd-sysctl.service systemd-sysctl.service && \ + $(LN_S) ../systemd-binfmt.service systemd-binfmt.service && \ $(LN_S) ../systemd-ask-password-console.path systemd-ask-password-console.path && \ $(LN_S) ../systemd-kmsg-syslogd.service && \ $(LN_S) ../cryptsetup.target cryptsetup.target ) diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml new file mode 100644 index 000000000..d2a0d7932 --- /dev/null +++ b/man/binfmt.d.xml @@ -0,0 +1,103 @@ + + + + + + + + binfmt.d + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + binfmt.d + 5 + + + + binfmt.d + Configure additional binary formats at boot + + + + /etc/binfmt.d/*.conf + + + + Description + + systemd uses + /etc/binfmt.d/ to configure + additional binary formats to register during boot in + the kernel. Each configuration file is named in the + style of + /etc/binfmt.d/<program>.conf. + + + + + + Configuration Format + + Each file contains a list of binfmt_misc kernel + binary format rules. Consult binfmt_misc.txt + for more information on registration of additional + binary formats and how to write rules. + + Empty lines and lines beginning with ; and # are + ignored. Note that this means you may not use ; and # + as delimiter in binary format rules. + + Configuration files are loaded in alphabetical + order. To ensure that a specific rule takes precedence + over another place it in a file with an alphabetically + later name. + + + + + Example + + /etc/binfmt.d/wine.conf example: + + # Start WINE on Windows executables +:DOSWin:M::MZ::/usr/bin/wine: + + + + + See Also + + systemd1, + wine8 + + + + diff --git a/src/binfmt.c b/src/binfmt.c new file mode 100644 index 000000000..6ebd212ee --- /dev/null +++ b/src/binfmt.c @@ -0,0 +1,187 @@ +/*-*- 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" + +static int delete_rule(const char *rule) { + char *x, *fn, *e; + int r; + + assert(rule[0]); + + if (!(x = strdup(rule))) + return -ENOMEM; + + e = strchrnul(x+1, x[0]); + *e = 0; + + asprintf(&fn, "/proc/sys/fs/binfmt_misc/%s", x+1); + free(x); + + if (!fn) + return -ENOMEM; + + r = write_one_line_file(fn, "-1"); + free(fn); + + return r; +} + +static int apply_rule(const char *rule) { + int r; + + delete_rule(rule); + + if ((r = write_one_line_file("/proc/sys/fs/binfmt_misc/register", rule)) < 0) { + log_error("Failed to add binary format: %s", strerror(-r)); + return r; + } + + return 0; +} + +static int apply_file(const char *path, bool ignore_enoent) { + FILE *f; + int r = 0; + + assert(path); + + if (!(f = fopen(path, "re"))) { + if (ignore_enoent && errno == ENOENT) + return 0; + + log_error("Failed to open file '%s', ignoring: %m", path); + return -errno; + } + + while (!feof(f)) { + char l[LINE_MAX], *p; + int k; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + log_error("Failed to read file '%s', ignoring: %m", path); + r = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + if ((k = apply_rule(p)) < 0 && r == 0) + r = k; + } + +finish: + fclose(f); + + return r; +} + +static int scandir_filter(const struct dirent *d) { + assert(d); + + if (ignore_file(d->d_name)) + return 0; + + if (d->d_type != DT_REG && + d->d_type != DT_LNK && + d->d_type != DT_UNKNOWN) + return 0; + + return endswith(d->d_name, ".conf"); +} + +static int apply_tree(const char *path) { + struct dirent **de = NULL; + int n, i, r = 0; + + if ((n = scandir(path, &de, scandir_filter, alphasort)) < 0) { + + if (errno == ENOENT) + return 0; + + log_error("Failed to enumerate %s files: %m", path); + return -errno; + } + + for (i = 0; i < n; i++) { + char *fn; + int k; + + k = asprintf(&fn, "%s/%s", path, de[i]->d_name); + free(de[i]); + + if (k < 0) { + log_error("Failed to allocate file name."); + + if (r == 0) + r = -ENOMEM; + continue; + } + + if ((k = apply_file(fn, true)) < 0 && r == 0) + r = k; + } + + free(de); + + return r; +} + +int main(int argc, char *argv[]) { + int r = 0; + + if (argc > 2) { + log_error("This program expects one or no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + if (argc > 1) + r = apply_file(argv[1], false); + else { + /* Flush out all rules */ + write_one_line_file("/proc/sys/fs/binfmt_misc/status", "-1"); + + r = apply_tree("/etc/binfmt.d"); + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/util.c b/src/util.c index a1686ed38..5daafdf7c 100644 --- a/src/util.c +++ b/src/util.c @@ -513,7 +513,16 @@ int write_one_line_file(const char *fn, const char *line) { if (!endswith(line, "\n")) fputc('\n', f); - r = 0; + fflush(f); + + if (ferror(f)) { + if (errno != 0) + r = -errno; + else + r = -EIO; + } else + r = 0; + finish: fclose(f); return r; diff --git a/units/.gitignore b/units/.gitignore index 41ab51b2a..cbf9f255f 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -34,3 +34,4 @@ remote-fs.target systemd-update-utmp-runlevel.service systemd-update-utmp-shutdown.service test-env-replace +systemd-binfmt.service diff --git a/units/systemd-binfmt.service.in b/units/systemd-binfmt.service.in new file mode 100644 index 000000000..0bf6df201 --- /dev/null +++ b/units/systemd-binfmt.service.in @@ -0,0 +1,19 @@ +# 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=Set Up Additional Binary Formats +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service proc-sys-fs-binfmt_misc.automount +Before=sysinit.target shutdown.target +ConditionDirectoryNotEmpty=/etc/binfmt.d + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-binfmt From c91faef3b3facfdf13282aee957af25dd555890b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 03:48:09 +0200 Subject: [PATCH 169/200] man: document /etc/sysctl.d/ --- Makefile.am | 3 +- man/binfmt.d.xml | 2 +- man/modules-load.d.xml | 2 +- man/sysctl.d.xml | 95 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 man/sysctl.d.xml diff --git a/Makefile.am b/Makefile.am index 4fd3e6257..349316aa3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -573,7 +573,8 @@ MANPAGES = \ man/locale.conf.5 \ man/os-release.5 \ man/modules-load.d.5 \ - man/binfmt.d.5 + man/binfmt.d.5 \ + man/sysctl.d.5 MANPAGES_ALIAS = \ man/reboot.8 \ diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml index d2a0d7932..64c27554e 100644 --- a/man/binfmt.d.xml +++ b/man/binfmt.d.xml @@ -4,7 +4,7 @@ + + + + + + sysctl.d + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sysctl.d + 5 + + + + sysctl.d + Configure kernel parameters at boot + + + + /etc/sysctl.d/*.conf + + + + Description + + systemd uses + /etc/sysctl.d/ to configure + sysctl8 + kernel parameters to load during boot. Each + configuration file is named in the style of + /etc/sysctl.d/<program>.conf. + + + + Configuration Format + + The configuration files should simply contain a + list of variable assignments, separated by + newlines. Empty lines and lines whose first + non-whitespace character is # or ; are ignored. + + Note that both / and . are accepted as + separators in sysctl variable names. + + + + + Example + + /etc/sysctl.d/domain-name.conf example: + + # Set kernel YP domain name +kernel.domainname=example.com + + + + + See Also + + systemd1, + sysctl8, + sysctl.conf5 + + + + From 30d6500340bd93da4dae63223e1bd8e1da6b07c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 04:06:24 +0200 Subject: [PATCH 170/200] units: improve logger descriptions --- TODO | 2 -- units/systemd-kmsg-syslogd.service.in | 2 +- units/systemd-logger.service.in | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index f4026c3fd..ce1a26ecf 100644 --- a/TODO +++ b/TODO @@ -25,8 +25,6 @@ F15: Features: -* add bimft_misc client tools - * in pam_systemd: don't rely on /proc/self/loginuid in a container * take BSD file lock on tty devices when using them? diff --git a/units/systemd-kmsg-syslogd.service.in b/units/systemd-kmsg-syslogd.service.in index adb375021..b81e4a306 100644 --- a/units/systemd-kmsg-syslogd.service.in +++ b/units/systemd-kmsg-syslogd.service.in @@ -8,7 +8,7 @@ # See systemd.special(7) for details [Unit] -Description=systemd Syslog Kernel Log Buffer Bridge +Description=Syslog Kernel Log Buffer Bridge DefaultDependencies=no [Service] diff --git a/units/systemd-logger.service.in b/units/systemd-logger.service.in index ff7a1316c..0fb0b4204 100644 --- a/units/systemd-logger.service.in +++ b/units/systemd-logger.service.in @@ -8,7 +8,7 @@ # See systemd.special(7) for details [Unit] -Description=Logging Daemon +Description=Stream Logging Service DefaultDependencies=no After=syslog.socket From f1159d7c78ba5f4551603f2afc8b3b9dd07117ca Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 15:23:29 +0200 Subject: [PATCH 171/200] logger: name socket like service --- units/systemd-logger.socket | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/systemd-logger.socket b/units/systemd-logger.socket index 9b2d202f2..389b507d2 100644 --- a/units/systemd-logger.socket +++ b/units/systemd-logger.socket @@ -8,7 +8,7 @@ # See systemd.special(7) for details [Unit] -Description=Logging Socket +Description=Stream Logging Socket DefaultDependencies=no Before=sockets.target From d19c883d509bb0926635a1a9b30c4875dbbbbfab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 15:22:58 +0200 Subject: [PATCH 172/200] units: move user units from /usr/share to /usr/lib since they might be arch-dependent --- Makefile.am | 4 +++- systemd.pc.in | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 349316aa3..efc969cca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,7 +30,7 @@ bashcompletiondir=$(sysconfdir)/bash_completion.d # Our own, non-special dirs pkgsysconfdir=$(sysconfdir)/systemd -userunitdir=$(pkgdatadir)/user +userunitdir=$(pkglibdir)/user tmpfilesdir=$(sysconfdir)/tmpfiles.d usergeneratordir=$(pkglibexecdir)/user-generators @@ -1130,7 +1130,9 @@ SED_PROCESS = \ -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \ -e 's,@pkgsysconfdir\@,$(pkgsysconfdir),g' \ -e 's,@pkgdatadir\@,$(pkgdatadir),g' \ + -e 's,@pkglibdir\@,$(pkglibdir),g' \ -e 's,@systemunitdir\@,$(systemunitdir),g' \ + -e 's,@userunitdir\@,$(userunitdir),g' \ -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \ -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \ -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' \ diff --git a/systemd.pc.in b/systemd.pc.in index 6a843fbde..33c3f36a9 100644 --- a/systemd.pc.in +++ b/systemd.pc.in @@ -8,7 +8,7 @@ prefix=@prefix@ exec_prefix=${prefix} systemdsystemunitdir=@systemunitdir@ -systemduserunitdir=@pkgdatadir@/user +systemduserunitdir=@userunitdir@ systemdsystemconfdir=@pkgsysconfdir@/system systemduserconfdir=@pkgsysconfdir@/user systemdsystemunitpath=/run/systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/share/systemd/system:/lib/systemd/system:${systemdsystemunitdir} From db019b8dd206844dcf5fde661256dc71fcc06fef Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 4 Apr 2011 15:33:00 +0200 Subject: [PATCH 173/200] change remaining /var/run to /run --- src/bridge.c | 2 +- src/shutdownd.c | 8 ++++---- src/tmpfiles.c | 5 ++--- src/user-sessions.c | 8 ++++---- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/bridge.c b/src/bridge.c index 5ee058a37..878856cfd 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -158,7 +158,7 @@ int main(int argc, char *argv[]) { zero(sa); sa.un.sun_family = AF_UNIX; - strncpy(sa.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(sa.un.sun_path)); + strncpy(sa.un.sun_path, "/run/dbus/system_bus_socket", sizeof(sa.un.sun_path)); if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { log_error("Failed to connect: %m"); diff --git a/src/shutdownd.c b/src/shutdownd.c index 6b92ceeb1..8f765b451 100644 --- a/src/shutdownd.c +++ b/src/shutdownd.c @@ -318,10 +318,10 @@ int main(int argc, char *argv[]) { if (pollfd[FD_NOLOGIN_TIMER].revents) { int e; - log_info("Creating /var/run/nologin, blocking further logins..."); + log_info("Creating /run/nologin, blocking further logins..."); - if ((e = write_one_line_file("/var/run/nologin", "System is going down.")) < 0) - log_error("Failed to create /var/run/nologin: %s", strerror(-e)); + if ((e = write_one_line_file("/run/nologin", "System is going down.")) < 0) + log_error("Failed to create /run/nologin: %s", strerror(-e)); else unlink_nologin = true; @@ -346,7 +346,7 @@ finish: close_nointr_nofail(pollfd[i].fd); if (unlink_nologin) - unlink("/var/run/nologin"); + unlink("/run/nologin"); if (exec_shutdown) { char sw[3]; diff --git a/src/tmpfiles.c b/src/tmpfiles.c index 70a9ebd83..b21df95a7 100644 --- a/src/tmpfiles.c +++ b/src/tmpfiles.c @@ -47,9 +47,8 @@ /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates * them in the file system. This is intended to be used to create - * properly owned directories beneath /tmp, /var/tmp, /run and - * /var/lock which are volatile and hence need to be recreated on - * bootup. */ + * properly owned directories beneath /tmp, /var/tmp, /run, which are + * volatile and hence need to be recreated on bootup. */ enum { /* These ones take file names */ diff --git a/src/user-sessions.c b/src/user-sessions.c index d3faad0cd..4518d953e 100644 --- a/src/user-sessions.c +++ b/src/user-sessions.c @@ -42,8 +42,8 @@ int main(int argc, char*argv[]) { if (streq(argv[1], "start")) { int q = 0, r = 0; - if (unlink("/var/run/nologin") < 0 && errno != ENOENT) { - log_error("Failed to remove /var/run/nologin file: %m"); + if (unlink("/run/nologin") < 0 && errno != ENOENT) { + log_error("Failed to remove /run/nologin file: %m"); r = -errno; } @@ -59,8 +59,8 @@ int main(int argc, char*argv[]) { int r, q; char *cgroup_user_tree = NULL; - if ((r = write_one_line_file("/var/run/nologin", "System is going down.")) < 0) - log_error("Failed to create /var/run/nologin: %s", strerror(-r)); + if ((r = write_one_line_file("/run/nologin", "System is going down.")) < 0) + log_error("Failed to create /run/nologin: %s", strerror(-r)); if ((q = cg_get_user_path(&cgroup_user_tree)) < 0) { log_error("Failed to determine use path: %s", strerror(-q)); From 4466ee6a7151b30b7738b09c4c21ffa3872a5047 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Mon, 4 Apr 2011 15:08:40 +0200 Subject: [PATCH 174/200] manager: fd must be int, not char This should fix the crash reported by Dan Horak on s390x which does not have VTs. --- src/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manager.c b/src/manager.c index dae746cae..9fc854b66 100644 --- a/src/manager.c +++ b/src/manager.c @@ -127,7 +127,7 @@ static int manager_setup_notify(Manager *m) { } static int enable_special_signals(Manager *m) { - char fd; + int fd; assert(m); From 9d8677dad260d7dc20146f8affe3d376daff7c19 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 15:38:25 +0200 Subject: [PATCH 175/200] update TODO --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index ce1a26ecf..466dadc09 100644 --- a/TODO +++ b/TODO @@ -25,6 +25,10 @@ F15: Features: +* rename systemd-logger to systemd-stdio-syslog-bridge + +* introduce /usr/lib/binfmt.d/, /usr/lib/tmpfiles.d/ + * in pam_systemd: don't rely on /proc/self/loginuid in a container * take BSD file lock on tty devices when using them? From 3bbecb2f2cd758e2513993efad01180c7c3c665f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 16:56:51 +0200 Subject: [PATCH 176/200] selinux: relabel /run the same way as /dev after loading the policy since they both come pre-filled and unlabelled --- src/mount-setup.c | 4 +++- src/selinux-setup.c | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mount-setup.c b/src/mount-setup.c index 49eab0bfa..a42ed4395 100644 --- a/src/mount-setup.c +++ b/src/mount-setup.c @@ -243,8 +243,10 @@ int mount_setup(void) { * appropriate labels, after mounting. The other virtual API * file systems do not need. */ - if (unlink("/dev/.systemd-relabel-devtmpfs") >= 0) + if (unlink("/dev/.systemd-relabel-run-dev") >= 0) { nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS); + nftw("/run", 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 diff --git a/src/selinux-setup.c b/src/selinux-setup.c index e21ff6bb9..c32c7ad8d 100644 --- a/src/selinux-setup.c +++ b/src/selinux-setup.c @@ -43,9 +43,9 @@ int selinux_setup(char *const argv[]) { 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. */ - touch("/dev/.systemd-relabel-devtmpfs"); + * that after the reexec we iterate through /run and /dev to + * relabel things. */ + touch("/dev/.systemd-relabel-run-dev"); if (selinux_init_load_policy(&enforce) == 0) { log_debug("Successfully loaded SELinux policy, reexecuting."); @@ -60,7 +60,7 @@ int selinux_setup(char *const argv[]) { } else { log_full(enforce > 0 ? LOG_ERR : LOG_WARNING, "Failed to load SELinux policy."); - unlink("/dev/.systemd-relabel-devtmpfs"); + unlink("/dev/.systemd-relabel-run-dev"); if (enforce > 0) return -EIO; From 3d57c6ab801f4437f12948e29589e3d00c3ad9db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 18:15:13 +0200 Subject: [PATCH 177/200] exec: support unlimited resources --- TODO | 2 ++ man/systemd.exec.xml | 5 ++++- src/load-fragment.c | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 466dadc09..494f991aa 100644 --- a/TODO +++ b/TODO @@ -25,6 +25,8 @@ F15: Features: +* allow port = 0 in .socket units + * rename systemd-logger to systemd-stdio-syslog-bridge * introduce /usr/lib/binfmt.d/, /usr/lib/tmpfiles.d/ diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index fb8496f54..5b0d2ce37 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -558,7 +558,10 @@ various resource limits for executed processes. See setrlimit2 - for details. + for details. Use the string + infinity to + configure no limit on a specific + resource. diff --git a/src/load-fragment.c b/src/load-fragment.c index eea545c8d..8635bdb22 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include "unit.h" #include "strv.h" @@ -965,7 +967,9 @@ static int config_parse_limit( assert(rvalue); assert(data); - if (safe_atollu(rvalue, &u) < 0) { + if (streq(rvalue, "infinity")) + u = (unsigned long long) RLIM_INFINITY; + else if (safe_atollu(rvalue, &u) < 0) { log_error("[%s:%u] Failed to parse resource value, ignoring: %s", filename, line, rvalue); return 0; } From ef3102bf436a88fe565de1be655cdb8ca853c495 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 19:02:32 +0200 Subject: [PATCH 178/200] lookup: always also look into /usr/lib for units --- src/path-lookup.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/path-lookup.c b/src/path-lookup.c index fff930469..e5533c04d 100644 --- a/src/path-lookup.c +++ b/src/path-lookup.c @@ -102,7 +102,11 @@ static char** user_dirs(void) { if ((e = getenv("XDG_DATA_DIRS"))) data_dirs = strv_split(e, ":"); else - data_dirs = strv_new("/usr/local/share", "/usr/share", NULL); + data_dirs = strv_new("/usr/local/share", + "/usr/local/lib", + "/usr/share", + "/usr/lib", + NULL); if (!data_dirs) goto fail; @@ -187,9 +191,11 @@ int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as) { SYSTEM_CONFIG_UNIT_PATH, "/etc/systemd/system", "/usr/local/share/systemd/system", + "/usr/local/lib/systemd/system", "/usr/share/systemd/system", - "/lib/systemd/system", + "/usr/lib/systemd/system", SYSTEM_DATA_UNIT_PATH, + "/lib/systemd/system", NULL))) return -ENOMEM; } From 0b5b0ffbe0e62248c741df3b0eb475159de1c551 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Apr 2011 19:14:38 +0200 Subject: [PATCH 179/200] pkgconfig: update .pc file accordingly --- src/path-lookup.c | 2 +- systemd.pc.in | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/path-lookup.c b/src/path-lookup.c index e5533c04d..b39ce8b69 100644 --- a/src/path-lookup.c +++ b/src/path-lookup.c @@ -194,8 +194,8 @@ int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as) { "/usr/local/lib/systemd/system", "/usr/share/systemd/system", "/usr/lib/systemd/system", - SYSTEM_DATA_UNIT_PATH, "/lib/systemd/system", + SYSTEM_DATA_UNIT_PATH, NULL))) return -ENOMEM; } diff --git a/systemd.pc.in b/systemd.pc.in index 33c3f36a9..2e2217ec4 100644 --- a/systemd.pc.in +++ b/systemd.pc.in @@ -11,7 +11,8 @@ systemdsystemunitdir=@systemunitdir@ systemduserunitdir=@userunitdir@ systemdsystemconfdir=@pkgsysconfdir@/system systemduserconfdir=@pkgsysconfdir@/user -systemdsystemunitpath=/run/systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/share/systemd/system:/lib/systemd/system:${systemdsystemunitdir} +systemdsystemunitpath=/run/systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/local/lib/systemd/system:/usr/share/systemd/system:/usr/lib/systemd/system:/lib/systemd/system:${systemdsystemunitdir} +systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/usr/local/share/systemd/user:/usr/local/lib/systemd/user:/usr/share/systemd/user:/usr/lib/systemd/user:${systemduserunitdir} Name: systemd Description: systemd System and Service Manager From 68c7d001f4117f0c3d0a4582e32cbb03ae5fac57 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 00:24:00 +0200 Subject: [PATCH 180/200] update TODO --- TODO | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 494f991aa..db7947794 100644 --- a/TODO +++ b/TODO @@ -23,8 +23,19 @@ F15: * fix alsa mixer restore to not print error when no config is stored +* don't trim empty cgroups + https://bugzilla.redhat.com/show_bug.cgi?id=678555 + +* reload-or-try-restart man page uses word "fail" + Features: +* write blog stories about: + - chroot, nspawn and friends + - the blame game: systemd-analyze + - enabling dbus services + - status update + * allow port = 0 in .socket units * rename systemd-logger to systemd-stdio-syslog-bridge @@ -43,6 +54,8 @@ Features: * teach dbus to activate all services it finds in /etc/systemd/services/org-*.service +* get process transport into dbus for systemctl -P/-H + * document default dependencies * support systemd.whitelist=/systemd.blacklist= on the kernel command @@ -167,7 +180,7 @@ Features: - bluetoothd (/var/run/sdp! @/org/bluez/audio!) - distccd -* fingerprint.target, wireless.target, gps.target +* fingerprint.target, wireless.target, gps.target, netdevice.target * set_put(), hashmap_put() return values check. i.e. == 0 doesn't free()! From 8947c242c5287ce20fc1e7f12344da84fe06a35b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 00:36:01 +0200 Subject: [PATCH 181/200] build-sys: bump version number --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0821e7235..0025a6a4d 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.63) -AC_INIT([systemd],[22],[systemd-devel@lists.freedesktop.org]) +AC_INIT([systemd],[23],[systemd-devel@lists.freedesktop.org]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) From cdee58bd382df3dffb103b45c848aa759ff73881 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 01:44:26 +0200 Subject: [PATCH 182/200] update TODO --- TODO | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index db7947794..0297a1772 100644 --- a/TODO +++ b/TODO @@ -10,8 +10,6 @@ F15: * hook emergency.target into local-fs.target in some way as OnFailure with isolate -* save/restore tool for SysV as requested by FPC (PENDING) - * bind mounts are ignored * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown @@ -28,6 +26,8 @@ F15: * reload-or-try-restart man page uses word "fail" +* Move units from lib64 to lib + Features: * write blog stories about: From 61fbbab8697ec62cdedc08efdbb8da1c875ce2a1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 5 Apr 2011 02:19:42 +0200 Subject: [PATCH 183/200] build-sys: always place user units in /usr/lib/systemd ./configure --libexecdir=/usr/lib --- Makefile.am | 10 +++++----- TODO | 2 -- autogen.sh | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Makefile.am b/Makefile.am index efc969cca..ca027b62b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,7 +30,7 @@ bashcompletiondir=$(sysconfdir)/bash_completion.d # Our own, non-special dirs pkgsysconfdir=$(sysconfdir)/systemd -userunitdir=$(pkglibdir)/user +userunitdir=$(pkglibexecdir)/user tmpfilesdir=$(sysconfdir)/tmpfiles.d usergeneratordir=$(pkglibexecdir)/user-generators @@ -145,7 +145,7 @@ rootlibexec_PROGRAMS = \ systemd-ac-power \ systemd-detect-virt \ systemd-sysctl \ - systemd-binfmt + systemd-binfmt systemgenerator_PROGRAMS = \ systemd-getty-generator @@ -573,8 +573,8 @@ MANPAGES = \ man/locale.conf.5 \ man/os-release.5 \ man/modules-load.d.5 \ - man/binfmt.d.5 \ - man/sysctl.d.5 + man/binfmt.d.5 \ + man/sysctl.d.5 MANPAGES_ALIAS = \ man/reboot.8 \ @@ -1130,7 +1130,7 @@ SED_PROCESS = \ -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \ -e 's,@pkgsysconfdir\@,$(pkgsysconfdir),g' \ -e 's,@pkgdatadir\@,$(pkgdatadir),g' \ - -e 's,@pkglibdir\@,$(pkglibdir),g' \ + -e 's,@pkglibexecdir\@,$(pkglibexecdir),g' \ -e 's,@systemunitdir\@,$(systemunitdir),g' \ -e 's,@userunitdir\@,$(userunitdir),g' \ -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \ diff --git a/TODO b/TODO index 0297a1772..c8bf22943 100644 --- a/TODO +++ b/TODO @@ -26,8 +26,6 @@ F15: * reload-or-try-restart man page uses word "fail" -* Move units from lib64 to lib - Features: * write blog stories about: diff --git a/autogen.sh b/autogen.sh index 74f814d28..826d9b0d0 100755 --- a/autogen.sh +++ b/autogen.sh @@ -66,7 +66,7 @@ else run_versioned automake "$AM_VERSION" --copy --foreign --add-missing if [ "x$1" != "xac" ]; then - CFLAGS="$CFLAGS -g -O0" ./configure --sysconfdir=/etc --localstatedir=/var --with-rootdir= "$@" + CFLAGS="$CFLAGS -g -O0" ./configure --sysconfdir=/etc --localstatedir=/var --with-rootdir= --libexecdir=/usr/lib "$@" make clean fi fi From bfdb49388f0e46fe223c768aee4aa6d1fd959fe2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 02:40:59 +0200 Subject: [PATCH 184/200] build-sys: fix libexecdir to /usr/lib --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index ca027b62b..ee39cf090 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,9 @@ ACLOCAL_AMFLAGS = -I m4 +# Override libexecdir +libexecdir=$(exec_prefix)/lib + # Dirs of external packages dbuspolicydir=@dbuspolicydir@ dbussessionservicedir=@dbussessionservicedir@ From 32d0463d5c9982cc0c98a6e2867f94c764a496c2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 02:49:49 +0200 Subject: [PATCH 185/200] build-sys: better don't use libexecdir here at all --- Makefile.am | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index ee39cf090..41e7a921a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,9 +17,6 @@ ACLOCAL_AMFLAGS = -I m4 -# Override libexecdir -libexecdir=$(exec_prefix)/lib - # Dirs of external packages dbuspolicydir=@dbuspolicydir@ dbussessionservicedir=@dbussessionservicedir@ @@ -33,7 +30,7 @@ bashcompletiondir=$(sysconfdir)/bash_completion.d # Our own, non-special dirs pkgsysconfdir=$(sysconfdir)/systemd -userunitdir=$(pkglibexecdir)/user +userunitdir=$(prefix)/lib/systemd/user tmpfilesdir=$(sysconfdir)/tmpfiles.d usergeneratordir=$(pkglibexecdir)/user-generators From cb06add70d69eae1a990da283e1a582ee98a142d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 02:52:21 +0200 Subject: [PATCH 186/200] build-sys: we don't need rootsbindir anymore since we don't install anything to /sbin --- Makefile.am | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 41e7a921a..4e244807c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,11 +37,10 @@ usergeneratordir=$(pkglibexecdir)/user-generators # And these are the special ones for / rootdir=@rootdir@ rootbindir=$(rootdir)/bin -rootsbindir=$(rootdir)/sbin rootlibexecdir=$(rootdir)/lib/systemd +systemgeneratordir=$(rootlibexecdir)/system-generators +systemshutdowndir=$(rootlibexecdir)/system-shutdown systemunitdir=$(rootdir)/lib/systemd/system -systemgeneratordir=$(rootdir)/lib/systemd/system-generators -systemshutdowndir=$(rootdir)/lib/systemd/system-shutdown AM_CPPFLAGS = \ -include $(top_builddir)/config.h \ From 33bd08a97a5bf64e0a1ac72190dc3a8e1231e7f2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 23:22:35 +0200 Subject: [PATCH 187/200] units: call the logger a bridge too --- TODO | 4 +++- units/systemd-logger.service.in | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index c8bf22943..fe516c5ee 100644 --- a/TODO +++ b/TODO @@ -24,7 +24,9 @@ F15: * don't trim empty cgroups https://bugzilla.redhat.com/show_bug.cgi?id=678555 -* reload-or-try-restart man page uses word "fail" +* reload-or-try-restart man page blurb uses word "fail" + +* explicitly block creation of mount units for API file systems Features: diff --git a/units/systemd-logger.service.in b/units/systemd-logger.service.in index 0fb0b4204..f82db15ac 100644 --- a/units/systemd-logger.service.in +++ b/units/systemd-logger.service.in @@ -8,7 +8,7 @@ # See systemd.special(7) for details [Unit] -Description=Stream Logging Service +Description=Stdio Syslog Bridge DefaultDependencies=no After=syslog.socket From 33ff02c9fe84394c34c3a50c6dab85c1847a6fc7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 23:39:21 +0200 Subject: [PATCH 188/200] mount: block creation of mount units for API file systems --- TODO | 2 -- src/mount.c | 9 ++++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index fe516c5ee..e6c2ee567 100644 --- a/TODO +++ b/TODO @@ -26,8 +26,6 @@ F15: * reload-or-try-restart man page blurb uses word "fail" -* explicitly block creation of mount units for API file systems - Features: * write blog stories about: diff --git a/src/mount.c b/src/mount.c index 2d8542d9d..49bfd079a 100644 --- a/src/mount.c +++ b/src/mount.c @@ -476,6 +476,11 @@ static int mount_verify(Mount *m) { return -EINVAL; } + if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) { + log_error("Cannot create mount unit for API file system %s. Refusing.", m->where); + return -EINVAL; + } + if (m->meta.fragment_path && !m->parameters_fragment.what) { log_error("%s's What setting is missing. Refusing.", m->meta.id); return -EBADMSG; @@ -1300,9 +1305,7 @@ static int mount_add_one( /* Ignore API mount points. They should never be referenced in * dependencies ever. */ - if (mount_point_is_api(where)) - return 0; - if (mount_point_ignore(where)) + if (mount_point_is_api(where) || mount_point_ignore(where)) return 0; if (streq(fstype, "autofs")) From 100fd5676c53c6709442a22db0253cc57f05c46d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Apr 2011 23:41:27 +0200 Subject: [PATCH 189/200] man: fix description of systemctl reload-or-try-restart --- TODO | 2 +- man/systemctl.xml | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index e6c2ee567..f3c9b4057 100644 --- a/TODO +++ b/TODO @@ -24,7 +24,7 @@ F15: * don't trim empty cgroups https://bugzilla.redhat.com/show_bug.cgi?id=678555 -* reload-or-try-restart man page blurb uses word "fail" +* disable most systemctl verbs in chroot()s Features: diff --git a/man/systemctl.xml b/man/systemctl.xml index 922fd2d68..e9e3371ba 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -487,12 +487,13 @@ Reload one or more units if they support it. If not, - restart them instead. If the units - are not running yet the operation - will fail. Note that for - compatibility with SysV init scripts + restart them instead. Do nothing if + the units are not running. Note that + for compatibility with SysV init + scripts force-reload is - equivalent to this command. + equivalent to this + command. isolate [NAME] From 67370238b55df4126e505007d46deaff8bb55a36 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 01:33:34 +0200 Subject: [PATCH 190/200] manager: don't show PID for incoming signals if it is 0 --- TODO | 6 +++--- src/manager.c | 16 +++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index f3c9b4057..f4aacacfb 100644 --- a/TODO +++ b/TODO @@ -21,13 +21,13 @@ F15: * fix alsa mixer restore to not print error when no config is stored -* don't trim empty cgroups - https://bugzilla.redhat.com/show_bug.cgi?id=678555 - * disable most systemctl verbs in chroot()s Features: +* don't trim empty cgroups + https://bugzilla.redhat.com/show_bug.cgi?id=678555 + * write blog stories about: - chroot, nspawn and friends - the blame game: systemd-analyze diff --git a/src/manager.c b/src/manager.c index 9fc854b66..6ddd40e87 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2059,8 +2059,6 @@ static int manager_process_signal_fd(Manager *m) { assert(m); for (;;) { - char *p = NULL; - if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) { if (n >= 0) @@ -2072,13 +2070,17 @@ static int manager_process_signal_fd(Manager *m) { return -errno; } - if (sfsi.ssi_pid > 0) + if (sfsi.ssi_pid > 0) { + char *p = NULL; + get_process_name(sfsi.ssi_pid, &p); - log_debug("Received SIG%s from PID %lu (%s)", - strna(signal_to_string(sfsi.ssi_signo)), - (unsigned long) sfsi.ssi_pid, strna(p)); - free(p); + log_debug("Received SIG%s from PID %lu (%s).", + strna(signal_to_string(sfsi.ssi_signo)), + (unsigned long) sfsi.ssi_pid, strna(p)); + free(p); + } else + log_debug("Received SIG%s.", strna(signal_to_string(sfsi.ssi_signo))); switch (sfsi.ssi_signo) { From 82e23dddebc79245ccd8333f229aa37975f81b6a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 01:35:56 +0200 Subject: [PATCH 191/200] systemctl: make most operations NOPs in a chroot --- src/systemctl.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/systemctl.c b/src/systemctl.c index 1507b52f9..eab4bf30c 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -5336,11 +5336,17 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError /* Require a bus connection for all operations but * enable/disable */ - if (!streq(verbs[i].verb, "enable") && - !streq(verbs[i].verb, "disable") && - !bus) { - log_error("Failed to get D-Bus connection: %s", error->message); - return -EIO; + if (!streq(verbs[i].verb, "enable") && !streq(verbs[i].verb, "disable")) { + + if (running_in_chroot() > 0) { + log_info("Running in chroot, ignoring request."); + return 0; + } + + if (!bus) { + log_error("Failed to get D-Bus connection: %s", error->message); + return -EIO; + } } return verbs[i].dispatch(bus, argv + optind, left); @@ -5652,6 +5658,12 @@ int main(int argc, char*argv[]) { goto finish; } + if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) { + log_info("Running in chroot, ignoring request."); + retval = 0; + goto finish; + } + if (arg_transport == TRANSPORT_NORMAL) bus_connect(arg_user ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error); else if (arg_transport == TRANSPORT_POLKIT) { From 9c1b183c709b90e735b60294d7be00b37814645a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 02:25:39 +0200 Subject: [PATCH 192/200] service: fix units with more than one socket https://bugzilla.redhat.com/show_bug.cgi?id=693289 --- TODO | 2 -- src/execute.c | 2 +- src/service.c | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index f4aacacfb..f91d664f2 100644 --- a/TODO +++ b/TODO @@ -21,8 +21,6 @@ F15: * fix alsa mixer restore to not print error when no config is stored -* disable most systemctl verbs in chroot()s - Features: * don't trim empty cgroups diff --git a/src/execute.c b/src/execute.c index 80c649f1c..d67916c24 100644 --- a/src/execute.c +++ b/src/execute.c @@ -981,7 +981,7 @@ int exec_spawn(ExecCommand *command, /* This string must fit in 10 chars (i.e. the length * of "/sbin/init") */ - rename_process("sd:exec"); + rename_process("sd.exec"); /* We reset exactly these signals, since they are the * only ones we set to SIG_IGN in the main daemon. All diff --git a/src/service.c b/src/service.c index 728ca0b01..a297cd911 100644 --- a/src/service.c +++ b/src/service.c @@ -1592,8 +1592,8 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) { goto fail; } - memcpy(t, rfds, rn_fds); - memcpy(t+rn_fds, cfds, cn_fds); + memcpy(t, rfds, rn_fds * sizeof(int)); + memcpy(t+rn_fds, cfds, cn_fds * sizeof(int)); free(rfds); free(cfds); From 017803e242b21ae35eed968e0a5f5310379a2e73 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 02:46:13 +0200 Subject: [PATCH 193/200] systemctl: properly parse JobNew signals https://bugzilla.redhat.com/show_bug.cgi?id=693274 --- src/systemctl.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/systemctl.c b/src/systemctl.c index eab4bf30c..00db47f12 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -2840,8 +2840,20 @@ static DBusHandlerResult monitor_filter(DBusConnection *connection, DBusMessage else printf("Unit %s removed.\n", id); - } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobNew") || - dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobNew")) { + uint32_t id; + const char *path; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + log_error("Failed to parse message: %s", bus_error_message(&error)); + else + printf("Job %u added.\n", id); + + + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { uint32_t id; const char *path, *result; @@ -2851,10 +2863,8 @@ static DBusHandlerResult monitor_filter(DBusConnection *connection, DBusMessage DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID)) log_error("Failed to parse message: %s", bus_error_message(&error)); - else if (streq(dbus_message_get_member(message), "JobNew")) - printf("Job %u added.\n", id); else - printf("Job %u removed.\n", id); + printf("Job %u removed (result=%s).\n", id, result); } else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) { From e252dd8f0ee40ac1c20d524f3622641c7907919f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 15:32:11 +0200 Subject: [PATCH 194/200] update TODO --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index f91d664f2..45d7b4ebc 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,10 @@ Features: * don't trim empty cgroups https://bugzilla.redhat.com/show_bug.cgi?id=678555 +* serialize used job ids and max job id + +* expose monotonic timestamps on the bus and make systemd-analyze use it + * write blog stories about: - chroot, nspawn and friends - the blame game: systemd-analyze From f80781eaf9f927d7b4d5e66116e3f3a4242e6fa1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 15:57:37 +0200 Subject: [PATCH 195/200] var-lock: don't try to enable var-lock.mount if we don't install it --- Makefile.am | 9 ++++++--- TODO | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Makefile.am b/Makefile.am index 4e244807c..160acfb9c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -274,7 +274,6 @@ dist_systemunit_DATA += \ units/var-lock.mount endif - nodist_systemunit_DATA = \ units/getty@.service \ units/serial-getty@.service \ @@ -1320,13 +1319,11 @@ install-data-hook: fsck-root.service \ remount-rootfs.service \ var-run.mount \ - var-lock.mount \ media.mount && \ $(LN_S) ../systemd-remount-api-vfs.service systemd-remount-api-vfs.service && \ $(LN_S) ../fsck-root.service fsck-root.service && \ $(LN_S) ../remount-rootfs.service remount-rootfs.service && \ $(LN_S) ../var-run.mount var-run.mount && \ - $(LN_S) ../var-lock.mount var-lock.mount && \ $(LN_S) ../media.mount media.mount ) ( cd $(DESTDIR)$(userunitdir) && \ rm -f shutdown.target sockets.target local-fs.target swap.target bluetooth.target printer.target sound.target && \ @@ -1474,6 +1471,12 @@ if TARGET_DEBIAN_OR_UBUNTU $(LN_S) multi-user.target runlevel5.target ) endif +if HAVE_SYSV_COMPAT + ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \ + rm -f var-lock.mount && \ + $(LN_S) ../var-lock.mount var-lock.mount ) +endif + DISTCHECK_CONFIGURE_FLAGS = \ --with-dbuspolicydir=$$dc_install_base/$(dbuspolicydir) \ --with-dbussessionservicedir=$$dc_install_base/$(dbussessionservicedir) \ diff --git a/TODO b/TODO index 45d7b4ebc..90d419d77 100644 --- a/TODO +++ b/TODO @@ -3,9 +3,15 @@ F15: * swap units that are activated by one name but shown in the kernel under another are semi-broken * isolate multi-user.target doesn't start a getty@tty1 if we run it from graphical.target + https://bugzilla.redhat.com/show_bug.cgi?id=688661 * NFS, networkmanager ordering issue (PENDING) +* NM should pull in network.target (PENDING) + https://bugzilla.redhat.com/show_bug.cgi?id=692008 + +* ntpd should pull in rtc-set.target. (PENDING) + * add fstab fields to add wait timeouts, change Wants to Requires by local-fs.target * hook emergency.target into local-fs.target in some way as OnFailure with isolate @@ -15,8 +21,6 @@ F15: * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown (path: after installing inotify watches, recheck file again to fix race) -* NM should pull in network.target, ntpd should pull in rtc-set.target. - * bluetooth should be possible to disable * fix alsa mixer restore to not print error when no config is stored From cebe0d41e4d5b3fdd9d521116cc029bcb819c90d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 19:09:33 +0200 Subject: [PATCH 196/200] job: fix deserialization of jobs: do not ignore ordering --- TODO | 1 + src/job.c | 5 +++-- src/job.h | 11 ++++++----- src/manager.c | 35 +++++++++++++++++++---------------- src/unit.c | 2 +- 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/TODO b/TODO index 90d419d77..aea00d223 100644 --- a/TODO +++ b/TODO @@ -17,6 +17,7 @@ F15: * hook emergency.target into local-fs.target in some way as OnFailure with isolate * bind mounts are ignored + https://bugzilla.redhat.com/show_bug.cgi?id=682662 * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown (path: after installing inotify watches, recheck file again to fix race) diff --git a/src/job.c b/src/job.c index f5d3ff8a3..a3be7beca 100644 --- a/src/job.c +++ b/src/job.c @@ -313,7 +313,7 @@ bool job_is_runnable(Job *j) { * type. */ /* First check if there is an override */ - if (j->ignore_deps) + if (j->ignore_order) return true; if (j->type == JOB_START || @@ -694,7 +694,8 @@ static const char* const job_mode_table[_JOB_MODE_MAX] = { [JOB_FAIL] = "fail", [JOB_REPLACE] = "replace", [JOB_ISOLATE] = "isolate", - [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies" + [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies", + [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements" }; DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode); diff --git a/src/job.h b/src/job.h index 2c65d9487..2121426b3 100644 --- a/src/job.h +++ b/src/job.h @@ -64,10 +64,11 @@ enum JobState { }; enum JobMode { - JOB_FAIL, - JOB_REPLACE, - JOB_ISOLATE, - JOB_IGNORE_DEPENDENCIES, + JOB_FAIL, /* Fail if a conflicting job is already queued */ + JOB_REPLACE, /* Replace an existing conflicting job */ + JOB_ISOLATE, /* Start a unit, and stop all others */ + JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */ + JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */ _JOB_MODE_MAX, _JOB_MODE_INVALID = -1 }; @@ -130,7 +131,7 @@ struct Job { bool override:1; bool in_dbus_queue:1; bool sent_dbus_new_signal:1; - bool ignore_deps:1; + bool ignore_order:1; }; Job* job_new(Manager *m, JobType type, Unit *unit); diff --git a/src/manager.c b/src/manager.c index 6ddd40e87..9b561c4ce 100644 --- a/src/manager.c +++ b/src/manager.c @@ -1423,7 +1423,8 @@ static int transaction_add_job_and_dependencies( bool matters, bool override, bool conflicts, - bool ignore_deps, + bool ignore_requirements, + bool ignore_order, DBusError *e, Job **_ret) { Job *ret; @@ -1471,20 +1472,20 @@ static int transaction_add_job_and_dependencies( if (!(ret = transaction_add_one_job(m, type, unit, override, &is_new))) return -ENOMEM; - ret->ignore_deps = ret->ignore_deps || ignore_deps; + ret->ignore_order = ret->ignore_order || ignore_order; /* Then, add a link to the job. */ if (!job_dependency_new(by, ret, matters, conflicts)) return -ENOMEM; - if (is_new && !ignore_deps) { + if (is_new && !ignore_requirements) { Set *following; /* If we are following some other unit, make sure we * add all dependencies of everybody following. */ if (unit_following_set(ret->unit, &following) > 0) { SET_FOREACH(dep, following, i) - if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, false, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, false, override, false, false, ignore_order, e, NULL)) < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r)); if (e) @@ -1497,7 +1498,7 @@ static int transaction_add_job_and_dependencies( /* Finally, recursively add in all dependencies. */ if (type == JOB_START || type == JOB_RELOAD_OR_START) { SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { if (r != -EBADR) goto fail; @@ -1506,7 +1507,7 @@ static int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BIND_TO], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { if (r != -EBADR) goto fail; @@ -1516,7 +1517,7 @@ static int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, false, ignore_order, e, NULL)) < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r)); if (e) @@ -1524,7 +1525,7 @@ static int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_WANTS], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, false, false, ignore_order, e, NULL)) < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r)); if (e) @@ -1532,7 +1533,7 @@ static int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { if (r != -EBADR) goto fail; @@ -1542,7 +1543,7 @@ static int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, ignore_order, e, NULL)) < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r)); if (e) @@ -1550,7 +1551,7 @@ static int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTS], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, true, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, true, false, ignore_order, e, NULL)) < 0) { if (r != -EBADR) goto fail; @@ -1560,7 +1561,7 @@ static int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTED_BY], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, false, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, false, override, false, false, ignore_order, e, NULL)) < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r)); if (e) @@ -1570,7 +1571,7 @@ static int transaction_add_job_and_dependencies( } else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) { SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i) - if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { if (r != -EBADR) goto fail; @@ -1580,7 +1581,7 @@ static int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BOUND_BY], i) - if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, e, NULL)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { if (r != -EBADR) goto fail; @@ -1627,7 +1628,7 @@ static int transaction_add_isolate_jobs(Manager *m) { if (hashmap_get(m->transaction_jobs, u)) continue; - if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, false, false, NULL, NULL)) < 0) + if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, false, false, false, NULL, NULL)) < 0) log_warning("Cannot add isolate job for unit %s, ignoring: %s", u->meta.id, strerror(-r)); } @@ -1655,7 +1656,9 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove log_debug("Trying to enqueue job %s/%s/%s", unit->meta.id, job_type_to_string(type), job_mode_to_string(mode)); - if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, false, mode == JOB_IGNORE_DEPENDENCIES, e, &ret)) < 0) { + if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, false, + mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS, + mode == JOB_IGNORE_DEPENDENCIES, e, &ret)) < 0) { transaction_abort(m); return r; } diff --git a/src/unit.c b/src/unit.c index 6fd4dc6cb..e4345aeff 100644 --- a/src/unit.c +++ b/src/unit.c @@ -2242,7 +2242,7 @@ int unit_coldplug(Unit *u) { return r; if (u->meta.deserialized_job >= 0) { - if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_IGNORE_DEPENDENCIES, false, NULL, NULL)) < 0) + if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL)) < 0) return r; u->meta.deserialized_job = _JOB_TYPE_INVALID; From 4466194c43a25bc51b21226f04245131e698bb3f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 19:18:11 +0200 Subject: [PATCH 197/200] units: rename rtc-set.target to time-sync.target and pull it in by hwclock-load.service On request of Miroslav Lichvar, rename rtc-set.target to time-sync.target since usually the RTC chip isn't involved at all in NTP syncs. Also, pull it in by hwclock-load.service. --- Makefile.am | 2 +- TODO | 2 +- man/systemd.special.xml.in | 4 ++-- src/service.c | 2 +- src/special.h | 2 +- units/hwclock-load.service | 3 ++- units/{rtc-set.target => time-sync.target} | 2 +- 7 files changed, 9 insertions(+), 8 deletions(-) rename units/{rtc-set.target => time-sync.target} (92%) diff --git a/Makefile.am b/Makefile.am index 160acfb9c..2f08ceb17 100644 --- a/Makefile.am +++ b/Makefile.am @@ -232,7 +232,7 @@ dist_systemunit_DATA = \ units/reboot.target \ units/rescue.target \ units/rpcbind.target \ - units/rtc-set.target \ + units/time-sync.target \ units/shutdown.target \ units/final.target \ units/umount.target \ diff --git a/TODO b/TODO index aea00d223..470e60f4e 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,7 @@ F15: * NM should pull in network.target (PENDING) https://bugzilla.redhat.com/show_bug.cgi?id=692008 -* ntpd should pull in rtc-set.target. (PENDING) +* ntpd should pull in time-sync.target. (PENDING) * add fstab fields to add wait timeouts, change Wants to Requires by local-fs.target diff --git a/man/systemd.special.xml.in b/man/systemd.special.xml.in index 804504a83..efc4c32be 100644 --- a/man/systemd.special.xml.in +++ b/man/systemd.special.xml.in @@ -68,7 +68,7 @@ remote-fs.target, rescue.target, rpcbind.target, - rtc-set.target, + time-sync.target, runlevel2.target, runlevel3.target, runlevel4.target, @@ -399,7 +399,7 @@ - rtc-set.target + time-sync.target systemd automatically adds dependencies of type diff --git a/src/service.c b/src/service.c index a297cd911..7f8d005f0 100644 --- a/src/service.c +++ b/src/service.c @@ -286,7 +286,7 @@ static int sysv_translate_facility(const char *name, const char *filename, char "portmap", SPECIAL_RPCBIND_TARGET, "remote_fs", SPECIAL_REMOTE_FS_TARGET, "syslog", SPECIAL_SYSLOG_TARGET, - "time", SPECIAL_RTC_SET_TARGET, + "time", SPECIAL_TIME_SYNC_TARGET, /* common extensions */ "mail-transfer-agent", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, diff --git a/src/special.h b/src/special.h index 6cedf18c0..08dae11a2 100644 --- a/src/special.h +++ b/src/special.h @@ -54,7 +54,7 @@ #define SPECIAL_NSS_LOOKUP_TARGET "nss-lookup.target" /* LSB's $named */ #define SPECIAL_RPCBIND_TARGET "rpcbind.target" /* LSB's $portmap */ #define SPECIAL_SYSLOG_TARGET "syslog.target" /* LSB's $syslog; Should pull in syslog.socket or syslog.service */ -#define SPECIAL_RTC_SET_TARGET "rtc-set.target" /* LSB's $time */ +#define SPECIAL_TIME_SYNC_TARGET "time-sync.target" /* LSB's $time */ #define SPECIAL_DISPLAY_MANAGER_SERVICE "display-manager.service" /* Debian's $x-display-manager */ #define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Debian's $mail-{transport|transfer-agent */ #define SPECIAL_HTTP_DAEMON_TARGET "http-daemon.target" diff --git a/units/hwclock-load.service b/units/hwclock-load.service index 51f255e2a..f278a671a 100644 --- a/units/hwclock-load.service +++ b/units/hwclock-load.service @@ -8,9 +8,10 @@ [Unit] Description=Apply System Clock UTC Offset DefaultDependencies=no +Wants=time-sync.target Conflicts=shutdown.target After=systemd-readahead-collect.service systemd-readahead-replay.service -Before=sysinit.target shutdown.target udev.service +Before=sysinit.target shutdown.target udev.service time-sync.target [Service] Type=oneshot diff --git a/units/rtc-set.target b/units/time-sync.target similarity index 92% rename from units/rtc-set.target rename to units/time-sync.target index df4c40298..aa34ecb5f 100644 --- a/units/rtc-set.target +++ b/units/time-sync.target @@ -11,4 +11,4 @@ # implementations lacking socket/bus activation. [Unit] -Description=RTC Set +Description=System Time Synchronized From 03aea2aecd6f9d2193af5d6cf866063da8d47ad5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 19:36:06 +0200 Subject: [PATCH 198/200] cmdline: we actually want to parse the kernel cmdline in VMs, just not in containers --- src/fsck.c | 2 +- src/locale-setup.c | 2 +- src/quotacheck.c | 2 +- src/vconsole-setup.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fsck.c b/src/fsck.c index 7b809b32b..19ca75311 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -106,7 +106,7 @@ static int parse_proc_cmdline(void) { int r; size_t l; - if (detect_virtualization(NULL) > 0) + if (detect_container(NULL) > 0) return 0; if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { diff --git a/src/locale-setup.c b/src/locale-setup.c index 39b877cab..08e289d4e 100644 --- a/src/locale-setup.c +++ b/src/locale-setup.c @@ -69,7 +69,7 @@ int locale_setup(void) { zero(variables); - if (detect_virtualization(NULL) <= 0) + if (detect_container(NULL) <= 0) if ((r = parse_env_file("/proc/cmdline", WHITESPACE, #ifdef TARGET_FEDORA "LANG", &variables[VARIABLE_LANG], diff --git a/src/quotacheck.c b/src/quotacheck.c index c7b20a60e..ba12b27ca 100644 --- a/src/quotacheck.c +++ b/src/quotacheck.c @@ -35,7 +35,7 @@ static int parse_proc_cmdline(void) { int r; size_t l; - if (detect_virtualization(NULL) > 0) + if (detect_container(NULL) > 0) return 0; if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { diff --git a/src/vconsole-setup.c b/src/vconsole-setup.c index 29ce7be77..67fb7b610 100644 --- a/src/vconsole-setup.c +++ b/src/vconsole-setup.c @@ -176,7 +176,7 @@ int main(int argc, char **argv) { utf8 = is_locale_utf8(); - if (detect_virtualization(NULL) <= 0) + if (detect_container(NULL) <= 0) if ((r = parse_env_file("/proc/cmdline", WHITESPACE, #ifdef TARGET_FEDORA "SYSFONT", &vc_font, From abf96c874cd644cf6c66da95d376aa330382376e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 21:07:10 +0200 Subject: [PATCH 199/200] update TODO --- TODO | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 470e60f4e..e8c1388ed 100644 --- a/TODO +++ b/TODO @@ -33,6 +33,8 @@ Features: * serialize used job ids and max job id +* show enablement status in systemctl status + * expose monotonic timestamps on the bus and make systemd-analyze use it * write blog stories about: @@ -75,9 +77,6 @@ Features: * get rid of random file name in generator directory? /run/systemd/generator-IH1vFu -* fix SD_WARNING syslog stuff in src/sd-daemon.h to include the - LOG_DAEMON(3) facility value. Never use the LOG_KERNEL(0) facility. - * add switch to systemctl to show enabled but not running services. Or another switch that shows service that have been running since booting but aren't running anymore. From 42054a3e4496108ea64bc46084bb056e56adec6c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2011 21:28:41 +0200 Subject: [PATCH 200/200] build-sys: bump version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0025a6a4d..fa8c8ba6d 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.63) -AC_INIT([systemd],[23],[systemd-devel@lists.freedesktop.org]) +AC_INIT([systemd],[24],[systemd-devel@lists.freedesktop.org]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h])