diff --git a/SOURCES/0233-units-serial-getty-.service-add-Install-section.patch b/SOURCES/0233-units-serial-getty-.service-add-Install-section.patch index ec8132e..dd560ff 100644 --- a/SOURCES/0233-units-serial-getty-.service-add-Install-section.patch +++ b/SOURCES/0233-units-serial-getty-.service-add-Install-section.patch @@ -1,4 +1,4 @@ -From 2e1c925693871dfba76845b82bb653dc09b2de97 Mon Sep 17 00:00:00 2001 +From 8ade7cd519f3cdccc81ed8c2fb2f72df48a191d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 24 Feb 2014 08:02:28 -0500 Subject: [PATCH] units/serial-getty@.service: add [Install] section @@ -8,7 +8,7 @@ specific gettys, and also mirrors getty@.service. http://lists.freedesktop.org/archives/systemd-devel/2014-February/017329.html -Resolves: #1118230 +Resolves: #1083936 --- units/serial-getty@.service.m4 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SOURCES/0234-units-order-network-online.target-after-network.targ.patch b/SOURCES/0234-units-order-network-online.target-after-network.targ.patch index 361bc19..4390f79 100644 --- a/SOURCES/0234-units-order-network-online.target-after-network.targ.patch +++ b/SOURCES/0234-units-order-network-online.target-after-network.targ.patch @@ -1,9 +1,9 @@ -From 8ace570670d71d13fe604e7cf9d264de245ac981 Mon Sep 17 00:00:00 2001 +From dda9057e8ee63f2e525333bf7d606f22bce0f7f5 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Mon, 21 Jul 2014 15:13:15 +0200 Subject: [PATCH] units: order network-online.target after network.target -Resolves: #1121650 +Resolves: #1072431 --- units/network-online.target | 1 + 1 file changed, 1 insertion(+) diff --git a/SOURCES/0235-util-consider-both-fuse.glusterfs-and-glusterfs-netw.patch b/SOURCES/0235-util-consider-both-fuse.glusterfs-and-glusterfs-netw.patch new file mode 100644 index 0000000..5cbe8ca --- /dev/null +++ b/SOURCES/0235-util-consider-both-fuse.glusterfs-and-glusterfs-netw.patch @@ -0,0 +1,36 @@ +From f8615ebc34fb1a960a1bd946650a8c15a9a347fa Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 25 Mar 2014 01:46:24 +0100 +Subject: [PATCH] util: consider both fuse.glusterfs and glusterfs network file + systems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Based on a similar patch by Lukáš Nykrýn. + +Resolves: #1080229 +--- + src/shared/util.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/shared/util.c b/src/shared/util.c +index 090a204..2974c2a 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -1625,7 +1625,14 @@ bool fstype_is_network(const char *fstype) { + "nfs\0" + "nfs4\0" + "gfs\0" +- "gfs2\0"; ++ "gfs2\0" ++ "glusterfs\0"; ++ ++ const char *x; ++ ++ x = startswith(fstype, "fuse."); ++ if (x) ++ fstype = x; + + return nulstr_contains(table, fstype); + } diff --git a/SOURCES/0235-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch b/SOURCES/0235-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch deleted file mode 100644 index 005ef88..0000000 --- a/SOURCES/0235-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 3a45f6df7e5d37c1eb0c6e83b74093ef717942e6 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 27 Aug 2014 21:42:20 +0200 -Subject: [PATCH] util: fix minimal race where we might miss SIGTERMs when - forking off an agent - -Before forking, block all signals, and unblock them afterwards. This way -the child will have them blocked, and we won't lose them. - -(cherry picked from commit 8a7c93d858c342744adf481565d8bb03b9713dcf) - -Related: #1134818 ---- - src/shared/util.c | 29 +++++++++++++++++++++++------ - 1 file changed, 23 insertions(+), 6 deletions(-) - -diff --git a/src/shared/util.c b/src/shared/util.c -index 090a204..0fcc130 100644 ---- a/src/shared/util.c -+++ b/src/shared/util.c -@@ -4991,9 +4991,9 @@ int fd_inc_rcvbuf(int fd, size_t n) { - } - - int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) { -- pid_t parent_pid, agent_pid; -- int fd; - bool stdout_is_tty, stderr_is_tty; -+ pid_t parent_pid, agent_pid; -+ sigset_t ss, saved_ss; - unsigned n, i; - va_list ap; - char **l; -@@ -5001,16 +5001,25 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa - assert(pid); - assert(path); - -- parent_pid = getpid(); -- - /* Spawns a temporary TTY agent, making sure it goes away when - * we go away */ - -+ parent_pid = getpid(); -+ -+ /* First we temporarily block all signals, so that the new -+ * child has them blocked initially. This way, we can be sure -+ * that SIGTERMs are not lost we might send to the agent. */ -+ assert_se(sigfillset(&ss) >= 0); -+ assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0); -+ - agent_pid = fork(); -- if (agent_pid < 0) -+ if (agent_pid < 0) { -+ assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0); - return -errno; -+ } - - if (agent_pid != 0) { -+ assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0); - *pid = agent_pid; - return 0; - } -@@ -5021,8 +5030,14 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa - if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) - _exit(EXIT_FAILURE); - -+ /* Make sure we actually can kill the agent, if we need to, in -+ * case somebody invoked us from a shell script that trapped -+ * SIGTERM or so... */ -+ reset_all_signal_handlers(); -+ reset_signal_mask(); -+ - /* Check whether our parent died before we were able -- * to set the death signal */ -+ * to set the death signal and unblock the signals */ - if (getppid() != parent_pid) - _exit(EXIT_SUCCESS); - -@@ -5033,6 +5048,8 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa - stderr_is_tty = isatty(STDERR_FILENO); - - if (!stdout_is_tty || !stderr_is_tty) { -+ int fd; -+ - /* Detach from stdout/stderr. and reopen - * /dev/tty for them. This is important to - * ensure that when systemctl is started via diff --git a/SOURCES/0236-core-make-StopWhenUnneeded-work-in-conjunction-with-.patch b/SOURCES/0236-core-make-StopWhenUnneeded-work-in-conjunction-with-.patch new file mode 100644 index 0000000..a7cb5f3 --- /dev/null +++ b/SOURCES/0236-core-make-StopWhenUnneeded-work-in-conjunction-with-.patch @@ -0,0 +1,43 @@ +From bb586b571661bd77cafe0824efecdba502c99a98 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 13 Feb 2014 02:12:27 +0100 +Subject: [PATCH] core: make StopWhenUnneeded work in conjunction with units + that fail during their start job + +https://bugzilla.redhat.com/show_bug.cgi?id=997031 + +Resolves: #986949 +--- + src/core/unit.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index a4e6c18..17792d1 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1455,7 +1455,9 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su + * sucessfully, since there's no change of state in that case. Which is + * why it is handled in service_set_state() */ + if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) { +- ExecContext *ec = unit_get_exec_context(u); ++ ExecContext *ec; ++ ++ ec = unit_get_exec_context(u); + if (ec && exec_context_may_touch_console(ec)) { + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) { + m->n_on_console --; +@@ -1551,12 +1553,11 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su + } + + /* stop unneeded units regardless if going down was expected or not */ +- if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) ++ if (UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + check_unneeded_dependencies(u); + + if (ns != os && ns == UNIT_FAILED) { +- log_notice_unit(u->id, +- "Unit %s entered failed state.", u->id); ++ log_notice_unit(u->id, "Unit %s entered failed state.", u->id); + unit_start_on_failure(u); + } + } diff --git a/SOURCES/0236-util-reset-signals-when-we-fork-off-agents.patch b/SOURCES/0236-util-reset-signals-when-we-fork-off-agents.patch deleted file mode 100644 index 04801b9..0000000 --- a/SOURCES/0236-util-reset-signals-when-we-fork-off-agents.patch +++ /dev/null @@ -1,70 +0,0 @@ -From c0e227a9fbb99cc9d437f8ac695c93c72c92e11b Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 26 Aug 2014 21:04:21 +0200 -Subject: [PATCH] util: reset signals when we fork off agents - -If we invoke agents, we should make sure we actually can kill them -again. I mean, it's probably not our job to cleanup the signals if our -tools are invoked in weird contexts, but at least we should make sure, -that the subprocesses we invoke and intend to control work as intended. - -Also see: - -http://lists.freedesktop.org/archives/systemd-devel/2014-August/022460.html - -(cherry picked from commit 8a7c93d858c342744adf481565d8bb03b9713dcf) - -Resolves: #1134818 ---- - src/shared/util.c | 18 ++++++++++++++++++ - src/shared/util.h | 1 + - 2 files changed, 19 insertions(+) - -diff --git a/src/shared/util.c b/src/shared/util.c -index 0fcc130..3620c0a 100644 ---- a/src/shared/util.c -+++ b/src/shared/util.c -@@ -935,6 +935,18 @@ int reset_all_signal_handlers(void) { - return 0; - } - -+int reset_signal_mask(void) { -+ sigset_t ss; -+ -+ if (sigemptyset(&ss) < 0) -+ return -errno; -+ -+ if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) -+ return -errno; -+ -+ return 0; -+} -+ - char *strstrip(char *s) { - char *e; - -@@ -5044,6 +5056,12 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa - /* Don't leak fds to the agent */ - close_all_fds(except, n_except); - -+ /* Make sure we actually can kill the agent, if we need to, in -+ * case somebody invoked us from a shell script that trapped -+ * SIGTERM or so... */ -+ reset_all_signal_handlers(); -+ reset_signal_mask(); -+ - stdout_is_tty = isatty(STDOUT_FILENO); - stderr_is_tty = isatty(STDERR_FILENO); - -diff --git a/src/shared/util.h b/src/shared/util.h -index 3a4bc98..cf935ce 100644 ---- a/src/shared/util.h -+++ b/src/shared/util.h -@@ -206,6 +206,7 @@ int readlink_and_make_absolute(const char *p, char **r); - int readlink_and_canonicalize(const char *p, char **r); - - int reset_all_signal_handlers(void); -+int reset_signal_mask(void); - - char *strstrip(char *s); - char *delete_chars(char *s, const char *bad); diff --git a/SOURCES/0237-cgroups-agent-down-grade-log-level.patch b/SOURCES/0237-cgroups-agent-down-grade-log-level.patch new file mode 100644 index 0000000..5cc9b97 --- /dev/null +++ b/SOURCES/0237-cgroups-agent-down-grade-log-level.patch @@ -0,0 +1,41 @@ +From b0010d76a8c56900d15fab8ac1ed94d364d1e566 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Wed, 23 Jul 2014 14:08:18 +0200 +Subject: [PATCH] cgroups-agent: down-grade log level + +(cherry picked from commit 844de4355592259eebcffddfc38c63266e451cb6) + +Conflicts: + src/cgroups-agent/cgroups-agent.c + +Resolves: #1044386 +--- + src/cgroups-agent/cgroups-agent.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c +index a47949a..43b9b3a 100644 +--- a/src/cgroups-agent/cgroups-agent.c ++++ b/src/cgroups-agent/cgroups-agent.c +@@ -50,7 +50,11 @@ int main(int argc, char *argv[]) { + + bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error); + if (!bus) { +- log_warning("Failed to get D-Bus connection: %s", bus_error_message(&error)); ++ log_warning("Failed to get D-Bus connection: %s", strerror(-r)); ++ /* If we couldn't connect we assume this was triggered ++ * while systemd got restarted/transitioned from ++ * initrd to the system, so let's ignore this */ ++ log_debug("Failed to get D-Bus connection: %s", strerror(-r)); + goto finish; + } + +@@ -73,7 +77,7 @@ int main(int argc, char *argv[]) { + } + + if (!dbus_connection_send(bus, m, NULL)) { +- log_error("Failed to send signal message on private connection."); ++ log_debug("Failed to send signal message on private connection."); + goto finish; + } + diff --git a/SOURCES/0237-socket-add-SocketUser-and-SocketGroup-for-chown-ing-.patch b/SOURCES/0237-socket-add-SocketUser-and-SocketGroup-for-chown-ing-.patch deleted file mode 100644 index 5b6cfca..0000000 --- a/SOURCES/0237-socket-add-SocketUser-and-SocketGroup-for-chown-ing-.patch +++ /dev/null @@ -1,610 +0,0 @@ -From efd4bdec3cd568439eb9b0f0a555b4016da12efe Mon Sep 17 00:00:00 2001 -From: Michal Sekletar -Date: Tue, 24 Jun 2014 14:50:26 +0200 -Subject: [PATCH] socket: add SocketUser= and SocketGroup= for chown()ing - sockets in the file system - -This is relatively complex, as we cannot invoke NSS from PID 1, and thus -need to fork a helper process temporarily. - -(cherry picked from commit 3900e5fdff688dc3c273f177d9d913b7389d5561) - -Resolves: #1111761 ---- - man/systemd.socket.xml | 38 ++++-- - src/core/dbus-socket.c | 8 +- - src/core/load-fragment-gperf.gperf.m4 | 4 +- - src/core/socket.c | 220 +++++++++++++++++++++++++++------- - src/core/socket.h | 5 + - src/shared/exit-status.c | 4 + - src/shared/exit-status.h | 3 +- - 7 files changed, 224 insertions(+), 58 deletions(-) - -diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml -index 570a6fb..d146b3b 100644 ---- a/man/systemd.socket.xml -+++ b/man/systemd.socket.xml -@@ -372,16 +372,21 @@ - - - -- DirectoryMode= -- If listening on a file -- system socket or FIFO, the parent -- directories are automatically created -- if needed. This option specifies the -- file system access mode used when -- creating these directories. Takes an -- access mode in octal -- notation. Defaults to -- 0755. -+ SocketUser= -+ SocketGroup= -+ -+ Takes a UNIX -+ user/group name. When specified -+ all AF_UNIX sockets and FIFO nodes in -+ the file system are owned by the -+ specified user and group. If unset -+ (the default), the nodes are owned by -+ the root user/group (if run in system -+ context) or the invoking user/group -+ (if run in user context). If only a -+ user is specified but no group, then -+ the group is derived from the user's -+ default group. - - - -@@ -396,6 +401,19 @@ - - - -+ DirectoryMode= -+ If listening on a file -+ system socket or FIFO, the parent -+ directories are automatically created -+ if needed. This option specifies the -+ file system access mode used when -+ creating these directories. Takes an -+ access mode in octal -+ notation. Defaults to -+ 0755. -+ -+ -+ - Accept= - Takes a boolean - argument. If true, a service instance -diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c -index 30c4b63..870bcdc 100644 ---- a/src/core/dbus-socket.c -+++ b/src/core/dbus-socket.c -@@ -44,8 +44,10 @@ - BUS_CGROUP_CONTEXT_INTERFACE \ - " \n" \ - " \n" \ -- " \n" \ -+ " \n" \ -+ " \n" \ - " \n" \ -+ " \n" \ - " \n" \ - " \n" \ - " \n" \ -@@ -172,8 +174,10 @@ static const BusProperty bus_socket_properties[] = { - BUS_EXEC_COMMAND_PROPERTY("ExecStopPost", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_POST]), true ), - { "ControlPID", bus_property_append_pid, "u", offsetof(Socket, control_pid) }, - { "BindToDevice", bus_property_append_string, "s", offsetof(Socket, bind_to_device), true }, -- { "DirectoryMode", bus_property_append_mode, "u", offsetof(Socket, directory_mode) }, -+ { "SocketUser", bus_property_append_string, "s", offsetof(Socket, user), true }, -+ { "SocketGroup", bus_property_append_string, "s", offsetof(Socket, group), true }, - { "SocketMode", bus_property_append_mode, "u", offsetof(Socket, socket_mode) }, -+ { "DirectoryMode", bus_property_append_mode, "u", offsetof(Socket, directory_mode) }, - { "Accept", bus_property_append_bool, "b", offsetof(Socket, accept) }, - { "KeepAlive", bus_property_append_bool, "b", offsetof(Socket, keep_alive) }, - { "Priority", bus_property_append_int, "i", offsetof(Socket, priority) }, -diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 -index d65bcc1..0991cb9 100644 ---- a/src/core/load-fragment-gperf.gperf.m4 -+++ b/src/core/load-fragment-gperf.gperf.m4 -@@ -193,8 +193,10 @@ Socket.ExecStartPost, config_parse_exec, SOCKET_EXEC - Socket.ExecStopPre, config_parse_exec, SOCKET_EXEC_STOP_PRE, offsetof(Socket, exec_command) - Socket.ExecStopPost, config_parse_exec, SOCKET_EXEC_STOP_POST, offsetof(Socket, exec_command) - Socket.TimeoutSec, config_parse_sec, 0, offsetof(Socket, timeout_usec) --Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode) -+Socket.SocketUser, config_parse_unit_string_printf, 0, offsetof(Socket, user) -+Socket.SocketGroup, config_parse_unit_string_printf, 0, offsetof(Socket, group) - Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode) -+Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode) - Socket.Accept, config_parse_bool, 0, offsetof(Socket, accept) - Socket.MaxConnections, config_parse_unsigned, 0, offsetof(Socket, max_connections) - Socket.KeepAlive, config_parse_bool, 0, offsetof(Socket, keep_alive) -diff --git a/src/core/socket.c b/src/core/socket.c -index e673f38..32e0d35 100644 ---- a/src/core/socket.c -+++ b/src/core/socket.c -@@ -54,6 +54,7 @@ - static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { - [SOCKET_DEAD] = UNIT_INACTIVE, - [SOCKET_START_PRE] = UNIT_ACTIVATING, -+ [SOCKET_START_CHOWN] = UNIT_ACTIVATING, - [SOCKET_START_POST] = UNIT_ACTIVATING, - [SOCKET_LISTENING] = UNIT_ACTIVE, - [SOCKET_RUNNING] = UNIT_ACTIVE, -@@ -147,6 +148,8 @@ static void socket_done(Unit *u) { - free(s->smack); - free(s->smack_ip_in); - free(s->smack_ip_out); -+ free(s->user); -+ free(s->group); - - unit_unwatch_timer(u, &s->timer_watch); - } -@@ -527,6 +530,16 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { - "%sSmackLabelIPOut: %s\n", - prefix, s->smack_ip_out); - -+ if (s->user) -+ fprintf(f, -+ "%sOwnerUser: %s\n", -+ prefix, s->user); -+ -+ if (s->group) -+ fprintf(f, -+ "%sOwnerGroup: %s\n", -+ prefix, s->user); -+ - LIST_FOREACH(port, p, s->ports) { - - if (p->type == SOCKET_SOCKET) { -@@ -1100,6 +1113,7 @@ static void socket_set_state(Socket *s, SocketState state) { - s->state = state; - - if (state != SOCKET_START_PRE && -+ state != SOCKET_START_CHOWN && - state != SOCKET_START_POST && - state != SOCKET_STOP_PRE && - state != SOCKET_STOP_PRE_SIGTERM && -@@ -1116,7 +1130,8 @@ static void socket_set_state(Socket *s, SocketState state) { - if (state != SOCKET_LISTENING) - socket_unwatch_fds(s); - -- if (state != SOCKET_START_POST && -+ if (state != SOCKET_START_CHOWN && -+ state != SOCKET_START_POST && - state != SOCKET_LISTENING && - state != SOCKET_RUNNING && - state != SOCKET_STOP_PRE && -@@ -1143,6 +1158,7 @@ static int socket_coldplug(Unit *u) { - if (s->deserialized_state != s->state) { - - if (s->deserialized_state == SOCKET_START_PRE || -+ s->deserialized_state == SOCKET_START_CHOWN || - s->deserialized_state == SOCKET_START_POST || - s->deserialized_state == SOCKET_STOP_PRE || - s->deserialized_state == SOCKET_STOP_PRE_SIGTERM || -@@ -1163,7 +1179,8 @@ static int socket_coldplug(Unit *u) { - return r; - } - -- if (s->deserialized_state == SOCKET_START_POST || -+ if (s->deserialized_state == SOCKET_START_CHOWN || -+ s->deserialized_state == SOCKET_START_POST || - s->deserialized_state == SOCKET_LISTENING || - s->deserialized_state == SOCKET_RUNNING || - s->deserialized_state == SOCKET_STOP_PRE || -@@ -1185,7 +1202,7 @@ static int socket_coldplug(Unit *u) { - static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { - pid_t pid; - int r; -- char **argv; -+ _cleanup_strv_free_ char **argv = NULL; - - assert(s); - assert(c); -@@ -1216,11 +1233,11 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { - NULL, - &pid); - -- strv_free(argv); - if (r < 0) - goto fail; - -- if ((r = unit_watch_pid(UNIT(s), pid)) < 0) -+ r = unit_watch_pid(UNIT(s), pid); -+ if (r < 0) - /* FIXME: we need to do something here */ - goto fail; - -@@ -1234,6 +1251,88 @@ fail: - return r; - } - -+static int socket_chown(Socket *s, pid_t *_pid) { -+ pid_t pid; -+ int r; -+ -+ r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); -+ if (r < 0) -+ goto fail; -+ -+ pid = fork(); -+ if (pid < 0) -+ return -errno; -+ -+ if (pid == 0) { -+ SocketPort *p; -+ uid_t uid = (uid_t) -1; -+ gid_t gid = (gid_t) -1; -+ int ret; -+ -+ default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); -+ ignore_signals(SIGPIPE, -1); -+ log_forget_fds(); -+ -+ if (!isempty(s->user)) { -+ const char *user = s->user; -+ -+ r = get_user_creds(&user, &uid, &gid, NULL, NULL); -+ if (r < 0) { -+ ret = EXIT_USER; -+ goto fail_child; -+ } -+ } -+ -+ if (!isempty(s->group)) { -+ const char *group = s->group; -+ -+ r = get_group_creds(&group, &gid); -+ if (r < 0) { -+ ret = EXIT_GROUP; -+ goto fail_child; -+ } -+ } -+ -+ LIST_FOREACH(port, p, s->ports) { -+ const char *path = NULL; -+ -+ if (p->type == SOCKET_SOCKET) -+ path = socket_address_get_path(&p->address); -+ else if (p->type == SOCKET_FIFO) -+ path = p->path; -+ -+ if (!path) -+ continue; -+ -+ if (chown(path, uid, gid) < 0) { -+ r = -errno; -+ ret = EXIT_CHOWN; -+ goto fail_child; -+ } -+ } -+ -+ _exit(0); -+ -+ fail_child: -+ log_open(); -+ log_error("Failed to chown socket at step %s: %s", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD), strerror(-r)); -+ -+ _exit(ret); -+ } -+ -+ r = unit_watch_pid(UNIT(s), pid); -+ if (r < 0) -+ goto fail; -+ -+ *_pid = pid; -+ -+ return 0; -+ -+fail: -+ unit_unwatch_timer(UNIT(s), &s->timer_watch); -+ return r; -+} -+ - static void socket_enter_dead(Socket *s, SocketResult f) { - assert(s); - -@@ -1256,9 +1355,11 @@ static void socket_enter_stop_post(Socket *s, SocketResult f) { - socket_unwatch_control_pid(s); - - s->control_command_id = SOCKET_EXEC_STOP_POST; -+ s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST]; - -- if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) { -- if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) -+ if (s->control_command) { -+ r = socket_spawn(s, s->control_command, &s->control_pid); -+ if (r < 0) - goto fail; - - socket_set_state(s, SOCKET_STOP_POST); -@@ -1326,9 +1427,11 @@ static void socket_enter_stop_pre(Socket *s, SocketResult f) { - socket_unwatch_control_pid(s); - - s->control_command_id = SOCKET_EXEC_STOP_PRE; -+ s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE]; - -- if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) { -- if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) -+ if (s->control_command) { -+ r = socket_spawn(s, s->control_command, &s->control_pid); -+ if (r < 0) - goto fail; - - socket_set_state(s, SOCKET_STOP_PRE); -@@ -1376,15 +1479,13 @@ static void socket_enter_start_post(Socket *s) { - } - - socket_unwatch_control_pid(s); -- - s->control_command_id = SOCKET_EXEC_START_POST; -+ s->control_command = s->exec_command[SOCKET_EXEC_START_POST]; - -- if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) { -+ if (s->control_command) { - r = socket_spawn(s, s->control_command, &s->control_pid); - if (r < 0) { -- log_warning_unit(UNIT(s)->id, -- "%s failed to run 'start-post' task: %s", -- UNIT(s)->id, strerror(-r)); -+ log_warning_unit(UNIT(s)->id, "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r)); - goto fail; - } - -@@ -1398,6 +1499,38 @@ fail: - socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); - } - -+static void socket_enter_start_chown(Socket *s) { -+ int r; -+ -+ assert(s); -+ -+ r = socket_open_fds(s); -+ if (r < 0) { -+ log_warning_unit(UNIT(s)->id, "%s failed to listen on sockets: %s", UNIT(s)->id, strerror(-r)); -+ goto fail; -+ } -+ -+ if (!isempty(s->user) || !isempty(s->group)) { -+ socket_unwatch_control_pid(s); -+ s->control_command_id = SOCKET_EXEC_START_CHOWN; -+ s->control_command = NULL; -+ -+ r = socket_chown(s, &s->control_pid); -+ if (r < 0) { -+ log_warning_unit(UNIT(s)->id, "%s failed to fork 'start-chown' task: %s", UNIT(s)->id, strerror(-r)); -+ goto fail; -+ } -+ -+ socket_set_state(s, SOCKET_START_CHOWN); -+ } else -+ socket_enter_start_post(s); -+ -+ return; -+ -+fail: -+ socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); -+} -+ - static void socket_enter_start_pre(Socket *s) { - int r; - assert(s); -@@ -1405,21 +1538,21 @@ static void socket_enter_start_pre(Socket *s) { - socket_unwatch_control_pid(s); - - s->control_command_id = SOCKET_EXEC_START_PRE; -+ s->control_command = s->exec_command[SOCKET_EXEC_START_PRE]; - -- if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) { -- if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) -+ if (s->control_command) { -+ r = socket_spawn(s, s->control_command, &s->control_pid); -+ if (r < 0) - goto fail; - - socket_set_state(s, SOCKET_START_PRE); - } else -- socket_enter_start_post(s); -+ socket_enter_start_chown(s); - - return; - - fail: -- log_warning_unit(UNIT(s)->id, -- "%s failed to run 'start-pre' task: %s", -- UNIT(s)->id, strerror(-r)); -+ log_warning_unit(UNIT(s)->id, "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r)); - socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); - } - -@@ -1609,6 +1742,7 @@ static int socket_start(Unit *u) { - return -EAGAIN; - - if (s->state == SOCKET_START_PRE || -+ s->state == SOCKET_START_CHOWN || - s->state == SOCKET_START_POST) - return 0; - -@@ -1669,6 +1803,7 @@ static int socket_stop(Unit *u) { - /* If there's already something running we go directly into - * kill mode. */ - if (s->state == SOCKET_START_PRE || -+ s->state == SOCKET_START_CHOWN || - s->state == SOCKET_START_POST) { - socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS); - return -EAGAIN; -@@ -2098,11 +2233,18 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) { - - case SOCKET_START_PRE: - if (f == SOCKET_SUCCESS) -- socket_enter_start_post(s); -+ socket_enter_start_chown(s); - else - socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f); - break; - -+ case SOCKET_START_CHOWN: -+ if (f == SOCKET_SUCCESS) -+ socket_enter_start_post(s); -+ else -+ socket_enter_stop_pre(s, f); -+ break; -+ - case SOCKET_START_POST: - if (f == SOCKET_SUCCESS) - socket_enter_listening(s); -@@ -2141,65 +2283,53 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) { - switch (s->state) { - - case SOCKET_START_PRE: -- log_warning_unit(u->id, -- "%s starting timed out. Terminating.", u->id); -+ log_warning_unit(u->id, "%s starting timed out. Terminating.", u->id); - socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT); - break; - -+ case SOCKET_START_CHOWN: - case SOCKET_START_POST: -- log_warning_unit(u->id, -- "%s starting timed out. Stopping.", u->id); -+ log_warning_unit(u->id, "%s starting timed out. Stopping.", u->id); - socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT); - break; - - case SOCKET_STOP_PRE: -- log_warning_unit(u->id, -- "%s stopping timed out. Terminating.", u->id); -+ log_warning_unit(u->id, "%s stopping timed out. Terminating.", u->id); - socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT); - break; - - case SOCKET_STOP_PRE_SIGTERM: - if (s->kill_context.send_sigkill) { -- log_warning_unit(u->id, -- "%s stopping timed out. Killing.", u->id); -+ log_warning_unit(u->id, "%s stopping timed out. Killing.", u->id); - socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT); - } else { -- log_warning_unit(u->id, -- "%s stopping timed out. Skipping SIGKILL. Ignoring.", -- u->id); -+ log_warning_unit(u->id, "%s stopping timed out. Skipping SIGKILL. Ignoring.", u->id); - socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT); - } - break; - - case SOCKET_STOP_PRE_SIGKILL: -- log_warning_unit(u->id, -- "%s still around after SIGKILL. Ignoring.", u->id); -+ log_warning_unit(u->id, "%s still around after SIGKILL. Ignoring.", u->id); - socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT); - break; - - case SOCKET_STOP_POST: -- log_warning_unit(u->id, -- "%s stopping timed out (2). Terminating.", u->id); -+ log_warning_unit(u->id, "%s stopping timed out (2). Terminating.", u->id); - socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT); - break; - - case SOCKET_FINAL_SIGTERM: - if (s->kill_context.send_sigkill) { -- log_warning_unit(u->id, -- "%s stopping timed out (2). Killing.", u->id); -+ log_warning_unit(u->id, "%s stopping timed out (2). Killing.", u->id); - socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT); - } else { -- log_warning_unit(u->id, -- "%s stopping timed out (2). Skipping SIGKILL. Ignoring.", -- u->id); -+ log_warning_unit(u->id, "%s stopping timed out (2). Skipping SIGKILL. Ignoring.", u->id); - socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT); - } - break; - - case SOCKET_FINAL_SIGKILL: -- log_warning_unit(u->id, -- "%s still around after SIGKILL (2). Entering failed mode.", -- u->id); -+ log_warning_unit(u->id, "%s still around after SIGKILL (2). Entering failed mode.", u->id); - socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT); - break; - -@@ -2333,6 +2463,7 @@ static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) { - static const char* const socket_state_table[_SOCKET_STATE_MAX] = { - [SOCKET_DEAD] = "dead", - [SOCKET_START_PRE] = "start-pre", -+ [SOCKET_START_CHOWN] = "start-chown", - [SOCKET_START_POST] = "start-post", - [SOCKET_LISTENING] = "listening", - [SOCKET_RUNNING] = "running", -@@ -2349,6 +2480,7 @@ DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState); - - static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { - [SOCKET_EXEC_START_PRE] = "StartPre", -+ [SOCKET_EXEC_START_CHOWN] = "StartChown", - [SOCKET_EXEC_START_POST] = "StartPost", - [SOCKET_EXEC_STOP_PRE] = "StopPre", - [SOCKET_EXEC_STOP_POST] = "StopPost" -diff --git a/src/core/socket.h b/src/core/socket.h -index 3d7eadc..6a24883 100644 ---- a/src/core/socket.h -+++ b/src/core/socket.h -@@ -32,6 +32,7 @@ typedef struct Socket Socket; - typedef enum SocketState { - SOCKET_DEAD, - SOCKET_START_PRE, -+ SOCKET_START_CHOWN, - SOCKET_START_POST, - SOCKET_LISTENING, - SOCKET_RUNNING, -@@ -48,6 +49,7 @@ typedef enum SocketState { - - typedef enum SocketExecCommand { - SOCKET_EXEC_START_PRE, -+ SOCKET_EXEC_START_CHOWN, - SOCKET_EXEC_START_POST, - SOCKET_EXEC_STOP_PRE, - SOCKET_EXEC_STOP_POST, -@@ -151,6 +153,9 @@ struct Socket { - char *smack; - char *smack_ip_in; - char *smack_ip_out; -+ -+ char *user; -+ char *group; - }; - - /* Called from the service code when collecting fds */ -diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c -index 45131f2..f15fdba 100644 ---- a/src/shared/exit-status.c -+++ b/src/shared/exit-status.c -@@ -130,6 +130,10 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) { - - case EXIT_SECCOMP: - return "SECCOMP"; -+ -+ case EXIT_CHOWN: -+ return "CHOWN"; -+ - } - } - -diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h -index 1f035a3..52dd3d0 100644 ---- a/src/shared/exit-status.h -+++ b/src/shared/exit-status.h -@@ -67,7 +67,8 @@ typedef enum ExitStatus { - EXIT_NETWORK, - EXIT_NAMESPACE, - EXIT_NO_NEW_PRIVILEGES, -- EXIT_SECCOMP -+ EXIT_SECCOMP, -+ EXIT_CHOWN - } ExitStatus; - - typedef enum ExitStatusLevel { diff --git a/SOURCES/0238-random-seed-raise-POOL_SIZE_MIN-constant-to-1024.patch b/SOURCES/0238-random-seed-raise-POOL_SIZE_MIN-constant-to-1024.patch new file mode 100644 index 0000000..ccf36f5 --- /dev/null +++ b/SOURCES/0238-random-seed-raise-POOL_SIZE_MIN-constant-to-1024.patch @@ -0,0 +1,23 @@ +From 20436a1eb3a468b7bc32fe1d36cb7c4029519052 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 24 Jul 2014 11:17:36 +0200 +Subject: [PATCH] random-seed: raise POOL_SIZE_MIN constant to 1024 + +Resolves: #1066517 +--- + src/random-seed/random-seed.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c +index af79ecf..8b7bfbb 100644 +--- a/src/random-seed/random-seed.c ++++ b/src/random-seed/random-seed.c +@@ -29,7 +29,7 @@ + #include "util.h" + #include "mkdir.h" + +-#define POOL_SIZE_MIN 512 ++#define POOL_SIZE_MIN 1024 + + int main(int argc, char *argv[]) { + _cleanup_close_ int seed_fd = -1, random_fd = -1; diff --git a/SOURCES/0238-rules-don-t-enable-usb-pm-for-Avocent-devices.patch b/SOURCES/0238-rules-don-t-enable-usb-pm-for-Avocent-devices.patch deleted file mode 100644 index 0e9f0c3..0000000 --- a/SOURCES/0238-rules-don-t-enable-usb-pm-for-Avocent-devices.patch +++ /dev/null @@ -1,30 +0,0 @@ -From dcfab2c436b48d87cdfd2b9fa525e07816322b96 Mon Sep 17 00:00:00 2001 -From: Tom Hirst -Date: Wed, 25 Jun 2014 11:57:11 +0000 -Subject: [PATCH] rules: don't enable usb pm for Avocent devices - -The Avocent KVM over IP devices doesn't work correctly with USB power -management enabled. - -(cherry-picked from 52fb538361053f8c4abce0e40cd0bae3d28ceb16) - -Resolves: #1176736 ---- - rules/42-usb-hid-pm.rules | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/rules/42-usb-hid-pm.rules b/rules/42-usb-hid-pm.rules -index 3fd6e8a..483a781 100644 ---- a/rules/42-usb-hid-pm.rules -+++ b/rules/42-usb-hid-pm.rules -@@ -11,10 +11,6 @@ ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Mouse", ATTR{serial}== - ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Tablet", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto" - ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Keyboard", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto" - --# Catch-all for Avocent HID devices. Keyed off interface in order to only --# trigger on HID class devices. --ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0624", ATTR{bInterfaceClass}=="03", TEST=="../power/control", ATTR{../power/control}="auto" -- - # Dell DRAC 4 - ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="2500", TEST=="power/control", ATTR{power/control}="auto" - diff --git a/SOURCES/0239-core-introduce-new-Delegate-yes-no-property-controll.patch b/SOURCES/0239-core-introduce-new-Delegate-yes-no-property-controll.patch deleted file mode 100644 index 0e1f819..0000000 --- a/SOURCES/0239-core-introduce-new-Delegate-yes-no-property-controll.patch +++ /dev/null @@ -1,385 +0,0 @@ -From 80753fa3c0622fd8117c64e1ed2d7841edee3b00 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Thu, 13 Nov 2014 14:34:42 +0100 -Subject: [PATCH] core: introduce new Delegate=yes/no property controlling - creation of cgroup subhierarchies - -For priviliged units this resource control property ensures that the -processes have all controllers systemd manages enabled. - -For unpriviliged services (those with User= set) this ensures that -access rights to the service cgroup is granted to the user in question, -to create further subgroups. Note that this only applies to the -name=systemd hierarchy though, as access to other controllers is not -safe for unpriviliged processes. - -Delegate=yes should be set for container scopes where a systemd instance -inside the container shall manage the hierarchies below its own cgroup -and have access to all controllers. - -Delegate=yes should also be set for user@.service, so that systemd ---user can run, controlling its own cgroup tree. - -This commit changes machined, systemd-nspawn@.service and user@.service -to set this boolean, in order to ensure that container management will -just work, and the user systemd instance can run fine. - -(cherry picked from a931ad47a8623163a29d898224d8a8c1177ffdaf) - -Resolves: #1179715 ---- - man/systemd.resource-control.xml | 14 ++++++++++++ - src/core/cgroup.c | 19 +++++++++++++++-- - src/core/cgroup.h | 2 ++ - src/core/dbus-cgroup.c | 40 +++++++++++++++++++++++++++++++++++ - src/core/execute.c | 23 +++++++++++++++++--- - src/core/execute.h | 2 ++ - src/core/load-fragment-gperf.gperf.m4 | 3 ++- - src/core/mount.c | 1 + - src/core/service.c | 1 + - src/core/socket.c | 1 + - src/core/swap.c | 1 + - src/machine/machined-dbus.c | 10 +++++++++ - src/shared/cgroup-util.h | 3 ++- - units/systemd-nspawn@.service.in | 1 + - 14 files changed, 114 insertions(+), 7 deletions(-) - -diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml -index 8688905..3748c0c 100644 ---- a/man/systemd.resource-control.xml -+++ b/man/systemd.resource-control.xml -@@ -327,6 +327,20 @@ along with systemd; If not, see . - - - -+ -+ Delegate= -+ -+ -+ Turns on delegation of further resource control -+ partitioning to processes of the unit. For unpriviliged -+ services (i.e. those using the User= -+ setting) this allows processes to create a subhierarchy -+ beneath its control group path. For priviliged services and -+ scopes this ensures the processes will have all control -+ group controllers enabled. -+ -+ -+ - - - -diff --git a/src/core/cgroup.c b/src/core/cgroup.c -index 32e2599..764311f 100644 ---- a/src/core/cgroup.c -+++ b/src/core/cgroup.c -@@ -94,14 +94,16 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { - "%sCPUShares=%lu\n" - "%sBlockIOWeight=%lu\n" - "%sMemoryLimit=%" PRIu64 "\n" -- "%sDevicePolicy=%s\n", -+ "%sDevicePolicy=%s\n" -+ "%sDelegate=%s\n", - prefix, yes_no(c->cpu_accounting), - prefix, yes_no(c->blockio_accounting), - prefix, yes_no(c->memory_accounting), - prefix, c->cpu_shares, - prefix, c->blockio_weight, - prefix, c->memory_limit, -- prefix, cgroup_device_policy_to_string(c->device_policy)); -+ prefix, cgroup_device_policy_to_string(c->device_policy), -+ prefix, yes_no(c->delegate)); - - LIST_FOREACH(device_allow, a, c->device_allow) - fprintf(f, -@@ -342,6 +344,19 @@ static CGroupControllerMask unit_get_cgroup_mask(Unit *u) { - if (!c) - return 0; - -+ /* If delegation is turned on, then turn on all cgroups, -+ * unless the process we fork into it is known to drop -+ * privileges anyway, and shouldn't get access to the -+ * controllers anyway. */ -+ -+ if (c->delegate) { -+ ExecContext *e; -+ -+ e = unit_get_exec_context(u); -+ if (!e || exec_context_maintains_privileges(e)) -+ return _CGROUP_CONTROLLER_MASK_ALL; -+ } -+ - return cgroup_context_get_mask(c); - } - -diff --git a/src/core/cgroup.h b/src/core/cgroup.h -index 0a079e9..d00bcac 100644 ---- a/src/core/cgroup.h -+++ b/src/core/cgroup.h -@@ -80,6 +80,8 @@ struct CGroupContext { - - CGroupDevicePolicy device_policy; - LIST_HEAD(CGroupDeviceAllow, device_allow); -+ -+ bool delegate; - }; - - #include "unit.h" -diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c -index 9ebcad9..a13c869 100644 ---- a/src/core/dbus-cgroup.c -+++ b/src/core/dbus-cgroup.c -@@ -124,6 +124,7 @@ static int bus_cgroup_append_device_allow(DBusMessageIter *i, const char *proper - } - - const BusProperty bus_cgroup_context_properties[] = { -+ { "Delegate", bus_property_append_bool, "b", offsetof(CGroupContext, delegate) }, - { "CPUAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, cpu_accounting) }, - { "CPUShares", bus_property_append_ul, "t", offsetof(CGroupContext, cpu_shares) }, - { "BlockIOAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, blockio_accounting) }, -@@ -138,6 +139,38 @@ const BusProperty bus_cgroup_context_properties[] = { - {} - }; - -+static int bus_cgroup_set_transient_property( -+ Unit *u, -+ CGroupContext *c, -+ const char *name, -+ DBusMessageIter *i, -+ UnitSetPropertiesMode mode, -+ DBusError *error) { -+ -+ assert(u); -+ assert(c); -+ assert(name); -+ assert(i); -+ -+ if (streq(name, "Delegate")) { -+ -+ if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) -+ return -EINVAL; -+ -+ if (mode != UNIT_CHECK) { -+ dbus_bool_t b; -+ -+ dbus_message_iter_get_basic(i, &b); -+ c->delegate = b; -+ unit_write_drop_in_private(u, mode, name, b ? "Delegate=yes" : "Delegate=no"); -+ } -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ - int bus_cgroup_set_property( - Unit *u, - CGroupContext *c, -@@ -550,5 +583,12 @@ int bus_cgroup_set_property( - return 1; - } - -+ if (u->transient && u->load_state == UNIT_STUB) { -+ int r; -+ r = bus_cgroup_set_transient_property(u, c, name, i, mode, error); -+ if (r != 0) -+ return r; -+ } -+ - return 0; - } -diff --git a/src/core/execute.c b/src/core/execute.c -index 981b9e4..c3fd6a8 100644 ---- a/src/core/execute.c -+++ b/src/core/execute.c -@@ -1035,6 +1035,7 @@ int exec_spawn(ExecCommand *command, - bool confirm_spawn, - CGroupControllerMask cgroup_supported, - const char *cgroup_path, -+ bool cgroup_delegate, - const char *unit_id, - int idle_pipe[4], - pid_t *ret) { -@@ -1299,8 +1300,10 @@ int exec_spawn(ExecCommand *command, - } - } - --#ifdef HAVE_PAM -- if (cgroup_path && context->user && context->pam_name) { -+ /* If delegation is enabled we'll pass ownership of the cgroup -+ * (but only in systemd's own controller hierarchy!) to the -+ * user of the new process. */ -+ if (cgroup_path && context->user && cgroup_delegate) { - err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0644, uid, gid); - if (err < 0) { - r = EXIT_CGROUP; -@@ -1314,7 +1317,6 @@ int exec_spawn(ExecCommand *command, - goto fail_child; - } - } --#endif - - if (apply_permissions) { - err = enforce_groups(context, username, gid); -@@ -2069,6 +2071,21 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { - prefix, c->utmp_id); - } - -+bool exec_context_maintains_privileges(ExecContext *c) { -+ assert(c); -+ -+ /* Returns true if the process forked off would run under -+ * an unchanged UID or as root. */ -+ -+ if (!c->user) -+ return true; -+ -+ if (streq(c->user, "root") || streq(c->user, "0")) -+ return true; -+ -+ return false; -+} -+ - void exec_status_start(ExecStatus *s, pid_t pid) { - assert(s); - -diff --git a/src/core/execute.h b/src/core/execute.h -index c1e9717..eca9d7d 100644 ---- a/src/core/execute.h -+++ b/src/core/execute.h -@@ -173,6 +173,7 @@ int exec_spawn(ExecCommand *command, - bool confirm_spawn, - CGroupControllerMask cgroup_mask, - const char *cgroup_path, -+ bool cgroup_delegate, - const char *unit_id, - int pipe_fd[2], - pid_t *ret); -@@ -199,6 +200,7 @@ void exec_context_tty_reset(const ExecContext *context); - int exec_context_load_environment(const ExecContext *c, char ***l); - - bool exec_context_may_touch_console(ExecContext *c); -+bool exec_context_maintains_privileges(ExecContext *c); - void exec_context_serialize(const ExecContext *c, Unit *u, FILE *f); - - void exec_status_start(ExecStatus *s, pid_t pid); -diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 -index 0991cb9..3e88c8a 100644 ---- a/src/core/load-fragment-gperf.gperf.m4 -+++ b/src/core/load-fragment-gperf.gperf.m4 -@@ -95,7 +95,8 @@ $1.BlockIOAccounting, config_parse_bool, 0, - $1.BlockIOWeight, config_parse_blockio_weight, 0, offsetof($1, cgroup_context) - $1.BlockIODeviceWeight, config_parse_blockio_device_weight, 0, offsetof($1, cgroup_context) - $1.BlockIOReadBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context) --$1.BlockIOWriteBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context)' -+$1.BlockIOWriteBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context) -+$1.Delegate, config_parse_bool, 0, offsetof($1, cgroup_context.delegate)' - )m4_dnl - Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description) - Unit.Documentation, config_parse_documentation, 0, offsetof(Unit, documentation) -diff --git a/src/core/mount.c b/src/core/mount.c -index 3672338..f7c98c4 100644 ---- a/src/core/mount.c -+++ b/src/core/mount.c -@@ -793,6 +793,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { - UNIT(m)->manager->confirm_spawn, - UNIT(m)->manager->cgroup_supported, - UNIT(m)->cgroup_path, -+ m->cgroup_context.delegate, - UNIT(m)->id, - NULL, - &pid); -diff --git a/src/core/service.c b/src/core/service.c -index f6fdbbc..da30d77 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -1869,6 +1869,7 @@ static int service_spawn( - UNIT(s)->manager->confirm_spawn, - UNIT(s)->manager->cgroup_supported, - path, -+ s->cgroup_context.delegate, - UNIT(s)->id, - s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL, - &pid); -diff --git a/src/core/socket.c b/src/core/socket.c -index 32e0d35..f365125 100644 ---- a/src/core/socket.c -+++ b/src/core/socket.c -@@ -1229,6 +1229,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { - UNIT(s)->manager->confirm_spawn, - UNIT(s)->manager->cgroup_supported, - UNIT(s)->cgroup_path, -+ s->cgroup_context.delegate, - UNIT(s)->id, - NULL, - &pid); -diff --git a/src/core/swap.c b/src/core/swap.c -index 727bb95..597c8ca 100644 ---- a/src/core/swap.c -+++ b/src/core/swap.c -@@ -591,6 +591,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { - UNIT(s)->manager->confirm_spawn, - UNIT(s)->manager->cgroup_supported, - UNIT(s)->cgroup_path, -+ s->cgroup_context.delegate, - UNIT(s)->id, - NULL, - &pid); -diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c -index 22caadf..0cebdc5 100644 ---- a/src/machine/machined-dbus.c -+++ b/src/machine/machined-dbus.c -@@ -739,9 +739,11 @@ int manager_start_scope( - DBusMessageIter iter, sub, sub2, sub3, sub4; - const char *timeout_stop_property = "TimeoutStopUSec"; - const char *pids_property = "PIDs"; -+ const char *delegate_property = "Delegate"; - uint64_t timeout = 500 * USEC_PER_MSEC; - const char *fail = "fail"; - uint32_t u; -+ dbus_bool_t b = 1; - int r; - - assert(manager); -@@ -814,6 +816,14 @@ int manager_start_scope( - !dbus_message_iter_close_container(&sub, &sub2)) - return log_oom(); - -+ if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || -+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &delegate_property) || -+ !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "b", &sub3) || -+ !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_BOOLEAN, &b) || -+ !dbus_message_iter_close_container(&sub2, &sub3) || -+ !dbus_message_iter_close_container(&sub, &sub2)) -+ return log_oom(); -+ - if (more_properties) { - r = copy_many_fields(&sub, more_properties); - if (r < 0) -diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h -index 0963450..0608b9a 100644 ---- a/src/shared/cgroup-util.h -+++ b/src/shared/cgroup-util.h -@@ -34,7 +34,8 @@ typedef enum CGroupControllerMask { - CGROUP_CPUACCT = 2, - CGROUP_BLKIO = 4, - CGROUP_MEMORY = 8, -- CGROUP_DEVICE = 16 -+ CGROUP_DEVICE = 16, -+ _CGROUP_CONTROLLER_MASK_ALL = 31 - } CGroupControllerMask; - - /* -diff --git a/units/systemd-nspawn@.service.in b/units/systemd-nspawn@.service.in -index 8e00736..bdfa89f 100644 ---- a/units/systemd-nspawn@.service.in -+++ b/units/systemd-nspawn@.service.in -@@ -12,6 +12,7 @@ Documentation=man:systemd-nspawn(1) - [Service] - ExecStart=@bindir@/systemd-nspawn -bjD /var/lib/container/%i - Type=notify -+Delegate=yes - - [Install] - WantedBy=multi-user.target diff --git a/SOURCES/0239-delta-do-not-use-unicode-chars-in-C-locale.patch b/SOURCES/0239-delta-do-not-use-unicode-chars-in-C-locale.patch new file mode 100644 index 0000000..c3ff191 --- /dev/null +++ b/SOURCES/0239-delta-do-not-use-unicode-chars-in-C-locale.patch @@ -0,0 +1,135 @@ +From 719f080ce2c999febe4c9289fb09e5e2e719d4d2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 16 Apr 2014 23:33:41 -0400 +Subject: [PATCH] delta: do not use unicode chars in C locale + +https://bugzilla.redhat.com/show_bug.cgi?id=1088418 + +(cherry picked from commit 00a5cc3a63c125633e822f39efd9c32223169f62) + +Resolves: #1088419 +--- + src/delta/delta.c | 40 +++++++++++++++++++++++++--------------- + 1 file changed, 25 insertions(+), 15 deletions(-) + +diff --git a/src/delta/delta.c b/src/delta/delta.c +index a8dd57e..f1aea80 100644 +--- a/src/delta/delta.c ++++ b/src/delta/delta.c +@@ -85,6 +85,10 @@ static void pager_open_if_enabled(void) { + pager_open(false); + } + ++static inline const char* arrow(void) { ++ return is_locale_utf8() ? "→" : "->"; ++} ++ + static int equivalent(const char *a, const char *b) { + _cleanup_free_ char *x = NULL, *y = NULL; + +@@ -103,8 +107,9 @@ static int notify_override_masked(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_MASKED)) + return 0; + +- printf("%s%s%s %s → %s\n", +- ansi_highlight_red(), "[MASKED]", ansi_highlight_off(), top, bottom); ++ printf("%s%s%s %s %s %s\n", ++ ansi_highlight_red(), "[MASKED]", ansi_highlight_off(), ++ top, arrow(), bottom); + return 1; + } + +@@ -112,8 +117,9 @@ static int notify_override_equivalent(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_EQUIVALENT)) + return 0; + +- printf("%s%s%s %s → %s\n", +- ansi_highlight_green(), "[EQUIVALENT]", ansi_highlight_off(), top, bottom); ++ printf("%s%s%s %s %s %s\n", ++ ansi_highlight_green(), "[EQUIVALENT]", ansi_highlight_off(), ++ top, arrow(), bottom); + return 1; + } + +@@ -121,8 +127,9 @@ static int notify_override_redirected(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_REDIRECTED)) + return 0; + +- printf("%s%s%s %s → %s\n", +- ansi_highlight(), "[REDIRECTED]", ansi_highlight_off(), top, bottom); ++ printf("%s%s%s %s %s %s\n", ++ ansi_highlight(), "[REDIRECTED]", ansi_highlight_off(), ++ top, arrow(), bottom); + return 1; + } + +@@ -130,8 +137,9 @@ static int notify_override_overridden(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_OVERRIDDEN)) + return 0; + +- printf("%s%s%s %s → %s\n", +- ansi_highlight(), "[OVERRIDDEN]", ansi_highlight_off(), top, bottom); ++ printf("%s%s%s %s %s %s\n", ++ ansi_highlight(), "[OVERRIDDEN]", ansi_highlight_off(), ++ top, arrow(), bottom); + return 1; + } + +@@ -139,8 +147,9 @@ static int notify_override_extended(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_EXTENDED)) + return 0; + +- printf("%s%s%s %s → %s\n", +- ansi_highlight(), "[EXTENDED]", ansi_highlight_off(), top, bottom); ++ printf("%s%s%s %s %s %s\n", ++ ansi_highlight(), "[EXTENDED]", ansi_highlight_off(), ++ top, arrow(), bottom); + return 1; + } + +@@ -241,7 +250,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const + return -ENOMEM; + d = p + strlen(toppath) + 1; + +- log_debug("Adding at top: %s → %s", d, p); ++ log_debug("Adding at top: %s %s %s", d, arrow(), p); + k = hashmap_put(top, d, p); + if (k >= 0) { + p = strdup(p); +@@ -253,7 +262,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const + return k; + } + +- log_debug("Adding at bottom: %s → %s", d, p); ++ log_debug("Adding at bottom: %s %s %s", d, arrow(), p); + free(hashmap_remove(bottom, d)); + k = hashmap_put(bottom, d, p); + if (k < 0) { +@@ -276,7 +285,8 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const + if (!p) + return -ENOMEM; + +- log_debug("Adding to drops: %s → %s → %s", unit, basename(p), p); ++ log_debug("Adding to drops: %s %s %s %s %s", ++ unit, arrow(), basename(p), arrow(), p); + k = hashmap_put(h, basename(p), p); + if (k < 0) { + free(p); +@@ -328,7 +338,7 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch + if (!p) + return -ENOMEM; + +- log_debug("Adding at top: %s → %s", basename(p), p); ++ log_debug("Adding at top: %s %s %s", basename(p), arrow(), p); + k = hashmap_put(top, basename(p), p); + if (k >= 0) { + p = strdup(p); +@@ -339,7 +349,7 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch + return k; + } + +- log_debug("Adding at bottom: %s → %s", basename(p), p); ++ log_debug("Adding at bottom: %s %s %s", basename(p), arrow(), p); + free(hashmap_remove(bottom, basename(p))); + k = hashmap_put(bottom, basename(p), p); + if (k < 0) { diff --git a/SOURCES/0240-core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch b/SOURCES/0240-core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch deleted file mode 100644 index 17bf635..0000000 --- a/SOURCES/0240-core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch +++ /dev/null @@ -1,50 +0,0 @@ -From ca891be92be9f82078bd88d041098c34ae35334f Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 10 Dec 2014 20:38:24 +0100 -Subject: [PATCH] core: don't migrate PIDs for units that may contain - subcgroups, do this only for leaf units - -Otherwise a slice or delegation unit might move PIDs around ignoring the -fact that it is attached to a subcgroup. - -(cherry picked from commit 0cd385d31814c8c1bc0c81d11ef321036b8b0921) - -Resolves: #1179715 ---- - src/core/cgroup.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/src/core/cgroup.c b/src/core/cgroup.c -index 764311f..5558b6d 100644 ---- a/src/core/cgroup.c -+++ b/src/core/cgroup.c -@@ -392,11 +392,16 @@ static CGroupControllerMask unit_get_siblings_mask(Unit *u) { - - static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { - _cleanup_free_ char *path; -+ CGroupContext *c; - int r; - bool was_in_hash = false; - - assert(u); - -+ c = unit_get_cgroup_context(u); -+ if (!c) -+ return 0; -+ - path = unit_default_cgroup_path(u); - if (!path) - return log_oom(); -@@ -416,8 +421,10 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { - if (r < 0) - log_error("Failed to create cgroup %s: %s", path, strerror(-r)); - -- /* Then, possibly move things over */ -- if (u->cgroup_path) { -+ /* Then, possibly move things over, but not if -+ * subgroups may contain processes, which is the case -+ * for slice and delegation units. */ -+ if (u->cgroup_path && u->type != UNIT_SLICE && !c->delegate) { - r = cg_migrate_everywhere(u->manager->cgroup_supported, u->cgroup_path, path); - if (r < 0) - log_error("Failed to migrate cgroup from %s to %s: %s", diff --git a/SOURCES/0240-core-print-debug-instead-of-error-message.patch b/SOURCES/0240-core-print-debug-instead-of-error-message.patch new file mode 100644 index 0000000..a406895 --- /dev/null +++ b/SOURCES/0240-core-print-debug-instead-of-error-message.patch @@ -0,0 +1,32 @@ +From bcbb894a709f56ac0bccf7e5edfd59e39e8ec800 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 14 May 2014 15:13:43 +0200 +Subject: [PATCH] core: print debug instead of error message + +In case that session scope is in some other state than SCOPE_RUNNING or +SCOPE_ABANDONED we will not print error message. It might be the case +that scope is in other state because systemd realized that scope is +empty before dispatching dbus call from pam hook. Or system is going +down and stop job is runnig for the scope and changed scope state to +SCOPE_STOP_SIGTERM or SCOPE_STOP_SIGKILL. + +(cherry picked from commit f517790db5277fa71d6ae3617244f1acc4b62572) + +Resolves: #1105608 +--- + src/core/dbus-scope.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c +index 58dd9ff..71d6921 100644 +--- a/src/core/dbus-scope.c ++++ b/src/core/dbus-scope.c +@@ -76,7 +76,7 @@ DBusHandlerResult bus_scope_message_handler(Unit *u, DBusConnection *c, DBusMess + + r = scope_abandon(s); + if (r < 0) +- log_error("Failed to mark scope %s as abandoned : %s", UNIT(s)->id, strerror(-r)); ++ log_debug("Failed to mark scope %s as abandoned : Scope is not running", UNIT(s)->id); + + reply = dbus_message_new_method_return(message); + if (!reply) diff --git a/SOURCES/0241-journald-always-add-syslog-facility-for-messages-com.patch b/SOURCES/0241-journald-always-add-syslog-facility-for-messages-com.patch new file mode 100644 index 0000000..3d4c49a --- /dev/null +++ b/SOURCES/0241-journald-always-add-syslog-facility-for-messages-com.patch @@ -0,0 +1,41 @@ +From 7f85c4184fc45c3dd2c76b4867ab252c3530f84d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 25 Jul 2014 14:38:22 +0200 +Subject: [PATCH] journald: always add syslog facility for messages coming from + kmsg + +Set SYSLOG_FACILITY field for kernel log messages too. Setting only +SYSLOG_IDENTIFIER="kernel" is not sufficient and tools reading journal +maybe confused by missing SYSLOG_FACILITY field for kernel log messages. + +(cherry picked from commit 36dd072cdf03dcac0fcd2d6b42f261444dc7ac88) + +Resolves: #1113215 +--- + src/journal/journald-kmsg.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index 9895808..e393cb7 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -274,6 +274,9 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) { + if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_priority); + ++ if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) ++ IOVEC_SET_STRING(iovec[n++], syslog_facility); ++ + if ((priority & LOG_FACMASK) == LOG_KERN) + IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel"); + else { +@@ -295,9 +298,6 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) { + if (syslog_pid) + IOVEC_SET_STRING(iovec[n++], syslog_pid); + } +- +- if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) +- IOVEC_SET_STRING(iovec[n++], syslog_facility); + } + + message = cunescape_length_with_prefix(p, pl, "MESSAGE="); diff --git a/SOURCES/0242-Introduce-_cleanup_endmntent_.patch b/SOURCES/0242-Introduce-_cleanup_endmntent_.patch new file mode 100644 index 0000000..a195d89 --- /dev/null +++ b/SOURCES/0242-Introduce-_cleanup_endmntent_.patch @@ -0,0 +1,173 @@ +From 8e7be40d1386e6053d4663114a00e0390400350f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 3 Oct 2013 22:13:55 -0400 +Subject: [PATCH] Introduce _cleanup_endmntent_ + +(cherry picked from commit 5862d652ba14178cff46b8a8fc6c6d8392bf32b1) + +Related: #1098310 +--- + src/cryptsetup/cryptsetup.c | 19 ++++++------------- + src/fstab-generator/fstab-generator.c | 17 +++++------------ + src/remount-fs/remount-fs.c | 13 ++++--------- + src/shared/util.h | 7 +++++++ + 4 files changed, 22 insertions(+), 34 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 769c3e4..4f2f52a 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -236,31 +236,24 @@ finish: + } + + static char *disk_mount_point(const char *label) { +- char *mp = NULL; + _cleanup_free_ char *device = NULL; +- FILE *f = NULL; ++ _cleanup_endmntent_ FILE *f = NULL; + struct mntent *m; + + /* Yeah, we don't support native systemd unit files here for now */ + + if (asprintf(&device, "/dev/mapper/%s", label) < 0) +- goto finish; ++ return NULL; + + f = setmntent("/etc/fstab", "r"); + if (!f) +- goto finish; ++ return NULL; + + while ((m = getmntent(f))) +- if (path_equal(m->mnt_fsname, device)) { +- mp = strdup(m->mnt_dir); +- break; +- } +- +-finish: +- if (f) +- endmntent(f); ++ if (path_equal(m->mnt_fsname, device)) ++ return strdup(m->mnt_dir); + +- return mp; ++ return NULL; + } + + static int get_password(const char *name, usec_t until, bool accept_cached, char ***passwords) { +diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c +index c0c2992..78d7609 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -327,15 +327,12 @@ static int add_mount( + } + + static int parse_fstab(const char *prefix, bool initrd) { +- _cleanup_free_ char *fstab_path = NULL; +- FILE *f; ++ char *fstab_path; ++ _cleanup_endmntent_ FILE *f; + int r = 0; + struct mntent *me; + +- fstab_path = strjoin(strempty(prefix), "/etc/fstab", NULL); +- if (!fstab_path) +- return log_oom(); +- ++ fstab_path = strappenda(strempty(prefix), "/etc/fstab"); + f = setmntent(fstab_path, "r"); + if (!f) { + if (errno == ENOENT) +@@ -354,10 +351,8 @@ static int parse_fstab(const char *prefix, bool initrd) { + + what = fstab_node_to_udev_node(me->mnt_fsname); + where = strjoin(strempty(prefix), me->mnt_dir, NULL); +- if (!what || !where) { +- r = log_oom(); +- goto finish; +- } ++ if (!what || !where) ++ return log_oom(); + + if (is_path(where)) + path_kill_slashes(where); +@@ -395,8 +390,6 @@ static int parse_fstab(const char *prefix, bool initrd) { + r = k; + } + +-finish: +- endmntent(f); + return r; + } + +diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c +index f432718..847637a 100644 +--- a/src/remount-fs/remount-fs.c ++++ b/src/remount-fs/remount-fs.c +@@ -40,7 +40,7 @@ + + int main(int argc, char *argv[]) { + int ret = EXIT_FAILURE; +- FILE *f = NULL; ++ _cleanup_endmntent_ FILE *f = NULL; + struct mntent* me; + Hashmap *pids = NULL; + +@@ -57,13 +57,11 @@ int main(int argc, char *argv[]) { + + f = setmntent("/etc/fstab", "r"); + if (!f) { +- if (errno == ENOENT) { +- ret = EXIT_SUCCESS; +- goto finish; +- } ++ if (errno == ENOENT) ++ return EXIT_SUCCESS; + + log_error("Failed to open /etc/fstab: %m"); +- goto finish; ++ return EXIT_FAILURE; + } + + pids = hashmap_new(trivial_hash_func, trivial_compare_func); +@@ -162,8 +160,5 @@ finish: + if (pids) + hashmap_free_free(pids); + +- if (f) +- endmntent(f); +- + return ret; + } +diff --git a/src/shared/util.h b/src/shared/util.h +index 3a4bc98..5a1e1bc 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + #include "macro.h" + #include "time-util.h" +@@ -579,6 +580,11 @@ static inline void umaskp(mode_t *u) { + umask(*u); + } + ++static inline void endmntentp(FILE **f) { ++ if (*f) ++ endmntent(*f); ++} ++ + #define _cleanup_free_ _cleanup_(freep) + #define _cleanup_fclose_ _cleanup_(fclosep) + #define _cleanup_pclose_ _cleanup_(pclosep) +@@ -586,6 +592,7 @@ static inline void umaskp(mode_t *u) { + #define _cleanup_closedir_ _cleanup_(closedirp) + #define _cleanup_umask_ _cleanup_(umaskp) + #define _cleanup_globfree_ _cleanup_(globfree) ++#define _cleanup_endmntent_ _cleanup_(endmntentp) + + _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) { + if (_unlikely_(b == 0 || a > ((size_t) -1) / b)) diff --git a/SOURCES/0243-Introduce-_cleanup_fdset_free_.patch b/SOURCES/0243-Introduce-_cleanup_fdset_free_.patch new file mode 100644 index 0000000..a698bdb --- /dev/null +++ b/SOURCES/0243-Introduce-_cleanup_fdset_free_.patch @@ -0,0 +1,127 @@ +From 735583e63b9c109e3aaa7aecbce8d7a477988ef6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 11 Oct 2013 19:33:48 -0400 +Subject: [PATCH] Introduce _cleanup_fdset_free_ + +(cherry picked from commit 51d122af23533b0b8318911c4fc8b128ad8eafb7) + +Related: #1098310 +--- + src/core/manager.c | 22 +++++++--------------- + src/nspawn/nspawn.c | 4 +--- + src/shared/fdset.h | 7 +++++++ + 3 files changed, 15 insertions(+), 18 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index 2829c95..57a88b0 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -236,7 +236,7 @@ static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned po + *p++ = '*'; + if (pos < width-1) + p = mempset(p, ' ', width-1-pos); +- p = stpcpy(p, ANSI_HIGHLIGHT_OFF); ++ strcpy(p, ANSI_HIGHLIGHT_OFF); + } + } + +@@ -257,6 +257,7 @@ static void manager_print_jobs_in_progress(Manager *m) { + /* m->n_running_jobs must be consistent with the contents of m->jobs, + * so the above loop must have succeeded in finding j. */ + assert(counter == print_nr + 1); ++ assert(j); + + cylon_pos = m->jobs_in_progress_iteration % 14; + if (cylon_pos >= 8) +@@ -2343,8 +2344,8 @@ int manager_distribute_fds(Manager *m, FDSet *fds) { + + int manager_reload(Manager *m) { + int r, q; +- FILE *f; +- FDSet *fds; ++ _cleanup_fclose_ FILE *f = NULL; ++ _cleanup_fdset_free_ FDSet *fds = NULL; + + assert(m); + +@@ -2358,20 +2359,18 @@ int manager_reload(Manager *m) { + fds = fdset_new(); + if (!fds) { + m->n_reloading --; +- r = -ENOMEM; +- goto finish; ++ return -ENOMEM; + } + + r = manager_serialize(m, f, fds, false); + if (r < 0) { + m->n_reloading --; +- goto finish; ++ return r; + } + + if (fseeko(f, 0, SEEK_SET) < 0) { + m->n_reloading --; +- r = -errno; +- goto finish; ++ return -errno; + } + + /* From here on there is no way back. */ +@@ -2415,13 +2414,6 @@ int manager_reload(Manager *m) { + + m->send_reloading_done = true; + +-finish: +- if (f) +- fclose(f); +- +- if (fds) +- fdset_free(fds); +- + return r; + } + +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index f326f99..1cf67d0 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -1305,7 +1305,7 @@ int main(int argc, char *argv[]) { + bool saved_attr_valid = false; + struct winsize ws; + int kmsg_socket_pair[2] = { -1, -1 }; +- FDSet *fds = NULL; ++ _cleanup_fdset_free_ FDSet *fds = NULL; + + log_parse_environment(); + log_open(); +@@ -1813,7 +1813,5 @@ finish: + free(arg_directory); + free(arg_machine); + +- fdset_free(fds); +- + return r; + } +diff --git a/src/shared/fdset.h b/src/shared/fdset.h +index a7bd5e2..1a26005 100644 +--- a/src/shared/fdset.h ++++ b/src/shared/fdset.h +@@ -22,6 +22,7 @@ + ***/ + + #include "set.h" ++#include "util.h" + + typedef struct FDSet FDSet; + +@@ -47,3 +48,9 @@ int fdset_iterate(FDSet *s, Iterator *i); + + #define FDSET_FOREACH(fd, fds, i) \ + for ((i) = ITERATOR_FIRST, (fd) = fdset_iterate((fds), &(i)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i))) ++ ++static inline void fdset_freep(FDSet **fds) { ++ if (*fds) ++ fdset_free(*fds); ++} ++#define _cleanup_fdset_free_ _cleanup_(fdset_freep) diff --git a/SOURCES/0244-Introduce-udev-object-cleanup-functions.patch b/SOURCES/0244-Introduce-udev-object-cleanup-functions.patch new file mode 100644 index 0000000..db3bda5 --- /dev/null +++ b/SOURCES/0244-Introduce-udev-object-cleanup-functions.patch @@ -0,0 +1,1291 @@ +From 0aad0e32d93d848e707a3cd0edd78c58a4c21829 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 12 Oct 2013 20:28:21 -0400 +Subject: [PATCH] Introduce udev object cleanup functions + +Conflicts: + src/backlight/backlight.c + src/gpt-auto-generator/gpt-auto-generator.c + +(cherry picked from commit 1ca208fb4f93e5869704af1812cbff7130a2fc03) + +Related: #1098310 +--- + Makefile.am | 1 + + src/backlight/backlight.c | 57 +++++------ + src/core/umount.c | 143 ++++++++++------------------ + src/cryptsetup/cryptsetup.c | 27 ++---- + src/fsck/fsck.c | 13 +-- + src/gpt-auto-generator/gpt-auto-generator.c | 121 +++++++---------------- + src/journal/journal-internal.h | 7 +- + src/login/sysfs-show.c | 22 ++--- + src/readahead/readahead-common.c | 66 +++++-------- + src/shared/fdset.h | 5 +- + src/shared/install.c | 6 +- + src/shared/set.h | 10 +- + src/shared/strv.h | 7 +- + src/shared/udev-util.h | 37 +++++++ + src/shared/util.h | 33 +++---- + src/test/test-libudev.c | 8 +- + src/test/test-udev.c | 21 ++-- + src/tmpfiles/tmpfiles.c | 5 +- + 18 files changed, 227 insertions(+), 362 deletions(-) + create mode 100644 src/shared/udev-util.h + +diff --git a/Makefile.am b/Makefile.am +index fa2fba6..ef73138 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -647,6 +647,7 @@ libsystemd_shared_la_SOURCES = \ + src/shared/sparse-endian.h \ + src/shared/util.c \ + src/shared/util.h \ ++ src/shared/udev-util.h \ + src/shared/virt.c \ + src/shared/virt.h \ + src/shared/efivars.c \ +diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c +index 9b2eada..aa80c29 100644 +--- a/src/backlight/backlight.c ++++ b/src/backlight/backlight.c +@@ -19,15 +19,15 @@ + along with systemd; If not, see . + ***/ + +-#include +- + #include "util.h" + #include "mkdir.h" + #include "fileio.h" ++#include "libudev.h" ++#include "udev-util.h" + + int main(int argc, char *argv[]) { +- struct udev *udev = NULL; +- struct udev_device *device = NULL; ++ _cleanup_udev_unref_ struct udev *udev = NULL; ++ _cleanup_udev_device_unref_ struct udev_device *device = NULL; + _cleanup_free_ char *saved = NULL; + int r; + +@@ -45,37 +45,35 @@ int main(int argc, char *argv[]) { + r = mkdir_p("/var/lib/systemd/backlight", 0755); + if (r < 0) { + log_error("Failed to create backlight directory: %s", strerror(-r)); +- goto finish; ++ return EXIT_FAILURE; + } + + udev = udev_new(); + if (!udev) { +- r = log_oom(); +- goto finish; ++ log_oom(); ++ return EXIT_FAILURE; + } + + errno = 0; + device = udev_device_new_from_subsystem_sysname(udev, "backlight", argv[2]); + if (!device) { +- if (errno != 0) { ++ if (errno != 0) + log_error("Failed to get backlight device: %m"); +- r = -errno; +- } else +- r = log_oom(); ++ else ++ log_oom(); + +- goto finish; ++ return EXIT_FAILURE; + } + + if (!streq_ptr(udev_device_get_subsystem(device), "backlight")) { + log_error("Not a backlight device: %s", argv[2]); +- r = -ENODEV; +- goto finish; ++ return EXIT_FAILURE; + } + + saved = strappend("/var/lib/systemd/backlight/", udev_device_get_sysname(device)); + if (!saved) { +- r = log_oom(); +- goto finish; ++ log_oom(); ++ return EXIT_FAILURE; + } + + if (streq(argv[1], "load")) { +@@ -84,19 +82,17 @@ int main(int argc, char *argv[]) { + r = read_one_line_file(saved, &value); + if (r < 0) { + +- if (r == -ENOENT) { +- r = 0; +- goto finish; +- } ++ if (r == -ENOENT) ++ return EXIT_SUCCESS; + + log_error("Failed to read %s: %s", saved, strerror(-r)); +- goto finish; ++ return EXIT_FAILURE; + } + + r = udev_device_set_sysattr_value(device, "brightness", value); + if (r < 0) { + log_error("Failed to write system attribute: %s", strerror(-r)); +- goto finish; ++ return EXIT_FAILURE; + } + + } else if (streq(argv[1], "save")) { +@@ -105,28 +101,19 @@ int main(int argc, char *argv[]) { + value = udev_device_get_sysattr_value(device, "brightness"); + if (!value) { + log_error("Failed to read system attribute: %s", strerror(-r)); +- goto finish; ++ return EXIT_FAILURE; + } + + r = write_string_file(saved, value); + if (r < 0) { + log_error("Failed to write %s: %s", saved, strerror(-r)); +- goto finish; ++ return EXIT_FAILURE; + } + + } else { + log_error("Unknown verb %s.", argv[1]); +- r = -EINVAL; +- goto finish; ++ return EXIT_FAILURE; + } + +-finish: +- if (device) +- udev_device_unref(device); +- +- if (udev) +- udev_unref(udev); +- +- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +- ++ return EXIT_SUCCESS; + } +diff --git a/src/core/umount.c b/src/core/umount.c +index 1e95ad7..99dbe27 100644 +--- a/src/core/umount.c ++++ b/src/core/umount.c +@@ -27,7 +27,6 @@ + #include + #include + #include +-#include + + #include "list.h" + #include "mount-setup.h" +@@ -35,6 +34,8 @@ + #include "path-util.h" + #include "util.h" + #include "virt.h" ++#include "libudev.h" ++#include "udev-util.h" + + typedef struct MountPoint { + char *path; +@@ -201,145 +202,108 @@ finish: + } + + static int loopback_list_get(MountPoint **head) { +- int r; +- struct udev *udev; +- struct udev_enumerate *e = NULL; ++ _cleanup_udev_unref_ struct udev *udev; ++ _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(head); + +- if (!(udev = udev_new())) { +- r = -ENOMEM; +- goto finish; +- } ++ udev = udev_new(); ++ if (!udev) ++ return -ENOMEM; + +- if (!(e = udev_enumerate_new(udev))) { +- r = -ENOMEM; +- goto finish; +- } ++ e = udev_enumerate_new(udev); ++ if (!e) ++ return -ENOMEM; + + if (udev_enumerate_add_match_subsystem(e, "block") < 0 || + udev_enumerate_add_match_sysname(e, "loop*") < 0 || +- udev_enumerate_add_match_sysattr(e, "loop/backing_file", NULL) < 0) { +- r = -EIO; +- goto finish; +- } ++ udev_enumerate_add_match_sysattr(e, "loop/backing_file", NULL) < 0) ++ return -EIO; + +- if (udev_enumerate_scan_devices(e) < 0) { +- r = -EIO; +- goto finish; +- } ++ if (udev_enumerate_scan_devices(e) < 0) ++ return -EIO; + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + MountPoint *lb; +- struct udev_device *d; ++ _cleanup_udev_device_unref_ struct udev_device *d; + char *loop; + const char *dn; + +- if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) { +- r = -ENOMEM; +- goto finish; +- } ++ d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); ++ if (!d) ++ return -ENOMEM; + +- if (!(dn = udev_device_get_devnode(d))) { +- udev_device_unref(d); ++ dn = udev_device_get_devnode(d); ++ if (!dn) + continue; +- } + + loop = strdup(dn); +- udev_device_unref(d); +- +- if (!loop) { +- r = -ENOMEM; +- goto finish; +- } ++ if (!loop) ++ return -ENOMEM; + +- if (!(lb = new0(MountPoint, 1))) { ++ lb = new0(MountPoint, 1); ++ if (!lb) { + free(loop); +- r = -ENOMEM; +- goto finish; ++ return -ENOMEM; + } + + lb->path = loop; + LIST_PREPEND(MountPoint, mount_point, *head, lb); + } + +- r = 0; +- +-finish: +- if (e) +- udev_enumerate_unref(e); +- +- if (udev) +- udev_unref(udev); +- +- return r; ++ return 0; + } + + static int dm_list_get(MountPoint **head) { +- int r; +- struct udev *udev; +- struct udev_enumerate *e = NULL; ++ _cleanup_udev_unref_ struct udev *udev; ++ _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(head); + +- if (!(udev = udev_new())) { +- r = -ENOMEM; +- goto finish; +- } ++ udev = udev_new(); ++ if (!udev) ++ return -ENOMEM; + +- if (!(e = udev_enumerate_new(udev))) { +- r = -ENOMEM; +- goto finish; +- } ++ e = udev_enumerate_new(udev); ++ if (!e) ++ return -ENOMEM; + + if (udev_enumerate_add_match_subsystem(e, "block") < 0 || +- udev_enumerate_add_match_sysname(e, "dm-*") < 0) { +- r = -EIO; +- goto finish; +- } ++ udev_enumerate_add_match_sysname(e, "dm-*") < 0) ++ return -EIO; + +- if (udev_enumerate_scan_devices(e) < 0) { +- r = -EIO; +- goto finish; +- } ++ if (udev_enumerate_scan_devices(e) < 0) ++ return -EIO; + + first = udev_enumerate_get_list_entry(e); + + udev_list_entry_foreach(item, first) { + MountPoint *m; +- struct udev_device *d; ++ _cleanup_udev_device_unref_ struct udev_device *d; + dev_t devnum; + char *node; + const char *dn; + +- if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) { +- r = -ENOMEM; +- goto finish; +- } ++ d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); ++ if (!d) ++ return -ENOMEM; + + devnum = udev_device_get_devnum(d); + dn = udev_device_get_devnode(d); +- +- if (major(devnum) == 0 || !dn) { +- udev_device_unref(d); ++ if (major(devnum) == 0 || !dn) + continue; +- } + + node = strdup(dn); +- udev_device_unref(d); +- +- if (!node) { +- r = -ENOMEM; +- goto finish; +- } ++ if (!node) ++ return -ENOMEM; + +- if (!(m = new(MountPoint, 1))) { ++ m = new(MountPoint, 1); ++ if (!m) { + free(node); +- r = -ENOMEM; +- goto finish; ++ return -ENOMEM; + } + + m->path = node; +@@ -347,16 +311,7 @@ static int dm_list_get(MountPoint **head) { + LIST_PREPEND(MountPoint, mount_point, *head, m); + } + +- r = 0; +- +-finish: +- if (e) +- udev_enumerate_unref(e); +- +- if (udev) +- udev_unref(udev); +- +- return r; ++ return 0; + } + + static int delete_loopback(const char *device) { +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 4f2f52a..0a15b50 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -25,7 +25,6 @@ + #include + + #include +-#include + + #include "fileio.h" + #include "log.h" +@@ -34,6 +33,8 @@ + #include "strv.h" + #include "ask-password-api.h" + #include "def.h" ++#include "libudev.h" ++#include "udev-util.h" + + static const char *opt_type = NULL; /* CRYPT_LUKS1, CRYPT_TCRYPT or CRYPT_PLAIN */ + static char *opt_cipher = NULL; +@@ -184,7 +185,7 @@ static void log_glue(int level, const char *msg, void *usrptr) { + log_debug("%s", msg); + } + +-static char *disk_description(const char *path) { ++static char* disk_description(const char *path) { + + static const char name_fields[] = { + "ID_PART_ENTRY_NAME\0" +@@ -193,10 +194,9 @@ static char *disk_description(const char *path) { + "ID_MODEL\0" + }; + +- struct udev *udev = NULL; +- struct udev_device *device = NULL; ++ _cleanup_udev_unref_ struct udev *udev = NULL; ++ _cleanup_udev_device_unref_ struct udev_device *device = NULL; + struct stat st; +- char *description = NULL; + const char *i; + + assert(path); +@@ -213,26 +213,17 @@ static char *disk_description(const char *path) { + + device = udev_device_new_from_devnum(udev, 'b', st.st_rdev); + if (!device) +- goto finish; ++ return NULL; + + NULSTR_FOREACH(i, name_fields) { + const char *name; + + name = udev_device_get_property_value(device, i); +- if (!isempty(name)) { +- description = strdup(name); +- break; +- } ++ if (!isempty(name)) ++ return strdup(name); + } + +-finish: +- if (device) +- udev_device_unref(device); +- +- if (udev) +- udev_unref(udev); +- +- return description; ++ return NULL; + } + + static char *disk_mount_point(const char *label) { +diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c +index f298cf7..96a79dd 100644 +--- a/src/fsck/fsck.c ++++ b/src/fsck/fsck.c +@@ -27,7 +27,6 @@ + #include + #include + +-#include + #include + + #include "util.h" +@@ -36,6 +35,8 @@ + #include "bus-errors.h" + #include "virt.h" + #include "fileio.h" ++#include "libudev.h" ++#include "udev-util.h" + + static bool arg_skip = false; + static bool arg_force = false; +@@ -251,8 +252,8 @@ int main(int argc, char *argv[]) { + int i = 0, r = EXIT_FAILURE, q; + pid_t pid; + siginfo_t status; +- struct udev *udev = NULL; +- struct udev_device *udev_device = NULL; ++ _cleanup_udev_unref_ struct udev *udev = NULL; ++ _cleanup_udev_device_unref_ struct udev_device *udev_device = NULL; + const char *device; + bool root_directory; + int progress_pipe[2] = { -1, -1 }; +@@ -400,12 +401,6 @@ int main(int argc, char *argv[]) { + touch("/run/systemd/quotacheck"); + + finish: +- if (udev_device) +- udev_device_unref(udev_device); +- +- if (udev) +- udev_unref(udev); +- + close_pipe(progress_pipe); + + return r; +diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c +index adbf71d..8436d26 100644 +--- a/src/gpt-auto-generator/gpt-auto-generator.c ++++ b/src/gpt-auto-generator/gpt-auto-generator.c +@@ -36,6 +36,7 @@ + #include "missing.h" + #include "sd-id128.h" + #include "libudev.h" ++#include "udev-util.h" + #include "special.h" + #include "unit-name.h" + #include "virt.h" +@@ -50,10 +51,7 @@ + + static const char *arg_dest = "/tmp"; + +-static inline void blkid_free_probep(blkid_probe *b) { +- if (*b) +- blkid_free_probe(*b); +-} ++define_trivial_cleanup_func(blkid_probe, blkid_free_probe) + #define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep) + + static int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr, char **fstype) { +@@ -236,75 +234,62 @@ static int add_home(const char *path, const char *fstype) { + } + + static int enumerate_partitions(struct udev *udev, dev_t dev) { +- struct udev_enumerate *e = NULL; +- struct udev_device *parent = NULL, *d = NULL; ++ struct udev_device *parent = NULL; ++ _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; ++ _cleanup_udev_device_unref_ struct udev_device *d = NULL; + struct udev_list_entry *first, *item; + unsigned home_nr = (unsigned) -1; + _cleanup_free_ char *home = NULL, *home_fstype = NULL; + int r; + + e = udev_enumerate_new(udev); +- if (!e) { +- r = log_oom(); +- goto finish; +- } ++ if (!e) ++ return log_oom(); + + d = udev_device_new_from_devnum(udev, 'b', dev); +- if (!d) { +- r = log_oom(); +- goto finish; +- } ++ if (!d) ++ return log_oom(); + + parent = udev_device_get_parent(d); +- if (!parent) { +- r = log_oom(); +- goto finish; +- } ++ if (!parent) ++ return log_oom(); + + r = udev_enumerate_add_match_parent(e, parent); +- if (r < 0) { +- r = log_oom(); +- goto finish; +- } ++ if (r < 0) ++ return log_oom(); + + r = udev_enumerate_add_match_subsystem(e, "block"); +- if (r < 0) { +- r = log_oom(); +- goto finish; +- } ++ if (r < 0) ++ return log_oom(); + + r = udev_enumerate_scan_devices(e); + if (r < 0) { + log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s", + major(dev), minor(dev), strerror(-r)); +- goto finish; ++ return r; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + _cleanup_free_ char *fstype = NULL; + const char *node = NULL; +- struct udev_device *q; ++ _cleanup_udev_device_unref_ struct udev_device *q; + sd_id128_t type_id; + unsigned nr; + + q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); +- if (!q) { +- r = log_oom(); +- goto finish; +- } ++ if (!q) ++ return log_oom(); + + if (udev_device_get_devnum(q) == udev_device_get_devnum(d)) +- goto skip; ++ continue; + + if (udev_device_get_devnum(q) == udev_device_get_devnum(parent)) +- goto skip; ++ continue; + + node = udev_device_get_devnode(q); +- if (!node) { +- r = log_oom(); +- goto finish; +- } ++ if (!node) ++ return log_oom(); + + r = verify_gpt_partition(node, &type_id, &nr, &fstype); + if (r < 0) { +@@ -313,11 +298,10 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { + continue; + log_error("Failed to verify GPT partition %s: %s", + node, strerror(-r)); +- udev_device_unref(q); +- goto finish; ++ return r; + } + if (r == 0) +- goto skip; ++ continue; + + if (sd_id128_equal(type_id, SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f))) + add_swap(node, fstype); +@@ -326,10 +310,8 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { + if (!home || nr < home_nr) { + free(home); + home = strdup(node); +- if (!home) { +- r = log_oom(); +- goto finish; +- } ++ if (!home) ++ return log_oom(); + + home_nr = nr; + +@@ -338,22 +320,11 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { + fstype = NULL; + } + } +- +- skip: +- udev_device_unref(q); + } + + if (home && home_fstype) + add_home(home, home_fstype); + +-finish: +- if (d) +- udev_device_unref(d); +- +- if (e) +- udev_enumerate_unref(e); +- +- + return r; + } + +@@ -432,44 +403,31 @@ static int get_block_device(const char *path, dev_t *dev) { + } + + static int devno_to_devnode(struct udev *udev, dev_t devno, char **ret) { +- struct udev_device *d = NULL; ++ _cleanup_udev_device_unref_ struct udev_device *d; + const char *t; + char *n; +- int r; + + d = udev_device_new_from_devnum(udev, 'b', devno); +- if (!d) { +- r = log_oom(); +- goto finish; +- } ++ if (!d) ++ return log_oom(); + + t = udev_device_get_devnode(d); +- if (!t) { +- r = -ENODEV; +- goto finish; +- } ++ if (!t) ++ return -ENODEV; + + n = strdup(t); +- if (!n) { +- r = -ENOMEM; +- goto finish; +- } ++ if (!n) ++ return -ENOMEM; + + *ret = n; +- r = 0; +- +-finish: +- if (d) +- udev_device_unref(d); +- +- return r; ++ return 0; + } + + int main(int argc, char *argv[]) { + _cleanup_free_ char *node = NULL; +- struct udev *udev = NULL; ++ _cleanup_udev_unref_ struct udev *udev = NULL; + dev_t devno; +- int r; ++ int r = 0; + + if (argc > 1 && argc != 4) { + log_error("This program takes three or no arguments."); +@@ -488,13 +446,11 @@ int main(int argc, char *argv[]) { + + if (in_initrd()) { + log_debug("In initrd, exiting."); +- r = 0; + goto finish; + } + + if (detect_container(NULL) > 0) { + log_debug("In a container, exiting."); +- r = 0; + goto finish; + } + +@@ -533,8 +489,5 @@ int main(int argc, char *argv[]) { + r = enumerate_partitions(udev, devno); + + finish: +- if (udev) +- udev_unref(udev); +- + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } +diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h +index 5bc6535..1bc912c 100644 +--- a/src/journal/journal-internal.h ++++ b/src/journal/journal-internal.h +@@ -135,11 +135,8 @@ struct sd_journal { + char *journal_make_match_string(sd_journal *j); + void journal_print_header(sd_journal *j); + +-static inline void journal_closep(sd_journal **j) { +- sd_journal_close(*j); +-} +- +-#define _cleanup_journal_close_ _cleanup_(journal_closep) ++define_trivial_cleanup_func(sd_journal*, sd_journal_close) ++#define _cleanup_journal_close_ _cleanup_(sd_journal_closep) + + #define JOURNAL_FOREACH_DATA_RETVAL(j, data, l, retval) \ + for (sd_journal_restart_data(j); ((retval) = sd_journal_enumerate_data((j), &(data), &(l))) > 0; ) +diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c +index 14de7d8..9fc3054 100644 +--- a/src/login/sysfs-show.c ++++ b/src/login/sysfs-show.c +@@ -26,6 +26,7 @@ + #include "util.h" + #include "sysfs-show.h" + #include "path-util.h" ++#include "udev-util.h" + + static int show_sysfs_one( + struct udev *udev, +@@ -143,9 +144,9 @@ static int show_sysfs_one( + } + + int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { +- struct udev *udev; ++ _cleanup_udev_unref_ struct udev *udev; ++ _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; + struct udev_list_entry *first = NULL; +- struct udev_enumerate *e; + int r; + + if (n_columns <= 0) +@@ -162,10 +163,8 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { + return -ENOMEM; + + e = udev_enumerate_new(udev); +- if (!e) { +- r = -ENOMEM; +- goto finish; +- } ++ if (!e) ++ return ENOMEM; + + if (!streq(seat, "seat0")) + r = udev_enumerate_add_match_tag(e, seat); +@@ -173,11 +172,11 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { + r = udev_enumerate_add_match_tag(e, "seat"); + + if (r < 0) +- goto finish; ++ return r; + + r = udev_enumerate_scan_devices(e); + if (r < 0) +- goto finish; ++ return r; + + first = udev_enumerate_get_list_entry(e); + if (first) +@@ -185,12 +184,5 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { + else + printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT), "(none)"); + +-finish: +- if (e) +- udev_enumerate_unref(e); +- +- if (udev) +- udev_unref(udev); +- + return r; + } +diff --git a/src/readahead/readahead-common.c b/src/readahead/readahead-common.c +index a234a89..aea1fbe 100644 +--- a/src/readahead/readahead-common.c ++++ b/src/readahead/readahead-common.c +@@ -27,13 +27,14 @@ + #include + #include + #include +-#include + + #include "log.h" + #include "readahead-common.h" + #include "util.h" + #include "missing.h" + #include "fileio.h" ++#include "libudev.h" ++#include "udev-util.h" + + int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) { + assert(fd >= 0); +@@ -60,9 +61,9 @@ int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) { + + int fs_on_ssd(const char *p) { + struct stat st; +- struct udev *udev = NULL; +- struct udev_device *udev_device = NULL, *look_at = NULL; +- bool b = false; ++ _cleanup_udev_unref_ struct udev *udev = NULL; ++ _cleanup_udev_device_unref_ struct udev_device *udev_device = NULL; ++ struct udev_device *look_at = NULL; + const char *devtype, *rotational, *model, *id; + int r; + +@@ -128,7 +129,7 @@ int fs_on_ssd(const char *p) { + + udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev); + if (!udev_device) +- goto finish; ++ return false; + + devtype = udev_device_get_property_value(udev_device, "DEVTYPE"); + if (devtype && streq(devtype, "partition")) +@@ -137,46 +138,34 @@ int fs_on_ssd(const char *p) { + look_at = udev_device; + + if (!look_at) +- goto finish; ++ return false; + + /* First, try high-level property */ + id = udev_device_get_property_value(look_at, "ID_SSD"); +- if (id) { +- b = streq(id, "1"); +- goto finish; +- } ++ if (id) ++ return streq(id, "1"); + + /* Second, try kernel attribute */ + rotational = udev_device_get_sysattr_value(look_at, "queue/rotational"); +- if (rotational) { +- b = streq(rotational, "0"); +- goto finish; +- } ++ if (rotational) ++ return streq(rotational, "0"); + + /* Finally, fallback to heuristics */ + look_at = udev_device_get_parent(look_at); + if (!look_at) +- goto finish; ++ return false; + + model = udev_device_get_sysattr_value(look_at, "model"); + if (model) +- b = !!strstr(model, "SSD"); +- +-finish: +- if (udev_device) +- udev_device_unref(udev_device); +- +- if (udev) +- udev_unref(udev); ++ return !!strstr(model, "SSD"); + +- return b; ++ return false; + } + + int fs_on_read_only(const char *p) { + struct stat st; +- struct udev *udev = NULL; +- struct udev_device *udev_device = NULL; +- bool b = false; ++ _cleanup_udev_unref_ struct udev *udev = NULL; ++ _cleanup_udev_device_unref_ struct udev_device *udev_device = NULL; + const char *read_only; + + assert(p); +@@ -187,24 +176,19 @@ int fs_on_read_only(const char *p) { + if (major(st.st_dev) == 0) + return false; + +- if (!(udev = udev_new())) ++ udev = udev_new(); ++ if (!udev) + return -ENOMEM; + +- if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) +- goto finish; +- +- if ((read_only = udev_device_get_sysattr_value(udev_device, "ro"))) +- if ((b = streq(read_only, "1"))) +- goto finish; +- +-finish: +- if (udev_device) +- udev_device_unref(udev_device); ++ udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev); ++ if (!udev_device) ++ return false; + +- if (udev) +- udev_unref(udev); ++ read_only = udev_device_get_sysattr_value(udev_device, "ro"); ++ if (read_only) ++ return streq(read_only, "1"); + +- return b; ++ return false; + } + + bool enough_ram(void) { +diff --git a/src/shared/fdset.h b/src/shared/fdset.h +index 1a26005..6277e46 100644 +--- a/src/shared/fdset.h ++++ b/src/shared/fdset.h +@@ -49,8 +49,5 @@ int fdset_iterate(FDSet *s, Iterator *i); + #define FDSET_FOREACH(fd, fds, i) \ + for ((i) = ITERATOR_FIRST, (fd) = fdset_iterate((fds), &(i)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i))) + +-static inline void fdset_freep(FDSet **fds) { +- if (*fds) +- fdset_free(*fds); +-} ++define_trivial_cleanup_func(FDSet*, fdset_free) + #define _cleanup_fdset_free_ _cleanup_(fdset_freep) +diff --git a/src/shared/install.c b/src/shared/install.c +index 9722ed4..b9c85b7 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -44,10 +44,8 @@ typedef struct { + Hashmap *have_installed; + } InstallContext; + +-#define _cleanup_lookup_paths_free_ \ +- __attribute__((cleanup(lookup_paths_free))) +-#define _cleanup_install_context_done_ \ +- __attribute__((cleanup(install_context_done))) ++#define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free) ++#define _cleanup_install_context_done_ _cleanup_(install_context_done) + + static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) { + assert(paths); +diff --git a/src/shared/set.h b/src/shared/set.h +index e5d46e9..a291470 100644 +--- a/src/shared/set.h ++++ b/src/shared/set.h +@@ -28,19 +28,13 @@ + * for each set use. */ + + #include "hashmap.h" ++#include "util.h" + + typedef struct Set Set; + + Set *set_new(hash_func_t hash_func, compare_func_t compare_func); + void set_free(Set* s); +-static inline void set_freep(Set **s) { +- set_free(*s); +-} +- + void set_free_free(Set *s); +-static inline void set_free_freep(Set **s) { +- set_free_free(*s); +-} + + Set* set_copy(Set *s); + int set_ensure_allocated(Set **s, hash_func_t hash_func, compare_func_t compare_func); +@@ -79,5 +73,7 @@ char **set_get_strv(Set *s); + #define SET_FOREACH_BACKWARDS(e, s, i) \ + for ((i) = ITERATOR_LAST, (e) = set_iterate_backwards((s), &(i)); (e); (e) = set_iterate_backwards((s), &(i))) + ++define_trivial_cleanup_func(Set*, set_free) ++define_trivial_cleanup_func(Set*, set_free_free) + #define _cleanup_set_free_ _cleanup_(set_freep) + #define _cleanup_set_free_free_ _cleanup_(set_free_freep) +diff --git a/src/shared/strv.h b/src/shared/strv.h +index d1f2a0e..4d117f8 100644 +--- a/src/shared/strv.h ++++ b/src/shared/strv.h +@@ -24,16 +24,13 @@ + #include + #include + +-#include "macro.h" ++#include "util.h" + + char *strv_find(char **l, const char *name) _pure_; + char *strv_find_prefix(char **l, const char *name) _pure_; + + void strv_free(char **l); +-static inline void strv_freep(char ***l) { +- strv_free(*l); +-} +- ++define_trivial_cleanup_func(char**, strv_free) + #define _cleanup_strv_free_ _cleanup_(strv_freep) + + char **strv_copy(char * const *l); +diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h +new file mode 100644 +index 0000000..bff8f5f +--- /dev/null ++++ b/src/shared/udev-util.h +@@ -0,0 +1,37 @@ ++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ ++ ++#pragma once ++ ++/*** ++ This file is part of systemd. ++ ++ Copyright 2013 Zbigniew Jędrzejewski-Szmek ++ ++ systemd is free software; you can redistribute it and/or modify it ++ under the terms of the GNU Lesser General Public License as published by ++ the Free Software Foundation; either version 2.1 of the License, or ++ (at your option) any later version. ++ ++ systemd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with systemd; If not, see . ++***/ ++ ++#include "udev.h" ++#include "util.h" ++ ++define_trivial_cleanup_func(struct udev*, udev_unref) ++define_trivial_cleanup_func(struct udev_device*, udev_device_unref) ++define_trivial_cleanup_func(struct udev_enumerate*, udev_enumerate_unref) ++define_trivial_cleanup_func(struct udev_event*, udev_event_unref) ++define_trivial_cleanup_func(struct udev_rules*, udev_rules_unref) ++ ++#define _cleanup_udev_unref_ _cleanup_(udev_unrefp) ++#define _cleanup_udev_device_unref_ _cleanup_(udev_device_unrefp) ++#define _cleanup_udev_enumerate_unref_ _cleanup_(udev_enumerate_unrefp) ++#define _cleanup_udev_event_unref_ _cleanup_(udev_event_unrefp) ++#define _cleanup_udev_rules_unref_ _cleanup_(udev_rules_unrefp) +diff --git a/src/shared/util.h b/src/shared/util.h +index 5a1e1bc..e577ef0 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -556,42 +556,33 @@ static inline void freep(void *p) { + free(*(void**) p); + } + +-static inline void fclosep(FILE **f) { +- if (*f) +- fclose(*f); +-} +- +-static inline void pclosep(FILE **f) { +- if (*f) +- pclose(*f); +-} ++#define define_trivial_cleanup_func(type, func) \ ++ static inline void func##p(type *p) { \ ++ if (*p) \ ++ func(*p); \ ++ } \ + + static inline void closep(int *fd) { + if (*fd >= 0) + close_nointr_nofail(*fd); + } + +-static inline void closedirp(DIR **d) { +- if (*d) +- closedir(*d); +-} +- + static inline void umaskp(mode_t *u) { + umask(*u); + } + +-static inline void endmntentp(FILE **f) { +- if (*f) +- endmntent(*f); +-} ++define_trivial_cleanup_func(FILE*, fclose) ++define_trivial_cleanup_func(FILE*, pclose) ++define_trivial_cleanup_func(DIR*, closedir) ++define_trivial_cleanup_func(FILE*, endmntent) + + #define _cleanup_free_ _cleanup_(freep) +-#define _cleanup_fclose_ _cleanup_(fclosep) +-#define _cleanup_pclose_ _cleanup_(pclosep) + #define _cleanup_close_ _cleanup_(closep) +-#define _cleanup_closedir_ _cleanup_(closedirp) + #define _cleanup_umask_ _cleanup_(umaskp) + #define _cleanup_globfree_ _cleanup_(globfree) ++#define _cleanup_fclose_ _cleanup_(fclosep) ++#define _cleanup_pclose_ _cleanup_(pclosep) ++#define _cleanup_closedir_ _cleanup_(closedirp) + #define _cleanup_endmntent_ _cleanup_(endmntentp) + + _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) { +diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c +index 716767b..ab7d5a9 100644 +--- a/src/test/test-libudev.c ++++ b/src/test/test-libudev.c +@@ -29,6 +29,7 @@ + #include + + #include "libudev.h" ++#include "udev-util.h" + #include "util.h" + + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +@@ -117,7 +118,7 @@ static void print_device(struct udev_device *device) + + static int test_device(struct udev *udev, const char *syspath) + { +- struct udev_device *device; ++ _cleanup_udev_device_unref_ struct udev_device *device; + + printf("looking at device: %s\n", syspath); + device = udev_device_new_from_syspath(udev, syspath); +@@ -126,13 +127,13 @@ static int test_device(struct udev *udev, const char *syspath) + return -1; + } + print_device(device); +- udev_device_unref(device); ++ + return 0; + } + + static int test_device_parents(struct udev *udev, const char *syspath) + { +- struct udev_device *device; ++ _cleanup_udev_device_unref_ struct udev_device *device; + struct udev_device *device_parent; + + printf("looking at device: %s\n", syspath); +@@ -153,7 +154,6 @@ static int test_device_parents(struct udev *udev, const char *syspath) + print_device(device_parent); + device_parent = udev_device_get_parent(device_parent); + } while (device_parent != NULL); +- udev_device_unref(device); + + return 0; + } +diff --git a/src/test/test-udev.c b/src/test/test-udev.c +index 52b61b4..17825f1 100644 +--- a/src/test/test-udev.c ++++ b/src/test/test-udev.c +@@ -34,6 +34,7 @@ + + #include "missing.h" + #include "udev.h" ++#include "udev-util.h" + + void udev_main_log(struct udev *udev, int priority, + const char *file, int line, const char *fn, +@@ -82,10 +83,10 @@ out: + + int main(int argc, char *argv[]) + { +- struct udev *udev; +- struct udev_event *event = NULL; +- struct udev_device *dev = NULL; +- struct udev_rules *rules = NULL; ++ _cleanup_udev_unref_ struct udev *udev = NULL; ++ _cleanup_udev_event_unref_ struct udev_event *event = NULL; ++ _cleanup_udev_device_unref_ struct udev_device *dev = NULL; ++ _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL; + char syspath[UTIL_PATH_SIZE]; + const char *devpath; + const char *action; +@@ -98,7 +99,8 @@ int main(int argc, char *argv[]) + + udev = udev_new(); + if (udev == NULL) +- exit(EXIT_FAILURE); ++ return EXIT_FAILURE; ++ + log_debug("version %s\n", VERSION); + label_init("/dev"); + +@@ -160,12 +162,7 @@ int main(int argc, char *argv[]) + out: + if (event != NULL && event->fd_signal >= 0) + close(event->fd_signal); +- udev_event_unref(event); +- udev_device_unref(dev); +- udev_rules_unref(rules); + label_finish(); +- udev_unref(udev); +- if (err != 0) +- return EXIT_FAILURE; +- return EXIT_SUCCESS; ++ ++ return err ? EXIT_FAILURE : EXIT_SUCCESS; + } +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 67b13bc..309fa07 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -996,10 +996,7 @@ static void item_free(Item *i) { + free(i); + } + +-static inline void item_freep(Item **i) { +- if (*i) +- item_free(*i); +-} ++define_trivial_cleanup_func(Item*, item_free) + #define _cleanup_item_free_ _cleanup_(item_freep) + + static bool item_equal(Item *a, Item *b) { diff --git a/SOURCES/0245-fsck-modernization.patch b/SOURCES/0245-fsck-modernization.patch new file mode 100644 index 0000000..bcb1278 --- /dev/null +++ b/SOURCES/0245-fsck-modernization.patch @@ -0,0 +1,140 @@ +From 64de3526cce9ef980b37fcb5c412a2734132ad47 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 11 Nov 2013 23:32:31 -0500 +Subject: [PATCH] fsck: modernization + +(cherry picked from commit e375825da0cbdbf3be755c277f9c0dec35b41a09) + +Related: #1098310 +--- + src/fsck/fsck.c | 43 ++++++++++++++++++------------------------- + 1 file changed, 18 insertions(+), 25 deletions(-) + +diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c +index 96a79dd..9b4e555 100644 +--- a/src/fsck/fsck.c ++++ b/src/fsck/fsck.c +@@ -176,7 +176,7 @@ static double percent(int pass, unsigned long cur, unsigned long max) { + } + + static int process_progress(int fd) { +- FILE *f, *console; ++ _cleanup_fclose_ FILE *console = NULL, *f = NULL; + usec_t last = 0; + bool locked = false; + int clear = 0; +@@ -188,15 +188,13 @@ static int process_progress(int fd) { + } + + console = fopen("/dev/console", "w"); +- if (!console) { +- fclose(f); ++ if (!console) + return -ENOMEM; +- } + + while (!feof(f)) { + int pass, m; + unsigned long cur, max; +- char *device; ++ _cleanup_free_ char *device = NULL; + double p; + usec_t t; + +@@ -205,20 +203,16 @@ static int process_progress(int fd) { + + /* Only show one progress counter at max */ + if (!locked) { +- if (flock(fileno(console), LOCK_EX|LOCK_NB) < 0) { +- free(device); ++ if (flock(fileno(console), LOCK_EX|LOCK_NB) < 0) + continue; +- } + + locked = true; + } + + /* Only update once every 50ms */ + t = now(CLOCK_MONOTONIC); +- if (last + 50 * USEC_PER_MSEC > t) { +- free(device); ++ if (last + 50 * USEC_PER_MSEC > t) + continue; +- } + + last = t; + +@@ -226,8 +220,6 @@ static int process_progress(int fd) { + fprintf(console, "\r%s: fsck %3.1f%% complete...\r%n", device, p, &m); + fflush(console); + +- free(device); +- + if (m > clear) + clear = m; + } +@@ -242,8 +234,6 @@ static int process_progress(int fd) { + fflush(console); + } + +- fclose(f); +- fclose(console); + return 0; + } + +@@ -287,34 +277,37 @@ int main(int argc, char *argv[]) { + + if (stat("/", &st) < 0) { + log_error("Failed to stat() the root directory: %m"); +- goto finish; ++ return EXIT_FAILURE; + } + + /* Virtual root devices don't need an fsck */ + if (major(st.st_dev) == 0) +- return 0; ++ return EXIT_SUCCESS; + + /* check if we are already writable */ + times[0] = st.st_atim; + times[1] = st.st_mtim; + if (utimensat(AT_FDCWD, "/", times, 0) == 0) { + log_info("Root directory is writable, skipping check."); +- return 0; ++ return EXIT_SUCCESS; + } + +- if (!(udev = udev_new())) { ++ udev = udev_new(); ++ if (!udev) { + log_oom(); +- goto finish; ++ return EXIT_FAILURE; + } + +- if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) { ++ udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev); ++ if (!udev_device) { + log_error("Failed to detect root device."); +- goto finish; ++ return EXIT_FAILURE; + } + +- if (!(device = udev_device_get_devnode(udev_device))) { ++ device = udev_device_get_devnode(udev_device); ++ if (!device) { + log_error("Failed to detect device node of root directory."); +- goto finish; ++ return EXIT_FAILURE; + } + + root_directory = true; +@@ -323,7 +316,7 @@ int main(int argc, char *argv[]) { + if (arg_show_progress) + if (pipe(progress_pipe) < 0) { + log_error("pipe(): %m"); +- goto finish; ++ return EXIT_FAILURE; + } + + cmdline[i++] = "/sbin/fsck"; diff --git a/SOURCES/0246-fsck-fstab-generator-be-lenient-about-missing-fsck.-.patch b/SOURCES/0246-fsck-fstab-generator-be-lenient-about-missing-fsck.-.patch new file mode 100644 index 0000000..75266a0 --- /dev/null +++ b/SOURCES/0246-fsck-fstab-generator-be-lenient-about-missing-fsck.-.patch @@ -0,0 +1,212 @@ +From c9e49e522d609f39ab77cbab18b8f1389692e1b8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 12 Nov 2013 00:53:59 -0500 +Subject: [PATCH] fsck,fstab-generator: be lenient about missing fsck. + +If fstab contains 1 for passno, treat this as an error, but only warn +briefly. If fstab doesn't contain this information, don't complain at +all. + +Patch is complicated a bit by the fact that we might have the fstype specified +in fstab or on /proc/cmdline, in which case we can check if we have the appropriate +fsck tool, or not specified, or specified as auto, in which case we have to look +and check the type of the filesystem ourselves. It cannot be done before the +device appears, so it is too early in the generator phase, and it must be done +directly in fsck service. + +(cherry picked from commit 94192cdaf652c9717f15274504ed315126c07a93) + +Resolves: #1098310 +--- + src/fsck/fsck.c | 40 ++++++++++++++---- + src/fstab-generator/fstab-generator.c | 77 +++++++++++++++++++++++------------ + 2 files changed, 82 insertions(+), 35 deletions(-) + +diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c +index 9b4e555..1189fe7 100644 +--- a/src/fsck/fsck.c ++++ b/src/fsck/fsck.c +@@ -244,10 +244,11 @@ int main(int argc, char *argv[]) { + siginfo_t status; + _cleanup_udev_unref_ struct udev *udev = NULL; + _cleanup_udev_device_unref_ struct udev_device *udev_device = NULL; +- const char *device; ++ const char *device, *type; + bool root_directory; + int progress_pipe[2] = { -1, -1 }; + char dash_c[2+10+1]; ++ struct stat st; + + if (argc > 2) { + log_error("This program expects one or no arguments."); +@@ -266,11 +267,27 @@ int main(int argc, char *argv[]) { + if (!arg_force && arg_skip) + return 0; + ++ udev = udev_new(); ++ if (!udev) { ++ log_oom(); ++ return EXIT_FAILURE; ++ } ++ + if (argc > 1) { + device = argv[1]; + root_directory = false; ++ ++ if (stat(device, &st) < 0) { ++ log_error("Failed to stat '%s': %m", device); ++ return EXIT_FAILURE; ++ } ++ ++ udev_device = udev_device_new_from_devnum(udev, 'b', st.st_rdev); ++ if (!udev_device) { ++ log_error("Failed to detect device %s", device); ++ return EXIT_FAILURE; ++ } + } else { +- struct stat st; + struct timespec times[2]; + + /* Find root device */ +@@ -292,12 +309,6 @@ int main(int argc, char *argv[]) { + return EXIT_SUCCESS; + } + +- udev = udev_new(); +- if (!udev) { +- log_oom(); +- return EXIT_FAILURE; +- } +- + udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev); + if (!udev_device) { + log_error("Failed to detect root device."); +@@ -313,6 +324,19 @@ int main(int argc, char *argv[]) { + root_directory = true; + } + ++ type = udev_device_get_property_value(udev_device, "ID_FS_TYPE"); ++ if (type) { ++ const char *checker = strappenda("/sbin/fsck.", type); ++ r = access(checker, X_OK); ++ if (r < 0) { ++ if (errno == ENOENT) { ++ log_info("%s doesn't exist, not checking file system.", checker); ++ return EXIT_SUCCESS; ++ } else ++ log_warning("%s cannot be used: %m", checker); ++ } ++ } ++ + if (arg_show_progress) + if (pipe(progress_pipe) < 0) { + log_error("pipe(): %m"); +diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c +index 78d7609..fa23ac9 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -147,6 +147,52 @@ static bool mount_in_initrd(struct mntent *me) { + streq(me->mnt_dir, "/usr"); + } + ++static int add_fsck(FILE *f, const char *what, const char *where, const char *type, int passno) { ++ assert(f); ++ ++ if (passno == 0) ++ return 0; ++ ++ if (type && !streq(type, "auto")) { ++ int r; ++ const char *checker; ++ ++ checker = strappenda("/sbin/fsck.", type); ++ r = access(checker, X_OK); ++ if (r < 0) { ++ log_warning("Checking was requested for %s, but %s cannot be used: %m", what, checker); ++ ++ /* treat missing check as essentially OK */ ++ return errno == ENOENT ? 0 : -errno; ++ } ++ } ++ ++ if (streq(where, "/")) { ++ char *lnk; ++ ++ lnk = strappenda(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service"); ++ mkdir_parents_label(lnk, 0755); ++ if (symlink("systemd-fsck-root.service", lnk) < 0) { ++ log_error("Failed to create symlink %s: %m", lnk); ++ return -errno; ++ } ++ } else { ++ _cleanup_free_ char *fsck = NULL; ++ ++ fsck = unit_name_from_path_instance("systemd-fsck", what, ".service"); ++ if (!fsck) ++ return log_oom(); ++ ++ fprintf(f, ++ "Requires=%s\n" ++ "After=%s\n", ++ fsck, ++ fsck); ++ } ++ ++ return 0; ++} ++ + static int add_mount( + const char *what, + const char *where, +@@ -162,6 +208,7 @@ static int add_mount( + *name = NULL, *unit = NULL, *lnk = NULL, + *automount_name = NULL, *automount_unit = NULL; + _cleanup_fclose_ FILE *f = NULL; ++ int r; + + assert(what); + assert(where); +@@ -209,32 +256,9 @@ static int add_mount( + "Before=%s\n", + post); + +- if (passno > 0) { +- if (streq(where, "/")) { +- lnk = strjoin(arg_dest, "/", SPECIAL_LOCAL_FS_TARGET, ".wants/", "systemd-fsck-root.service", NULL); +- if (!lnk) +- return log_oom(); +- +- mkdir_parents_label(lnk, 0755); +- if (symlink("systemd-fsck-root.service", lnk) < 0) { +- log_error("Failed to create symlink %s: %m", lnk); +- return -errno; +- } +- } else { +- _cleanup_free_ char *fsck = NULL; +- +- fsck = unit_name_from_path_instance("systemd-fsck", what, ".service"); +- if (!fsck) +- return log_oom(); +- +- fprintf(f, +- "Requires=%s\n" +- "After=%s\n", +- fsck, +- fsck); +- } +- } +- ++ r = add_fsck(f, what, where, type, passno); ++ if (r < 0) ++ return r; + + fprintf(f, + "\n" +@@ -260,7 +284,6 @@ static int add_mount( + + if (!noauto) { + if (post) { +- free(lnk); + lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL); + if (!lnk) + return log_oom(); diff --git a/SOURCES/0247-rules-60-persistent-storage-add-nvme-pcie-ssd-scsi_i.patch b/SOURCES/0247-rules-60-persistent-storage-add-nvme-pcie-ssd-scsi_i.patch new file mode 100644 index 0000000..d883427 --- /dev/null +++ b/SOURCES/0247-rules-60-persistent-storage-add-nvme-pcie-ssd-scsi_i.patch @@ -0,0 +1,24 @@ +From 5d050e50b2028d3b29f2ecd7a6e5fe0ab543c1df Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Mon, 28 Jul 2014 16:31:32 +0200 +Subject: [PATCH] rules/60-persistent-storage: add nvme pcie ssd scsi_id ENV + +Resolves: #1042990 +--- + rules/60-persistent-storage.rules | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules +index a4d009a..c47c130 100644 +--- a/rules/60-persistent-storage.rules ++++ b/rules/60-persistent-storage.rules +@@ -42,6 +42,9 @@ KERNEL=="cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}!="?*", IMPORT{program}="s + KERNEL=="sd*|sr*|cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" + KERNEL=="sd*|cciss*", ENV{DEVTYPE}=="partition", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" + ++# NVMe ++KERNEL=="nvme*", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $tempnode" ++ + # firewire + KERNEL=="sd*[!0-9]|sr*", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}" + KERNEL=="sd*[0-9]", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}-part%n" diff --git a/SOURCES/0248-cgls-fix-running-with-M-option.patch b/SOURCES/0248-cgls-fix-running-with-M-option.patch new file mode 100644 index 0000000..f0c728e --- /dev/null +++ b/SOURCES/0248-cgls-fix-running-with-M-option.patch @@ -0,0 +1,166 @@ +From 2b7fc0e2a0a680fe61041e569eda50f06c3f8768 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Mon, 28 Jul 2014 18:18:58 +0200 +Subject: [PATCH] cgls: fix running with -M option + +systemd-machined doesn't store cgroup path in a state file anymore. +Let's figure it out from the scope. + +Resolves: #1085455 +--- + Makefile.am | 8 +++++- + src/cgls/cgls.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 91 insertions(+), 2 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index fa2fba6..a9fb792 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1830,8 +1830,14 @@ systemd_reply_password_LDADD = \ + systemd_cgls_SOURCES = \ + src/cgls/cgls.c + ++systemd_cgls_CFLAGS = \ ++ $(AM_CFLAGS) \ ++ $(DBUS_CFLAGS) ++ + systemd_cgls_LDADD = \ +- libsystemd-shared.la ++ libsystemd-shared.la \ ++ libsystemd-dbus.la \ ++ libudev.la + + # ------------------------------------------------------------------------------ + systemd_cgtop_SOURCES = \ +diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c +index c689b5c..f678657 100644 +--- a/src/cgls/cgls.c ++++ b/src/cgls/cgls.c +@@ -19,6 +19,7 @@ + along with systemd; If not, see . + ***/ + ++#include + #include + #include + #include +@@ -35,6 +36,8 @@ + #include "build.h" + #include "output-mode.h" + #include "fileio.h" ++#include "dbus-common.h" ++#include "unit-name.h" + + static bool arg_no_pager = false; + static bool arg_kernel_threads = false; +@@ -127,6 +130,10 @@ int main(int argc, char *argv[]) { + int r = 0, retval = EXIT_FAILURE; + int output_flags; + char _cleanup_free_ *root = NULL; ++ DBusConnection *bus = NULL; ++ DBusError error; ++ ++ dbus_error_init(&error); + + log_parse_environment(); + log_open(); +@@ -147,6 +154,14 @@ int main(int argc, char *argv[]) { + } + } + ++ bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); ++ ++ if (!bus) { ++ printf("Failed to get D-Bus connection: %s", error.message); ++ retval = EXIT_FAILURE; ++ goto finish; ++ } ++ + output_flags = + arg_all * OUTPUT_SHOW_ALL | + (arg_full > 0) * OUTPUT_FULL_WIDTH; +@@ -189,8 +204,67 @@ int main(int argc, char *argv[]) { + } else { + if (arg_machine) { + char *m; ++ const char *cgroup; ++ const char *property = "ControlGroup"; ++ const char *interface = "org.freedesktop.systemd1.Scope"; ++ _cleanup_free_ char *scope = NULL; ++ _cleanup_free_ char *path = NULL; ++ _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; ++ DBusMessageIter iter, sub; ++ + m = strappenda("/run/systemd/machines/", arg_machine); +- r = parse_env_file(m, NEWLINE, "CGROUP", &root, NULL); ++ r = parse_env_file(m, NEWLINE, "SCOPE", &scope, NULL); ++ ++ if (r < 0) { ++ log_error("Failed to get machine path: %s", strerror(-r)); ++ goto finish; ++ } ++ ++ path = unit_dbus_path_from_name(scope); ++ if (!path) { ++ r = log_oom(); ++ goto finish; ++ } ++ ++ r = bus_method_call_with_reply( ++ bus, ++ "org.freedesktop.systemd1", ++ path, ++ "org.freedesktop.DBus.Properties", ++ "Get", ++ &reply, ++ &error, ++ DBUS_TYPE_STRING, &interface, ++ DBUS_TYPE_STRING, &property, ++ DBUS_TYPE_INVALID); ++ if (r < 0) { ++ log_error("Failed to query ControlGroup: %s", bus_error(&error, r)); ++ dbus_error_free(&error); ++ goto finish; ++ } ++ ++ if (!dbus_message_iter_init(reply, &iter) || ++ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { ++ log_error("Failed to parse reply."); ++ r = -EINVAL; ++ goto finish; ++ } ++ ++ dbus_message_iter_recurse(&iter, &sub); ++ if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { ++ log_error("Failed to parse reply."); ++ r = -EINVAL; ++ goto finish; ++ } ++ ++ dbus_message_iter_get_basic(&sub, &cgroup); ++ ++ root = strdup(cgroup); ++ if (!root) { ++ r = log_oom(); ++ goto finish; ++ } ++ + } else + r = cg_get_root_path(&root); + if (r < 0) { +@@ -211,6 +285,15 @@ int main(int argc, char *argv[]) { + retval = EXIT_SUCCESS; + + finish: ++ ++ if (bus) { ++ dbus_connection_flush(bus); ++ dbus_connection_close(bus); ++ dbus_connection_unref(bus); ++ } ++ ++ dbus_error_free(&error); ++ dbus_shutdown(); + pager_close(); + + return retval; diff --git a/SOURCES/0249-units-when-spawning-a-getty-configure-TERM-explicitl.patch b/SOURCES/0249-units-when-spawning-a-getty-configure-TERM-explicitl.patch new file mode 100644 index 0000000..a220c7b --- /dev/null +++ b/SOURCES/0249-units-when-spawning-a-getty-configure-TERM-explicitl.patch @@ -0,0 +1,60 @@ +From fa600b8b075ad4c717bd5f60fd3c6b5545cc75c5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 18 Dec 2013 17:48:31 +0100 +Subject: [PATCH] units: when spawning a getty configure TERM explicitly + +This way we can make use of our logic to automatically determine an +appropriate TERM for a specific tty. + +Conflicts: + units/console-getty.service.m4.in + units/container-getty@.service.m4.in + +(cherry picked from commit ccf22d4a104e6ed2666d6c5b4031981a84787790) + +Related: #1075729 +--- + units/console-getty.service.m4.in | 2 +- + units/getty@.service.m4 | 2 +- + units/serial-getty@.service.m4 | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/units/console-getty.service.m4.in b/units/console-getty.service.m4.in +index 2fd9dd8..8ac51a4 100644 +--- a/units/console-getty.service.m4.in ++++ b/units/console-getty.service.m4.in +@@ -15,7 +15,7 @@ After=rc-local.service + Before=getty.target + + [Service] +-ExecStart=-/sbin/agetty --noclear -s console 115200,38400,9600 ++ExecStart=-/sbin/agetty --noclear --keep-baud console 115200,38400,9600 $TERM + Type=idle + Restart=always + RestartSec=0 +diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 +index 253da85..aa853b8 100644 +--- a/units/getty@.service.m4 ++++ b/units/getty@.service.m4 +@@ -27,7 +27,7 @@ ConditionPathExists=/dev/tty0 + + [Service] + # the VT is cleared by TTYVTDisallocate +-ExecStart=-/sbin/agetty --noclear %I ++ExecStart=-/sbin/agetty --noclear %I $TERM + Type=idle + Restart=always + RestartSec=0 +diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 +index aea078f..e94cdb4 100644 +--- a/units/serial-getty@.service.m4 ++++ b/units/serial-getty@.service.m4 +@@ -22,7 +22,7 @@ Before=getty.target + IgnoreOnIsolate=yes + + [Service] +-ExecStart=-/sbin/agetty --keep-baud %I 115200,38400,9600 ++ExecStart=-/sbin/agetty --keep-baud %I 115200,38400,9600 $TERM + Type=idle + Restart=always + RestartSec=0 diff --git a/SOURCES/0250-getty-Start-getty-on-3270-terminals-available-on-Lin.patch b/SOURCES/0250-getty-Start-getty-on-3270-terminals-available-on-Lin.patch new file mode 100644 index 0000000..8bc3414 --- /dev/null +++ b/SOURCES/0250-getty-Start-getty-on-3270-terminals-available-on-Lin.patch @@ -0,0 +1,84 @@ +From 39456b9f6e692a2385bf1288a53d02dd9abac8d5 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Tue, 11 Mar 2014 18:41:09 +0100 +Subject: [PATCH] getty: Start getty on 3270 terminals available on Linux on + System z + +Add the first 3270 terminal device that is associated with the Linux preferred +console to the list of virtualization consoles. This is required to +automatically start a getty if the conmode=3270 kernel parameter is specified +for Linux on z/VM instances. Note that a queued upstream patch also enable +the 3270 terminal device if it is associated with the Linux preferred console. +How + +To successfully start agetty on a 3270 terminal, a change in the agetty +parameter order is required. Previously, agetty would started like this: + + /sbin/agetty --keep-baud 3270/tty1 115200,38400,9600 TERM + +The agetty program interprets the "3270/tty1" as baud rate and fails to start +with the "bad speed: 3270/tty1" error message. Fixing this in agetty is more +complex rather than reordering the command line parameters like this: + + /sbin/agetty --keep-baud 115200,38400,9600 3270/tty1 TERM + +According to agetty sources and "agetty --help", agetty accepts the "tty", +"baudrate tty", and "tty baudrate" specifications. + +P.S. The "tty: Set correct tty name in 'active' sysfs attribute" introduces + a change to display the terminal device which is associated with the + Linux preferred console. This change helps to let systemd handle this + particular case only. Without the changes of this commit, no additional + 3270 terminal device can be managed by systemd. + + https://git.kernel.org/cgit/linux/kernel/git/gregkh/tty.git/commit/?id=723abd87f6e536f1353c8f64f621520bc29523a3 + +(cherry picked from commit fc6c7fe9becdd70ae6b671c396f2ad2db0b71cd7) + +Resolves: #1075729 +--- + rules/99-systemd.rules.in | 2 +- + src/getty-generator/getty-generator.c | 3 ++- + units/serial-getty@.service.m4 | 2 +- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in +index 0471719..308a074 100644 +--- a/rules/99-systemd.rules.in ++++ b/rules/99-systemd.rules.in +@@ -7,7 +7,7 @@ + + ACTION=="remove", GOTO="systemd_end" + +-SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*", TAG+="systemd" ++SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty[0-9]*", TAG+="systemd" + + KERNEL=="vport*", TAG+="systemd" + +diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c +index 40374b5..5a1997f 100644 +--- a/src/getty-generator/getty-generator.c ++++ b/src/getty-generator/getty-generator.c +@@ -93,7 +93,8 @@ int main(int argc, char *argv[]) { + "xvc0\0" + "hvsi0\0" + "sclp_line0\0" +- "ttysclp0\0"; ++ "ttysclp0\0" ++ "3270!tty1\0"; + + int r = EXIT_SUCCESS; + char *active; +diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 +index e94cdb4..4ac51e7 100644 +--- a/units/serial-getty@.service.m4 ++++ b/units/serial-getty@.service.m4 +@@ -22,7 +22,7 @@ Before=getty.target + IgnoreOnIsolate=yes + + [Service] +-ExecStart=-/sbin/agetty --keep-baud %I 115200,38400,9600 $TERM ++ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM + Type=idle + Restart=always + RestartSec=0 diff --git a/SOURCES/0251-core-Added-support-for-ERRNO-NOTIFY_SOCKET-message-p.patch b/SOURCES/0251-core-Added-support-for-ERRNO-NOTIFY_SOCKET-message-p.patch new file mode 100644 index 0000000..fce708d --- /dev/null +++ b/SOURCES/0251-core-Added-support-for-ERRNO-NOTIFY_SOCKET-message-p.patch @@ -0,0 +1,126 @@ +From 4323a5406bb40c76076814fd998e09c58b433e7d Mon Sep 17 00:00:00 2001 +From: Miguel Angel Ajo +Date: Mon, 7 Jul 2014 14:20:36 +0200 +Subject: [PATCH] core: Added support for ERRNO NOTIFY_SOCKET message parsing + +Added StatusErrno dbus property along StatusText to allow notification of +numeric status condition while degraded service operation or any other special +situation. + +(cherry picked from commit 4774e357268e4a1e9fa82adb0563a538932a4c8e) + +Resolves: #1106457 +--- + src/core/dbus-service.c | 3 +++ + src/core/service.c | 33 +++++++++++++++++++++++++++++---- + src/core/service.h | 1 + + 3 files changed, 33 insertions(+), 4 deletions(-) + +diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c +index 696c446..edfc7ff 100644 +--- a/src/core/dbus-service.c ++++ b/src/core/dbus-service.c +@@ -64,6 +64,7 @@ + " \n" \ + " \n" \ + " \n" \ ++ " \n" \ + " \n" \ + " \n" + +@@ -96,6 +97,7 @@ const char bus_service_invalidating_properties[] = + "MainPID\0" + "ControlPID\0" + "StatusText\0" ++ "StatusErrno\0" + "Result\0"; + + static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType); +@@ -144,6 +146,7 @@ static const BusProperty bus_service_properties[] = { + { "ControlPID", bus_property_append_pid, "u", offsetof(Service, control_pid) }, + { "BusName", bus_property_append_string, "s", offsetof(Service, bus_name), true }, + { "StatusText", bus_property_append_string, "s", offsetof(Service, status_text), true }, ++ { "StatusErrno", bus_property_append_int, "i", offsetof(Service, status_errno) }, + { "Result", bus_service_append_service_result,"s", offsetof(Service, result) }, + {} + }; +diff --git a/src/core/service.c b/src/core/service.c +index f6fdbbc..3f6c8ac 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -3443,6 +3443,7 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) { + static void service_notify_message(Unit *u, pid_t pid, char **tags) { + Service *s = SERVICE(u); + const char *e; ++ bool notify_dbus = false; + + assert(u); + +@@ -3478,6 +3479,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { + "%s: got %s", u->id, e); + service_set_main_pid(s, pid); + unit_watch_pid(UNIT(s), pid); ++ notify_dbus = true; + } + } + +@@ -3516,12 +3518,34 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { + + free(s->status_text); + s->status_text = t; +- } else { ++ } else ++ t = NULL; ++ ++ if (!streq_ptr(s->status_text, t)) { + free(s->status_text); +- s->status_text = NULL; +- } ++ s->status_text = t; ++ notify_dbus = true; ++ } else ++ free(t); ++ } ++ ++ /* Interpret ERRNO= */ ++ e = strv_find_prefix(tags, "ERRNO="); ++ if (e) { ++ int status_errno; + ++ if (safe_atoi(e + 6, &status_errno) < 0) ++ log_warning_unit(u->id, "Failed to parse ERRNO= field in notification message: %s", e); ++ else { ++ log_debug_unit(u->id, "%s: got %s", u->id, e); ++ ++ if (s->status_errno != status_errno) { ++ s->status_errno = status_errno; ++ notify_dbus = true; ++ } ++ } + } ++ + if (strv_find(tags, "WATCHDOG=1")) { + log_debug_unit(u->id, + "%s: got WATCHDOG=1", u->id); +@@ -3530,7 +3554,8 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { + } + + /* Notify clients about changed status or main pid */ +- unit_add_to_dbus_queue(u); ++ if (notify_dbus) ++ unit_add_to_dbus_queue(u); + } + + #ifdef HAVE_SYSV_COMPAT +diff --git a/src/core/service.h b/src/core/service.h +index ce5b5e0..fa4ef2b 100644 +--- a/src/core/service.h ++++ b/src/core/service.h +@@ -187,6 +187,7 @@ struct Service { + char *bus_name; + + char *status_text; ++ int status_errno; + + RateLimit start_limit; + StartLimitAction start_limit_action; diff --git a/SOURCES/0252-service-don-t-accept-negative-ERRNO-notification-mes.patch b/SOURCES/0252-service-don-t-accept-negative-ERRNO-notification-mes.patch new file mode 100644 index 0000000..2e2d570 --- /dev/null +++ b/SOURCES/0252-service-don-t-accept-negative-ERRNO-notification-mes.patch @@ -0,0 +1,25 @@ +From 865e6e46f235bc9c58e61024696fff216e7a2182 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 7 Jul 2014 17:32:44 +0200 +Subject: [PATCH] service: don't accept negative ERRNO= notification messages + +(cherry picked from commit 2040ccf171404b709acb0ecf1d1f17b87c5d05f0) + +Related: #1106457 +--- + src/core/service.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 3f6c8ac..814019d 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -3534,7 +3534,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { + if (e) { + int status_errno; + +- if (safe_atoi(e + 6, &status_errno) < 0) ++ if (safe_atoi(e + 6, &status_errno) < 0 || status_errno < 0) + log_warning_unit(u->id, "Failed to parse ERRNO= field in notification message: %s", e); + else { + log_debug_unit(u->id, "%s: got %s", u->id, e); diff --git a/SOURCES/0253-socket-add-SocketUser-and-SocketGroup-for-chown-ing-.patch b/SOURCES/0253-socket-add-SocketUser-and-SocketGroup-for-chown-ing-.patch new file mode 100644 index 0000000..4670661 --- /dev/null +++ b/SOURCES/0253-socket-add-SocketUser-and-SocketGroup-for-chown-ing-.patch @@ -0,0 +1,610 @@ +From 6744ef720b34a87ff69acb8535cf5e83db6f5e8b Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 24 Jun 2014 14:50:26 +0200 +Subject: [PATCH] socket: add SocketUser= and SocketGroup= for chown()ing + sockets in the file system + +This is relatively complex, as we cannot invoke NSS from PID 1, and thus +need to fork a helper process temporarily. + +(cherry picked from commit 3900e5fdff688dc3c273f177d9d913b7389d5561) + +Resolves: #1111761 +--- + man/systemd.socket.xml | 38 ++++-- + src/core/dbus-socket.c | 8 +- + src/core/load-fragment-gperf.gperf.m4 | 4 +- + src/core/socket.c | 220 +++++++++++++++++++++++++++------- + src/core/socket.h | 5 + + src/shared/exit-status.c | 4 + + src/shared/exit-status.h | 3 +- + 7 files changed, 224 insertions(+), 58 deletions(-) + +diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml +index 570a6fb..d146b3b 100644 +--- a/man/systemd.socket.xml ++++ b/man/systemd.socket.xml +@@ -372,16 +372,21 @@ + + + +- DirectoryMode= +- If listening on a file +- system socket or FIFO, the parent +- directories are automatically created +- if needed. This option specifies the +- file system access mode used when +- creating these directories. Takes an +- access mode in octal +- notation. Defaults to +- 0755. ++ SocketUser= ++ SocketGroup= ++ ++ Takes a UNIX ++ user/group name. When specified ++ all AF_UNIX sockets and FIFO nodes in ++ the file system are owned by the ++ specified user and group. If unset ++ (the default), the nodes are owned by ++ the root user/group (if run in system ++ context) or the invoking user/group ++ (if run in user context). If only a ++ user is specified but no group, then ++ the group is derived from the user's ++ default group. + + + +@@ -396,6 +401,19 @@ + + + ++ DirectoryMode= ++ If listening on a file ++ system socket or FIFO, the parent ++ directories are automatically created ++ if needed. This option specifies the ++ file system access mode used when ++ creating these directories. Takes an ++ access mode in octal ++ notation. Defaults to ++ 0755. ++ ++ ++ + Accept= + Takes a boolean + argument. If true, a service instance +diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c +index 30c4b63..870bcdc 100644 +--- a/src/core/dbus-socket.c ++++ b/src/core/dbus-socket.c +@@ -44,8 +44,10 @@ + BUS_CGROUP_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ +- " \n" \ ++ " \n" \ ++ " \n" \ + " \n" \ ++ " \n" \ + " \n" \ + " \n" \ + " \n" \ +@@ -172,8 +174,10 @@ static const BusProperty bus_socket_properties[] = { + BUS_EXEC_COMMAND_PROPERTY("ExecStopPost", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_POST]), true ), + { "ControlPID", bus_property_append_pid, "u", offsetof(Socket, control_pid) }, + { "BindToDevice", bus_property_append_string, "s", offsetof(Socket, bind_to_device), true }, +- { "DirectoryMode", bus_property_append_mode, "u", offsetof(Socket, directory_mode) }, ++ { "SocketUser", bus_property_append_string, "s", offsetof(Socket, user), true }, ++ { "SocketGroup", bus_property_append_string, "s", offsetof(Socket, group), true }, + { "SocketMode", bus_property_append_mode, "u", offsetof(Socket, socket_mode) }, ++ { "DirectoryMode", bus_property_append_mode, "u", offsetof(Socket, directory_mode) }, + { "Accept", bus_property_append_bool, "b", offsetof(Socket, accept) }, + { "KeepAlive", bus_property_append_bool, "b", offsetof(Socket, keep_alive) }, + { "Priority", bus_property_append_int, "i", offsetof(Socket, priority) }, +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index d65bcc1..0991cb9 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -193,8 +193,10 @@ Socket.ExecStartPost, config_parse_exec, SOCKET_EXEC + Socket.ExecStopPre, config_parse_exec, SOCKET_EXEC_STOP_PRE, offsetof(Socket, exec_command) + Socket.ExecStopPost, config_parse_exec, SOCKET_EXEC_STOP_POST, offsetof(Socket, exec_command) + Socket.TimeoutSec, config_parse_sec, 0, offsetof(Socket, timeout_usec) +-Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode) ++Socket.SocketUser, config_parse_unit_string_printf, 0, offsetof(Socket, user) ++Socket.SocketGroup, config_parse_unit_string_printf, 0, offsetof(Socket, group) + Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode) ++Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode) + Socket.Accept, config_parse_bool, 0, offsetof(Socket, accept) + Socket.MaxConnections, config_parse_unsigned, 0, offsetof(Socket, max_connections) + Socket.KeepAlive, config_parse_bool, 0, offsetof(Socket, keep_alive) +diff --git a/src/core/socket.c b/src/core/socket.c +index e673f38..32e0d35 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -54,6 +54,7 @@ + static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { + [SOCKET_DEAD] = UNIT_INACTIVE, + [SOCKET_START_PRE] = UNIT_ACTIVATING, ++ [SOCKET_START_CHOWN] = UNIT_ACTIVATING, + [SOCKET_START_POST] = UNIT_ACTIVATING, + [SOCKET_LISTENING] = UNIT_ACTIVE, + [SOCKET_RUNNING] = UNIT_ACTIVE, +@@ -147,6 +148,8 @@ static void socket_done(Unit *u) { + free(s->smack); + free(s->smack_ip_in); + free(s->smack_ip_out); ++ free(s->user); ++ free(s->group); + + unit_unwatch_timer(u, &s->timer_watch); + } +@@ -527,6 +530,16 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { + "%sSmackLabelIPOut: %s\n", + prefix, s->smack_ip_out); + ++ if (s->user) ++ fprintf(f, ++ "%sOwnerUser: %s\n", ++ prefix, s->user); ++ ++ if (s->group) ++ fprintf(f, ++ "%sOwnerGroup: %s\n", ++ prefix, s->user); ++ + LIST_FOREACH(port, p, s->ports) { + + if (p->type == SOCKET_SOCKET) { +@@ -1100,6 +1113,7 @@ static void socket_set_state(Socket *s, SocketState state) { + s->state = state; + + if (state != SOCKET_START_PRE && ++ state != SOCKET_START_CHOWN && + state != SOCKET_START_POST && + state != SOCKET_STOP_PRE && + state != SOCKET_STOP_PRE_SIGTERM && +@@ -1116,7 +1130,8 @@ static void socket_set_state(Socket *s, SocketState state) { + if (state != SOCKET_LISTENING) + socket_unwatch_fds(s); + +- if (state != SOCKET_START_POST && ++ if (state != SOCKET_START_CHOWN && ++ state != SOCKET_START_POST && + state != SOCKET_LISTENING && + state != SOCKET_RUNNING && + state != SOCKET_STOP_PRE && +@@ -1143,6 +1158,7 @@ static int socket_coldplug(Unit *u) { + if (s->deserialized_state != s->state) { + + if (s->deserialized_state == SOCKET_START_PRE || ++ s->deserialized_state == SOCKET_START_CHOWN || + s->deserialized_state == SOCKET_START_POST || + s->deserialized_state == SOCKET_STOP_PRE || + s->deserialized_state == SOCKET_STOP_PRE_SIGTERM || +@@ -1163,7 +1179,8 @@ static int socket_coldplug(Unit *u) { + return r; + } + +- if (s->deserialized_state == SOCKET_START_POST || ++ if (s->deserialized_state == SOCKET_START_CHOWN || ++ s->deserialized_state == SOCKET_START_POST || + s->deserialized_state == SOCKET_LISTENING || + s->deserialized_state == SOCKET_RUNNING || + s->deserialized_state == SOCKET_STOP_PRE || +@@ -1185,7 +1202,7 @@ static int socket_coldplug(Unit *u) { + static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + pid_t pid; + int r; +- char **argv; ++ _cleanup_strv_free_ char **argv = NULL; + + assert(s); + assert(c); +@@ -1216,11 +1233,11 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + NULL, + &pid); + +- strv_free(argv); + if (r < 0) + goto fail; + +- if ((r = unit_watch_pid(UNIT(s), pid)) < 0) ++ r = unit_watch_pid(UNIT(s), pid); ++ if (r < 0) + /* FIXME: we need to do something here */ + goto fail; + +@@ -1234,6 +1251,88 @@ fail: + return r; + } + ++static int socket_chown(Socket *s, pid_t *_pid) { ++ pid_t pid; ++ int r; ++ ++ r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); ++ if (r < 0) ++ goto fail; ++ ++ pid = fork(); ++ if (pid < 0) ++ return -errno; ++ ++ if (pid == 0) { ++ SocketPort *p; ++ uid_t uid = (uid_t) -1; ++ gid_t gid = (gid_t) -1; ++ int ret; ++ ++ default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); ++ ignore_signals(SIGPIPE, -1); ++ log_forget_fds(); ++ ++ if (!isempty(s->user)) { ++ const char *user = s->user; ++ ++ r = get_user_creds(&user, &uid, &gid, NULL, NULL); ++ if (r < 0) { ++ ret = EXIT_USER; ++ goto fail_child; ++ } ++ } ++ ++ if (!isempty(s->group)) { ++ const char *group = s->group; ++ ++ r = get_group_creds(&group, &gid); ++ if (r < 0) { ++ ret = EXIT_GROUP; ++ goto fail_child; ++ } ++ } ++ ++ LIST_FOREACH(port, p, s->ports) { ++ const char *path = NULL; ++ ++ if (p->type == SOCKET_SOCKET) ++ path = socket_address_get_path(&p->address); ++ else if (p->type == SOCKET_FIFO) ++ path = p->path; ++ ++ if (!path) ++ continue; ++ ++ if (chown(path, uid, gid) < 0) { ++ r = -errno; ++ ret = EXIT_CHOWN; ++ goto fail_child; ++ } ++ } ++ ++ _exit(0); ++ ++ fail_child: ++ log_open(); ++ log_error("Failed to chown socket at step %s: %s", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD), strerror(-r)); ++ ++ _exit(ret); ++ } ++ ++ r = unit_watch_pid(UNIT(s), pid); ++ if (r < 0) ++ goto fail; ++ ++ *_pid = pid; ++ ++ return 0; ++ ++fail: ++ unit_unwatch_timer(UNIT(s), &s->timer_watch); ++ return r; ++} ++ + static void socket_enter_dead(Socket *s, SocketResult f) { + assert(s); + +@@ -1256,9 +1355,11 @@ static void socket_enter_stop_post(Socket *s, SocketResult f) { + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_STOP_POST; ++ s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST]; + +- if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) { +- if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) ++ if (s->control_command) { ++ r = socket_spawn(s, s->control_command, &s->control_pid); ++ if (r < 0) + goto fail; + + socket_set_state(s, SOCKET_STOP_POST); +@@ -1326,9 +1427,11 @@ static void socket_enter_stop_pre(Socket *s, SocketResult f) { + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_STOP_PRE; ++ s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE]; + +- if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) { +- if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) ++ if (s->control_command) { ++ r = socket_spawn(s, s->control_command, &s->control_pid); ++ if (r < 0) + goto fail; + + socket_set_state(s, SOCKET_STOP_PRE); +@@ -1376,15 +1479,13 @@ static void socket_enter_start_post(Socket *s) { + } + + socket_unwatch_control_pid(s); +- + s->control_command_id = SOCKET_EXEC_START_POST; ++ s->control_command = s->exec_command[SOCKET_EXEC_START_POST]; + +- if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) { ++ if (s->control_command) { + r = socket_spawn(s, s->control_command, &s->control_pid); + if (r < 0) { +- log_warning_unit(UNIT(s)->id, +- "%s failed to run 'start-post' task: %s", +- UNIT(s)->id, strerror(-r)); ++ log_warning_unit(UNIT(s)->id, "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r)); + goto fail; + } + +@@ -1398,6 +1499,38 @@ fail: + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); + } + ++static void socket_enter_start_chown(Socket *s) { ++ int r; ++ ++ assert(s); ++ ++ r = socket_open_fds(s); ++ if (r < 0) { ++ log_warning_unit(UNIT(s)->id, "%s failed to listen on sockets: %s", UNIT(s)->id, strerror(-r)); ++ goto fail; ++ } ++ ++ if (!isempty(s->user) || !isempty(s->group)) { ++ socket_unwatch_control_pid(s); ++ s->control_command_id = SOCKET_EXEC_START_CHOWN; ++ s->control_command = NULL; ++ ++ r = socket_chown(s, &s->control_pid); ++ if (r < 0) { ++ log_warning_unit(UNIT(s)->id, "%s failed to fork 'start-chown' task: %s", UNIT(s)->id, strerror(-r)); ++ goto fail; ++ } ++ ++ socket_set_state(s, SOCKET_START_CHOWN); ++ } else ++ socket_enter_start_post(s); ++ ++ return; ++ ++fail: ++ socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); ++} ++ + static void socket_enter_start_pre(Socket *s) { + int r; + assert(s); +@@ -1405,21 +1538,21 @@ static void socket_enter_start_pre(Socket *s) { + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_START_PRE; ++ s->control_command = s->exec_command[SOCKET_EXEC_START_PRE]; + +- if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) { +- if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) ++ if (s->control_command) { ++ r = socket_spawn(s, s->control_command, &s->control_pid); ++ if (r < 0) + goto fail; + + socket_set_state(s, SOCKET_START_PRE); + } else +- socket_enter_start_post(s); ++ socket_enter_start_chown(s); + + return; + + fail: +- log_warning_unit(UNIT(s)->id, +- "%s failed to run 'start-pre' task: %s", +- UNIT(s)->id, strerror(-r)); ++ log_warning_unit(UNIT(s)->id, "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r)); + socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); + } + +@@ -1609,6 +1742,7 @@ static int socket_start(Unit *u) { + return -EAGAIN; + + if (s->state == SOCKET_START_PRE || ++ s->state == SOCKET_START_CHOWN || + s->state == SOCKET_START_POST) + return 0; + +@@ -1669,6 +1803,7 @@ static int socket_stop(Unit *u) { + /* If there's already something running we go directly into + * kill mode. */ + if (s->state == SOCKET_START_PRE || ++ s->state == SOCKET_START_CHOWN || + s->state == SOCKET_START_POST) { + socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS); + return -EAGAIN; +@@ -2098,11 +2233,18 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) { + + case SOCKET_START_PRE: + if (f == SOCKET_SUCCESS) +- socket_enter_start_post(s); ++ socket_enter_start_chown(s); + else + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f); + break; + ++ case SOCKET_START_CHOWN: ++ if (f == SOCKET_SUCCESS) ++ socket_enter_start_post(s); ++ else ++ socket_enter_stop_pre(s, f); ++ break; ++ + case SOCKET_START_POST: + if (f == SOCKET_SUCCESS) + socket_enter_listening(s); +@@ -2141,65 +2283,53 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + switch (s->state) { + + case SOCKET_START_PRE: +- log_warning_unit(u->id, +- "%s starting timed out. Terminating.", u->id); ++ log_warning_unit(u->id, "%s starting timed out. Terminating.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + ++ case SOCKET_START_CHOWN: + case SOCKET_START_POST: +- log_warning_unit(u->id, +- "%s starting timed out. Stopping.", u->id); ++ log_warning_unit(u->id, "%s starting timed out. Stopping.", u->id); + socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_PRE: +- log_warning_unit(u->id, +- "%s stopping timed out. Terminating.", u->id); ++ log_warning_unit(u->id, "%s stopping timed out. Terminating.", u->id); + socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_PRE_SIGTERM: + if (s->kill_context.send_sigkill) { +- log_warning_unit(u->id, +- "%s stopping timed out. Killing.", u->id); ++ log_warning_unit(u->id, "%s stopping timed out. Killing.", u->id); + socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT); + } else { +- log_warning_unit(u->id, +- "%s stopping timed out. Skipping SIGKILL. Ignoring.", +- u->id); ++ log_warning_unit(u->id, "%s stopping timed out. Skipping SIGKILL. Ignoring.", u->id); + socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT); + } + break; + + case SOCKET_STOP_PRE_SIGKILL: +- log_warning_unit(u->id, +- "%s still around after SIGKILL. Ignoring.", u->id); ++ log_warning_unit(u->id, "%s still around after SIGKILL. Ignoring.", u->id); + socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_POST: +- log_warning_unit(u->id, +- "%s stopping timed out (2). Terminating.", u->id); ++ log_warning_unit(u->id, "%s stopping timed out (2). Terminating.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_FINAL_SIGTERM: + if (s->kill_context.send_sigkill) { +- log_warning_unit(u->id, +- "%s stopping timed out (2). Killing.", u->id); ++ log_warning_unit(u->id, "%s stopping timed out (2). Killing.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT); + } else { +- log_warning_unit(u->id, +- "%s stopping timed out (2). Skipping SIGKILL. Ignoring.", +- u->id); ++ log_warning_unit(u->id, "%s stopping timed out (2). Skipping SIGKILL. Ignoring.", u->id); + socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT); + } + break; + + case SOCKET_FINAL_SIGKILL: +- log_warning_unit(u->id, +- "%s still around after SIGKILL (2). Entering failed mode.", +- u->id); ++ log_warning_unit(u->id, "%s still around after SIGKILL (2). Entering failed mode.", u->id); + socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT); + break; + +@@ -2333,6 +2463,7 @@ static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) { + static const char* const socket_state_table[_SOCKET_STATE_MAX] = { + [SOCKET_DEAD] = "dead", + [SOCKET_START_PRE] = "start-pre", ++ [SOCKET_START_CHOWN] = "start-chown", + [SOCKET_START_POST] = "start-post", + [SOCKET_LISTENING] = "listening", + [SOCKET_RUNNING] = "running", +@@ -2349,6 +2480,7 @@ DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState); + + static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { + [SOCKET_EXEC_START_PRE] = "StartPre", ++ [SOCKET_EXEC_START_CHOWN] = "StartChown", + [SOCKET_EXEC_START_POST] = "StartPost", + [SOCKET_EXEC_STOP_PRE] = "StopPre", + [SOCKET_EXEC_STOP_POST] = "StopPost" +diff --git a/src/core/socket.h b/src/core/socket.h +index 3d7eadc..6a24883 100644 +--- a/src/core/socket.h ++++ b/src/core/socket.h +@@ -32,6 +32,7 @@ typedef struct Socket Socket; + typedef enum SocketState { + SOCKET_DEAD, + SOCKET_START_PRE, ++ SOCKET_START_CHOWN, + SOCKET_START_POST, + SOCKET_LISTENING, + SOCKET_RUNNING, +@@ -48,6 +49,7 @@ typedef enum SocketState { + + typedef enum SocketExecCommand { + SOCKET_EXEC_START_PRE, ++ SOCKET_EXEC_START_CHOWN, + SOCKET_EXEC_START_POST, + SOCKET_EXEC_STOP_PRE, + SOCKET_EXEC_STOP_POST, +@@ -151,6 +153,9 @@ struct Socket { + char *smack; + char *smack_ip_in; + char *smack_ip_out; ++ ++ char *user; ++ char *group; + }; + + /* Called from the service code when collecting fds */ +diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c +index 45131f2..f15fdba 100644 +--- a/src/shared/exit-status.c ++++ b/src/shared/exit-status.c +@@ -130,6 +130,10 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) { + + case EXIT_SECCOMP: + return "SECCOMP"; ++ ++ case EXIT_CHOWN: ++ return "CHOWN"; ++ + } + } + +diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h +index 1f035a3..52dd3d0 100644 +--- a/src/shared/exit-status.h ++++ b/src/shared/exit-status.h +@@ -67,7 +67,8 @@ typedef enum ExitStatus { + EXIT_NETWORK, + EXIT_NAMESPACE, + EXIT_NO_NEW_PRIVILEGES, +- EXIT_SECCOMP ++ EXIT_SECCOMP, ++ EXIT_CHOWN + } ExitStatus; + + typedef enum ExitStatusLevel { diff --git a/SOURCES/0254-selinux-Check-access-vector-for-enable-and-disable-p.patch b/SOURCES/0254-selinux-Check-access-vector-for-enable-and-disable-p.patch new file mode 100644 index 0000000..05bd7d7 --- /dev/null +++ b/SOURCES/0254-selinux-Check-access-vector-for-enable-and-disable-p.patch @@ -0,0 +1,83 @@ +From 1ea0879cf79412e27b8becdb2bbc7e0abd301a66 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 12 Aug 2014 12:58:47 +0200 +Subject: [PATCH] selinux: Check access vector for enable and disable perm for + each unit file + +--- + src/core/dbus-manager.c | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 6d16c2a..cebc730 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -1581,6 +1581,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetDefaultTarget")) { + + char **l = NULL; ++ char **i; + DBusMessageIter iter; + UnitFileScope scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; + UnitFileChange *changes = NULL; +@@ -1588,8 +1589,6 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, + dbus_bool_t runtime, force; + int carries_install_info = -1; + +- SELINUX_ACCESS_CHECK(connection, message, streq(member, "MaskUnitFiles") ? "disable" : "enable"); +- + if (!dbus_message_iter_init(message, &iter)) + goto oom; + +@@ -1601,6 +1600,17 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, + return bus_send_error_reply(connection, message, NULL, r); + } + ++ STRV_FOREACH(i, l) { ++ Unit *u; ++ ++ r = manager_load_unit(m, *i, NULL, NULL, &u); ++ if (r < 0) { ++ dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", *i); ++ return bus_send_error_reply(connection, message, &error, -ENOENT); ++ } ++ SELINUX_UNIT_ACCESS_CHECK(u, connection, message, streq(member, "MaskUnitFiles") ? "disable" : "enable"); ++ } ++ + if (!dbus_message_iter_next(&iter) || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, true) < 0 || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &force, false) < 0) { +@@ -1644,14 +1654,13 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnmaskUnitFiles")) { + + char **l = NULL; ++ char **i; + DBusMessageIter iter; + UnitFileScope scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + dbus_bool_t runtime; + +- SELINUX_ACCESS_CHECK(connection, message, streq(member, "UnmaskUnitFiles") ? "enable" : "disable"); +- + if (!dbus_message_iter_init(message, &iter)) + goto oom; + +@@ -1669,6 +1678,17 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, + return bus_send_error_reply(connection, message, NULL, -EIO); + } + ++ STRV_FOREACH(i, l) { ++ Unit *u; ++ ++ r = manager_load_unit(m, *i, NULL, NULL, &u); ++ if (r < 0) { ++ dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", *i); ++ return bus_send_error_reply(connection, message, &error, -ENOENT); ++ } ++ SELINUX_UNIT_ACCESS_CHECK(u, connection, message, streq(member, "UnmaskUnitFiles") ? "enable" : "disable"); ++ } ++ + if (streq(member, "DisableUnitFiles")) + r = unit_file_disable(scope, runtime, NULL, l, &changes, &n_changes); + else if (streq(member, "UnmaskUnitFiles")) diff --git a/SOURCES/0255-systemctl-show-StatusErrno-value-in-systemctl-status.patch b/SOURCES/0255-systemctl-show-StatusErrno-value-in-systemctl-status.patch new file mode 100644 index 0000000..527e21e --- /dev/null +++ b/SOURCES/0255-systemctl-show-StatusErrno-value-in-systemctl-status.patch @@ -0,0 +1,45 @@ +From eb075b31eb70910508309c6319d0cc37d454ff59 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 7 Jul 2014 17:33:26 +0200 +Subject: [PATCH] systemctl: show StatusErrno value in "systemctl status" + +(cherry picked from commit b4af5a803aa71a57733ca46fef29b7afb20a626c) + +Conflicts: + src/systemctl/systemctl.c + +Related: #1106457 +--- + src/systemctl/systemctl.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index d29133c..c738daf 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -2480,6 +2480,7 @@ typedef struct UnitStatusInfo { + const char *status_text; + const char *pid_file; + bool running:1; ++ int status_errno; + + usec_t start_timestamp; + usec_t exit_timestamp; +@@ -2751,6 +2752,8 @@ static void print_status_info(UnitStatusInfo *i, + + if (i->status_text) + printf(" Status: \"%s\"\n", i->status_text); ++ if (i->status_errno > 0) ++ printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno)); + + if (i->control_group && + (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) { +@@ -2963,6 +2966,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn + i->exit_code = (int) j; + else if (streq(name, "ExecMainStatus")) + i->exit_status = (int) j; ++ else if (streq(name, "StatusErrno")) ++ i->status_errno = (int) j; + + break; + } diff --git a/SOURCES/0256-service-flush-status-text-and-errno-values-each-time.patch b/SOURCES/0256-service-flush-status-text-and-errno-values-each-time.patch new file mode 100644 index 0000000..28b558a --- /dev/null +++ b/SOURCES/0256-service-flush-status-text-and-errno-values-each-time.patch @@ -0,0 +1,30 @@ +From 5078832417b89cfe92ad87133ecb4179a995db31 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 7 Jul 2014 17:33:46 +0200 +Subject: [PATCH] service: flush status text and errno values each time a + service is started + +We shouldn't show status texts from previous service starts + +(cherry picked from commit 8cfdb077b8e3da1c47fc1d735d051f21f33144c1) + +Related: #1106457 +--- + src/core/service.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/core/service.c b/src/core/service.c +index 814019d..a6d046c 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2579,6 +2579,10 @@ static int service_start(Unit *u) { + s->main_pid_alien = false; + s->forbid_restart = false; + ++ free(s->status_text); ++ s->status_text = NULL; ++ s->status_errno = 0; ++ + service_enter_start_pre(s); + return 0; + } diff --git a/SOURCES/0257-service-don-t-free-status_text-twice.patch b/SOURCES/0257-service-don-t-free-status_text-twice.patch new file mode 100644 index 0000000..fc2db4d --- /dev/null +++ b/SOURCES/0257-service-don-t-free-status_text-twice.patch @@ -0,0 +1,24 @@ +From 3b6a01f5fc0a4770d9c55a1c7fb1addc231f3021 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 18 Aug 2014 16:12:45 +0200 +Subject: [PATCH] service: don't free status_text twice + +Related: #1106457 +--- + src/core/service.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index a6d046c..4366e1b 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -3519,9 +3519,6 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { + + log_debug_unit(u->id, + "%s: got %s", u->id, e); +- +- free(s->status_text); +- s->status_text = t; + } else + t = NULL; + diff --git a/SOURCES/0258-util-add-files_same-helper-function.patch b/SOURCES/0258-util-add-files_same-helper-function.patch new file mode 100644 index 0000000..5f34fda --- /dev/null +++ b/SOURCES/0258-util-add-files_same-helper-function.patch @@ -0,0 +1,71 @@ +From b6fbffe3d4a9435cc8560ee0271c7e6e763e89c1 Mon Sep 17 00:00:00 2001 +From: Harald Hoyer +Date: Thu, 6 Mar 2014 09:12:57 +0100 +Subject: [PATCH] util: add files_same() helper function + +files_same() returns + 1, if the files are the same + 0, if the files have different inode/dev numbers + errno, for any stat error + + (cherry picked from commit 9d9951a460a90ef0e1e0384742cefdcf85193f8c) + + Related: #1111199 +--- + src/shared/util.c | 24 ++++++++++++++++-------- + src/shared/util.h | 2 ++ + 2 files changed, 18 insertions(+), 8 deletions(-) + +diff --git a/src/shared/util.c b/src/shared/util.c +index 2974c2a..fb1e6d1 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -3311,19 +3311,27 @@ bool on_tty(void) { + return cached_on_tty; + } + +-int running_in_chroot(void) { +- struct stat a = {}, b = {}; ++int files_same(const char *filea, const char *fileb) { ++ struct stat a, b; + +- /* Only works as root */ +- if (stat("/proc/1/root", &a) < 0) ++ if (stat(filea, &a) < 0) + return -errno; + +- if (stat("/", &b) < 0) ++ if (stat(fileb, &b) < 0) + return -errno; + +- return +- a.st_dev != b.st_dev || +- a.st_ino != b.st_ino; ++ return a.st_dev == b.st_dev && ++ a.st_ino == b.st_ino; ++} ++ ++int running_in_chroot(void) { ++ int ret; ++ ++ ret = files_same("/proc/1/root", "/"); ++ if (ret < 0) ++ return ret; ++ ++ return ret == 0; + } + + char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { +diff --git a/src/shared/util.h b/src/shared/util.h +index e577ef0..631a385 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -403,6 +403,8 @@ static inline const char *ansi_highlight_off(void) { + return on_tty() ? ANSI_HIGHLIGHT_OFF : ""; + } + ++int files_same(const char *filea, const char *fileb); ++ + int running_in_chroot(void); + + char *ellipsize(const char *s, size_t length, unsigned percent); diff --git a/SOURCES/0259-systemctl-for-switch-root-check-if-we-switch-to-a-sy.patch b/SOURCES/0259-systemctl-for-switch-root-check-if-we-switch-to-a-sy.patch new file mode 100644 index 0000000..e465adb --- /dev/null +++ b/SOURCES/0259-systemctl-for-switch-root-check-if-we-switch-to-a-sy.patch @@ -0,0 +1,109 @@ +From cad8ec5980d63253586d9f884649c45eed0667a1 Mon Sep 17 00:00:00 2001 +From: Harald Hoyer +Date: Thu, 6 Mar 2014 16:35:02 +0100 +Subject: [PATCH] systemctl: for switch-root check, if we switch to a systemd + init + +If "systemctl switch-root" is called with a specific "INIT" or +/proc/cmdline contains "init=", then systemd would not serialize +itsself. + +Let systemctl check, if the new init is in the standard systemd +installation path and if so, clear the INIT parameter, +to let systemd serialize itsself. + +Conflicts: + src/systemctl/systemctl.c + +(cherry picked from commit f39d4a08e746e703d562076a0f622eb91dbdcd3e) + +Related: #1111199 +--- + src/shared/util.h | 13 +++++++++++++ + src/systemctl/systemctl.c | 35 ++++++++++++++++++++++++++--------- + 2 files changed, 39 insertions(+), 9 deletions(-) + +diff --git a/src/shared/util.h b/src/shared/util.h +index 631a385..d11fa07 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -726,6 +726,19 @@ int unlink_noerrno(const char *path); + _c_; \ + }) + ++#define strappenda3(a, b, c) \ ++ ({ \ ++ const char *_a_ = (a), *_b_ = (b), *_c_ = (c); \ ++ char *_d_; \ ++ size_t _x_, _y_, _z_; \ ++ _x_ = strlen(_a_); \ ++ _y_ = strlen(_b_); \ ++ _z_ = strlen(_c_); \ ++ _d_ = alloca(_x_ + _y_ + _z_ + 1); \ ++ strcpy(stpcpy(stpcpy(_d_, _a_), _b_), _c_); \ ++ _d_; \ ++ }) ++ + #define procfs_file_alloca(pid, field) \ + ({ \ + pid_t _pid_ = (pid); \ +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index c738daf..1ca4fd3 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -4143,9 +4143,10 @@ static int show_enviroment(DBusConnection *bus, char **args) { + } + + static int switch_root(DBusConnection *bus, char **args) { ++ _cleanup_free_ char *cmdline_init = NULL; ++ const char *root, *init; + unsigned l; +- const char *root; +- _cleanup_free_ char *init = NULL; ++ int r; + + l = strv_length(args); + if (l < 2 || l > 3) { +@@ -4156,19 +4157,35 @@ static int switch_root(DBusConnection *bus, char **args) { + root = args[1]; + + if (l >= 3) +- init = strdup(args[2]); ++ init = args[2]; + else { +- parse_env_file("/proc/cmdline", WHITESPACE, +- "init", &init, +- NULL); ++ r = parse_env_file("/proc/cmdline", WHITESPACE, ++ "init", &cmdline_init, ++ NULL); ++ if (r < 0) ++ log_debug("Failed to parse /proc/cmdline: %s", strerror(-r)); + +- if (!init) +- init = strdup(""); ++ init = cmdline_init; + } + if (!init) + return log_oom(); + +- log_debug("switching root - root: %s; init: %s", root, init); ++ if (isempty(init)) ++ init = NULL; ++ ++ if (init) { ++ const char *root_systemd_path = NULL, *root_init_path = NULL; ++ ++ root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH); ++ root_init_path = strappenda3(root, "/", init); ++ ++ /* If the passed init is actually the same as the ++ * systemd binary, then let's suppress it. */ ++ if (files_same(root_init_path, root_systemd_path) > 0) ++ init = NULL; ++ } ++ ++ log_debug("Switching root - root: %s; init: %s", root, strna(init)); + + return bus_method_call_with_reply( + bus, diff --git a/SOURCES/0260-shared-include-root-when-canonicalizing-conf-paths.patch b/SOURCES/0260-shared-include-root-when-canonicalizing-conf-paths.patch new file mode 100644 index 0000000..0f85289 --- /dev/null +++ b/SOURCES/0260-shared-include-root-when-canonicalizing-conf-paths.patch @@ -0,0 +1,197 @@ +From b7f7813318b370d9ecf3833f92c5258d362d9441 Mon Sep 17 00:00:00 2001 +From: Michael Marineau +Date: Fri, 31 Jan 2014 15:35:04 -0800 +Subject: [PATCH] shared: include root when canonicalizing conf paths + +The conf_files_list family accepts an alternate root path to prefix all +directories in the list but path_strv_canonicalize_uniq doesn't use it. +This results in the suspicious behavior of resolving directory symlinks +based on the contents of / instead of the alternate root. + +This adds a prefix argument to path_strv_canonicalize which will now +prepend the prefix, if given, to every path in the list. To avoid +answering what a relative path means when called with a root prefix +path_strv_canonicalize is now path_strv_canonicalize_absolute and only +considers absolute paths. Fortunately all users of already call +path_strv_canonicalize with a list of absolute paths. + +(cherry picked from commit 112cfb181453e38d3ef4a74fba23abbb53392002) + +Related: #1111199 +--- + src/shared/conf-files.c | 10 +++------- + src/shared/path-lookup.c | 6 +++--- + src/shared/path-util.c | 29 +++++++++++++++++++---------- + src/shared/path-util.h | 4 ++-- + src/shared/util.c | 2 +- + src/udev/udev-rules.c | 2 +- + 6 files changed, 29 insertions(+), 24 deletions(-) + +diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c +index ed4070c..3d5b1df 100644 +--- a/src/shared/conf-files.c ++++ b/src/shared/conf-files.c +@@ -37,12 +37,8 @@ + #include "hashmap.h" + #include "conf-files.h" + +-static int files_add(Hashmap *h, const char *root, const char *path, const char *suffix) { ++static int files_add(Hashmap *h, const char *dirpath, const char *suffix) { + _cleanup_closedir_ DIR *dir = NULL; +- _cleanup_free_ char *dirpath = NULL; +- +- if (asprintf(&dirpath, "%s%s", root ? root : "", path) < 0) +- return -ENOMEM; + + dir = opendir(dirpath); + if (!dir) { +@@ -104,7 +100,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const + assert(suffix); + + /* This alters the dirs string array */ +- if (!path_strv_canonicalize_uniq(dirs)) ++ if (!path_strv_canonicalize_absolute_uniq(dirs, root)) + return -ENOMEM; + + fh = hashmap_new(string_hash_func, string_compare_func); +@@ -112,7 +108,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const + return -ENOMEM; + + STRV_FOREACH(p, dirs) { +- r = files_add(fh, root, *p, suffix); ++ r = files_add(fh, *p, suffix); + if (r == -ENOMEM) { + hashmap_free_free(fh); + return r; +diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c +index 1a47ea9..03c1380 100644 +--- a/src/shared/path-lookup.c ++++ b/src/shared/path-lookup.c +@@ -316,7 +316,7 @@ int lookup_paths_init( + } + } + +- if (!path_strv_canonicalize(p->unit_path)) ++ if (!path_strv_canonicalize_absolute(p->unit_path, NULL)) + return -ENOMEM; + + strv_uniq(p->unit_path); +@@ -372,10 +372,10 @@ int lookup_paths_init( + return -ENOMEM; + } + +- if (!path_strv_canonicalize(p->sysvinit_path)) ++ if (!path_strv_canonicalize_absolute(p->sysvinit_path, NULL)) + return -ENOMEM; + +- if (!path_strv_canonicalize(p->sysvrcnd_path)) ++ if (!path_strv_canonicalize_absolute(p->sysvrcnd_path, NULL)) + return -ENOMEM; + + strv_uniq(p->sysvinit_path); +diff --git a/src/shared/path-util.c b/src/shared/path-util.c +index 45099ee..de291a5 100644 +--- a/src/shared/path-util.c ++++ b/src/shared/path-util.c +@@ -165,7 +165,7 @@ char **path_strv_make_absolute_cwd(char **l) { + return l; + } + +-char **path_strv_canonicalize(char **l) { ++char **path_strv_canonicalize_absolute(char **l, const char *prefix) { + char **s; + unsigned k = 0; + bool enomem = false; +@@ -180,13 +180,21 @@ char **path_strv_canonicalize(char **l) { + STRV_FOREACH(s, l) { + char *t, *u; + +- t = path_make_absolute_cwd(*s); +- free(*s); +- *s = NULL; +- +- if (!t) { +- enomem = true; ++ if (!path_is_absolute(*s)) + continue; ++ ++ if (prefix) { ++ t = strappend(prefix, *s); ++ free(*s); ++ *s = NULL; ++ ++ if (!t) { ++ enomem = true; ++ continue; ++ } ++ } else { ++ t = *s; ++ *s = NULL; + } + + errno = 0; +@@ -196,7 +204,7 @@ char **path_strv_canonicalize(char **l) { + u = t; + else { + free(t); +- if (errno == ENOMEM || !errno) ++ if (errno == ENOMEM || errno == 0) + enomem = true; + + continue; +@@ -215,11 +223,12 @@ char **path_strv_canonicalize(char **l) { + return l; + } + +-char **path_strv_canonicalize_uniq(char **l) { ++char **path_strv_canonicalize_absolute_uniq(char **l, const char *prefix) { ++ + if (strv_isempty(l)) + return l; + +- if (!path_strv_canonicalize(l)) ++ if (!path_strv_canonicalize_absolute(l, prefix)) + return NULL; + + return strv_uniq(l); +diff --git a/src/shared/path-util.h b/src/shared/path-util.h +index 0a42de7..c69cd1f 100644 +--- a/src/shared/path-util.h ++++ b/src/shared/path-util.h +@@ -43,8 +43,8 @@ char* path_startswith(const char *path, const char *prefix) _pure_; + bool path_equal(const char *a, const char *b) _pure_; + + char** path_strv_make_absolute_cwd(char **l); +-char** path_strv_canonicalize(char **l); +-char** path_strv_canonicalize_uniq(char **l); ++char** path_strv_canonicalize_absolute(char **l, const char *prefix); ++char** path_strv_canonicalize_absolute_uniq(char **l, const char *prefix); + + int path_is_mount_point(const char *path, bool allow_symlink); + int path_is_read_only_fs(const char *path); +diff --git a/src/shared/util.c b/src/shared/util.c +index fb1e6d1..a5163fb 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -5681,7 +5681,7 @@ static int search_and_fopen_internal(const char *path, const char *mode, char ** + assert(mode); + assert(_f); + +- if (!path_strv_canonicalize_uniq(search)) ++ if (!path_strv_canonicalize_absolute_uniq(search, NULL)) + return -ENOMEM; + + STRV_FOREACH(i, search) { +diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c +index 6f8b127..9092b08 100644 +--- a/src/udev/udev-rules.c ++++ b/src/udev/udev-rules.c +@@ -1630,7 +1630,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) + log_error("failed to build config directory array"); + return udev_rules_unref(rules); + } +- if (!path_strv_canonicalize(rules->dirs)) { ++ if (!path_strv_canonicalize_absolute(rules->dirs, NULL)) { + log_error("failed to canonicalize config directories\n"); + return udev_rules_unref(rules); + } diff --git a/SOURCES/0261-shared-add-root-argument-to-search_and_fopen.patch b/SOURCES/0261-shared-add-root-argument-to-search_and_fopen.patch new file mode 100644 index 0000000..a9c965e --- /dev/null +++ b/SOURCES/0261-shared-add-root-argument-to-search_and_fopen.patch @@ -0,0 +1,144 @@ +From 123a76e6190cb2a4669d39e12983f46e27b11163 Mon Sep 17 00:00:00 2001 +From: Michael Marineau +Date: Thu, 13 Mar 2014 21:32:12 -0700 +Subject: [PATCH] shared: add root argument to search_and_fopen + +This adds the same root argument to search_and_fopen that +conf_files_list already has. Tools that use those two functions as a +pair can now be easily modified to load configuration files from an +alternate root filesystem tree. + +Conflicts: + src/shared/util.h + +(cherry picked from commit 4cf7ea556aa1e74f9b34d4467f36d46a1bb25da3) + +Related: #1111199 +--- + src/binfmt/binfmt.c | 2 +- + src/modules-load/modules-load.c | 2 +- + src/shared/util.c | 12 ++++++------ + src/shared/util.h | 4 ++-- + src/sysctl/sysctl.c | 2 +- + src/tmpfiles/tmpfiles.c | 2 +- + 6 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c +index 5a42b3d..3fff89a 100644 +--- a/src/binfmt/binfmt.c ++++ b/src/binfmt/binfmt.c +@@ -85,7 +85,7 @@ static int apply_file(const char *path, bool ignore_enoent) { + + assert(path); + +- r = search_and_fopen_nulstr(path, "re", conf_file_dirs, &f); ++ r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f); + if (r < 0) { + if (ignore_enoent && r == -ENOENT) + return 0; +diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c +index 49ee420..cba7c55 100644 +--- a/src/modules-load/modules-load.c ++++ b/src/modules-load/modules-load.c +@@ -181,7 +181,7 @@ static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent + assert(ctx); + assert(path); + +- r = search_and_fopen_nulstr(path, "re", conf_file_dirs, &f); ++ r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f); + if (r < 0) { + if (ignore_enoent && r == -ENOENT) + return 0; +diff --git a/src/shared/util.c b/src/shared/util.c +index a5163fb..e313ea9 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -5674,14 +5674,14 @@ int on_ac_power(void) { + return found_online || !found_offline; + } + +-static int search_and_fopen_internal(const char *path, const char *mode, char **search, FILE **_f) { ++static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) { + char **i; + + assert(path); + assert(mode); + assert(_f); + +- if (!path_strv_canonicalize_absolute_uniq(search, NULL)) ++ if (!path_strv_canonicalize_absolute_uniq(search, root)) + return -ENOMEM; + + STRV_FOREACH(i, search) { +@@ -5705,7 +5705,7 @@ static int search_and_fopen_internal(const char *path, const char *mode, char ** + return -ENOENT; + } + +-int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f) { ++int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) { + _cleanup_strv_free_ char **copy = NULL; + + assert(path); +@@ -5728,10 +5728,10 @@ int search_and_fopen(const char *path, const char *mode, const char **search, FI + if (!copy) + return -ENOMEM; + +- return search_and_fopen_internal(path, mode, copy, _f); ++ return search_and_fopen_internal(path, mode, root, copy, _f); + } + +-int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f) { ++int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) { + _cleanup_strv_free_ char **s = NULL; + + if (path_is_absolute(path)) { +@@ -5750,7 +5750,7 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *sear + if (!s) + return -ENOMEM; + +- return search_and_fopen_internal(path, mode, s, _f); ++ return search_and_fopen_internal(path, mode, root, s, _f); + } + + int create_tmp_dir(char template[], char** dir_name) { +diff --git a/src/shared/util.h b/src/shared/util.h +index d11fa07..3f30917 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -628,8 +628,8 @@ char *strip_tab_ansi(char **p, size_t *l); + + int on_ac_power(void); + +-int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f); +-int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f); ++int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f); ++int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f); + int create_tmp_dir(char template[], char** dir_name); + + #define FOREACH_LINE(line, f, on_error) \ +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index 878c923..a9d4d53 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -123,7 +123,7 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno + + assert(path); + +- r = search_and_fopen_nulstr(path, "re", conf_file_dirs, &f); ++ r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f); + if (r < 0) { + if (ignore_enoent && r == -ENOENT) + return 0; +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 309fa07..32f9088 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -1368,7 +1368,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) { + + assert(fn); + +- r = search_and_fopen_nulstr(fn, "re", conf_file_dirs, &f); ++ r = search_and_fopen_nulstr(fn, "re", NULL, conf_file_dirs, &f); + if (r < 0) { + if (ignore_enoent && r == -ENOENT) + return 0; diff --git a/SOURCES/0262-machine-id-add-root-option-to-operate-on-an-alternat.patch b/SOURCES/0262-machine-id-add-root-option-to-operate-on-an-alternat.patch new file mode 100644 index 0000000..08ff1fd --- /dev/null +++ b/SOURCES/0262-machine-id-add-root-option-to-operate-on-an-alternat.patch @@ -0,0 +1,264 @@ +From 99c06d718c91c91d0992869777c15b457f95443a Mon Sep 17 00:00:00 2001 +From: Greg KH +Date: Fri, 14 Mar 2014 04:43:04 +0000 +Subject: [PATCH] machine-id: add --root option to operate on an alternate fs + tree + +This makes it possible to initialize the /etc/machine-id file on an +arbitrary filesystem hierarchy. This helps systems that wish to run +this at image creation time in a subdirectory, or from initramfs before +pivot-root is called. + +[tomegun: converted to using _cleanup_free_ macros] + +Conflicts: + man/systemd-machine-id-setup.xml + src/machine-id-setup/machine-id-setup-main.c + +(cherry picked from commit 92f2f92edcad46ce4098ee26504edca0a1dad68e) + +Related: #1111199 +--- + man/systemd-machine-id-setup.xml | 23 +++++++-------- + src/core/machine-id-setup.c | 44 ++++++++++++++++++---------- + src/core/machine-id-setup.h | 2 +- + src/core/main.c | 2 +- + src/machine-id-setup/machine-id-setup-main.c | 17 ++++++++--- + 5 files changed, 53 insertions(+), 35 deletions(-) + +diff --git a/man/systemd-machine-id-setup.xml b/man/systemd-machine-id-setup.xml +index 7b3aa7e..b879b40 100644 +--- a/man/systemd-machine-id-setup.xml ++++ b/man/systemd-machine-id-setup.xml +@@ -21,7 +21,8 @@ + along with systemd; If not, see . + --> + +- ++ + + + systemd-machine-id-setup +@@ -96,19 +97,15 @@ + + + +- +- +- +- Prints a short help +- text and exits. +- +- +- +- +- +- Prints a short version +- string and exits. ++ ++ Takes a directory path ++ as an argument. All paths will be ++ prefixed with the given alternate ROOT ++ path, including config search paths. ++ + ++ ++ + + + +diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c +index 18e015f..291930e 100644 +--- a/src/core/machine-id-setup.c ++++ b/src/core/machine-id-setup.c +@@ -59,18 +59,22 @@ static int shorten_uuid(char destination[36], const char *source) { + return -EINVAL; + } + +-static int generate(char id[34]) { ++static int generate(char id[34], const char *root) { + int fd, r; + unsigned char *p; + sd_id128_t buf; + char *q; + ssize_t k; + const char *vm_id; ++ _cleanup_free_ char *dbus_machine_id = NULL; + + assert(id); + ++ if (asprintf(&dbus_machine_id, "%s/var/lib/dbus/machine-id", root) < 0) ++ return log_oom(); ++ + /* First, try reading the D-Bus machine id, unless it is a symlink */ +- fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); ++ fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); + if (fd >= 0) { + k = loop_read(fd, id, 33, false); + close_nointr_nofail(fd); +@@ -150,12 +154,20 @@ static int generate(char id[34]) { + return 0; + } + +-int machine_id_setup(void) { ++int machine_id_setup(const char *root) { + _cleanup_close_ int fd = -1; + int r; + bool writable; + struct stat st; + char id[34]; /* 32 + \n + \0 */ ++ _cleanup_free_ char *etc_machine_id = NULL; ++ _cleanup_free_ char *run_machine_id = NULL; ++ ++ if (asprintf(&etc_machine_id, "%s/etc/machine-id", root) < 0) ++ return log_oom(); ++ ++ if (asprintf(&run_machine_id, "%s/run/machine-id", root) < 0) ++ return log_oom(); + + RUN_WITH_UMASK(0000) { + /* We create this 0444, to indicate that this isn't really +@@ -163,13 +175,13 @@ int machine_id_setup(void) { + * will be owned by root it doesn't matter much, but maybe + * people look. */ + +- fd = open("/etc/machine-id", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444); ++ fd = open(etc_machine_id, O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444); + if (fd >= 0) + writable = true; + else { +- fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY); ++ fd = open(etc_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { +- log_error("Cannot open /etc/machine-id: %m"); ++ log_error("Cannot open %s: %m", etc_machine_id); + return -errno; + } + +@@ -193,7 +205,7 @@ int machine_id_setup(void) { + /* Hmm, so, the id currently stored is not useful, then let's + * generate one */ + +- r = generate(id); ++ r = generate(id, root); + if (r < 0) + return r; + +@@ -211,27 +223,27 @@ int machine_id_setup(void) { + * /run/machine-id as a replacement */ + + RUN_WITH_UMASK(0022) { +- r = write_string_file("/run/machine-id", id); ++ r = write_string_file(run_machine_id, id); + } + if (r < 0) { +- log_error("Cannot write /run/machine-id: %s", strerror(-r)); +- unlink("/run/machine-id"); ++ log_error("Cannot write %s: %s", run_machine_id, strerror(-r)); ++ unlink(run_machine_id); + return r; + } + + /* And now, let's mount it over */ +- r = mount("/run/machine-id", "/etc/machine-id", NULL, MS_BIND, NULL); ++ r = mount(run_machine_id, etc_machine_id, NULL, MS_BIND, NULL); + if (r < 0) { +- log_error("Failed to mount /etc/machine-id: %m"); +- unlink_noerrno("/run/machine-id"); ++ log_error("Failed to mount %s: %m", etc_machine_id); ++ unlink_noerrno(run_machine_id); + return -errno; + } + +- log_info("Installed transient /etc/machine-id file."); ++ log_info("Installed transient %s file.", etc_machine_id); + + /* Mark the mount read-only */ +- if (mount(NULL, "/etc/machine-id", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL) < 0) +- log_warning("Failed to make transient /etc/machine-id read-only: %m"); ++ if (mount(NULL, etc_machine_id, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL) < 0) ++ log_warning("Failed to make transient %s read-only: %m", etc_machine_id); + + return 0; + } +diff --git a/src/core/machine-id-setup.h b/src/core/machine-id-setup.h +index b9e6b4d..b0583ee 100644 +--- a/src/core/machine-id-setup.h ++++ b/src/core/machine-id-setup.h +@@ -21,4 +21,4 @@ + along with systemd; If not, see . + ***/ + +-int machine_id_setup(void); ++int machine_id_setup(const char *root); +diff --git a/src/core/main.c b/src/core/main.c +index 00fd394..afd5f6f 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1503,7 +1503,7 @@ int main(int argc, char *argv[]) { + kmod_setup(); + #endif + hostname_setup(); +- machine_id_setup(); ++ machine_id_setup(""); + loopback_setup(); + + test_mtab(); +diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c +index eb2d514..f4dc705 100644 +--- a/src/machine-id-setup/machine-id-setup-main.c ++++ b/src/machine-id-setup/machine-id-setup-main.c +@@ -29,12 +29,15 @@ + #include "log.h" + #include "build.h" + ++static const char *arg_root = ""; ++ + static int help(void) { + + printf("%s [OPTIONS...]\n\n" + "Initialize /etc/machine-id from a random source.\n\n" + " -h --help Show this help\n" +- " --version Show package version\n", ++ " --version Show package version\n" ++ " --root Filesystem root\n", + program_invocation_short_name); + + return 0; +@@ -43,13 +46,15 @@ static int help(void) { + static int parse_argv(int argc, char *argv[]) { + + enum { +- ARG_VERSION = 0x100 ++ ARG_VERSION = 0x100, ++ ARG_ROOT, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, +- { NULL, 0, NULL, 0 } ++ { "root", required_argument, NULL, ARG_ROOT }, ++ {} + }; + + int c; +@@ -70,6 +75,10 @@ static int parse_argv(int argc, char *argv[]) { + puts(SYSTEMD_FEATURES); + return 0; + ++ case ARG_ROOT: ++ arg_root = optarg; ++ break; ++ + case '?': + return -EINVAL; + +@@ -97,5 +106,5 @@ int main(int argc, char *argv[]) { + if (r <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + +- return machine_id_setup() < 0 ? EXIT_FAILURE : EXIT_SUCCESS; ++ return machine_id_setup(arg_root) < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } diff --git a/SOURCES/0263-conf-files-fix-when-for-root-logic.patch b/SOURCES/0263-conf-files-fix-when-for-root-logic.patch new file mode 100644 index 0000000..ac43e75 --- /dev/null +++ b/SOURCES/0263-conf-files-fix-when-for-root-logic.patch @@ -0,0 +1,51 @@ +From b5f15b581d886a332de50512c0fe75d1acc0c1ee Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 17 Jun 2014 01:56:44 +0200 +Subject: [PATCH] conf-files: fix when for --root= logic + +This is based on parts of similar patches from Michael Marineau and +Lukas Nykryn, but simply uses strappenda3(). + +(cherry picked from commit cebed5005b5ede17fc52ab50c054fca73bc938b8) + +Related: #1111199 +--- + src/shared/conf-files.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c +index 3d5b1df..4ec8bed 100644 +--- a/src/shared/conf-files.c ++++ b/src/shared/conf-files.c +@@ -37,10 +37,20 @@ + #include "hashmap.h" + #include "conf-files.h" + +-static int files_add(Hashmap *h, const char *dirpath, const char *suffix) { ++static int files_add(Hashmap *h, const char *dirpath, const char *suffix, const char *root) { + _cleanup_closedir_ DIR *dir = NULL; + +- dir = opendir(dirpath); ++ assert(dirpath); ++ assert(suffix); ++ ++ if (isempty(root)) ++ dir = opendir(dirpath); ++ else { ++ const char *p; ++ ++ p = strappenda3(root, "/", dirpath); ++ dir = opendir(p); ++ } + if (!dir) { + if (errno == ENOENT) + return 0; +@@ -108,7 +118,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const + return -ENOMEM; + + STRV_FOREACH(p, dirs) { +- r = files_add(fh, *p, suffix); ++ r = files_add(fh, *p, suffix, root); + if (r == -ENOMEM) { + hashmap_free_free(fh); + return r; diff --git a/SOURCES/0264-Make-systemctl-root-look-for-files-in-the-proper-pla.patch b/SOURCES/0264-Make-systemctl-root-look-for-files-in-the-proper-pla.patch new file mode 100644 index 0000000..1922225 --- /dev/null +++ b/SOURCES/0264-Make-systemctl-root-look-for-files-in-the-proper-pla.patch @@ -0,0 +1,341 @@ +From 022406c6dcaa5e9201a30b95f3e86328739e3892 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 24 Apr 2014 01:44:10 -0400 +Subject: [PATCH] Make systemctl --root look for files in the proper places + +Running systemctl enable/disable/set-default/... with the --root +option under strace reveals that it accessed various files and +directories in the main fs, and not underneath the specified root. +This can lead to correct results only when the layout and +configuration in the container are identical, which often is not the +case. Fix this by adding the specified root to all file access +operations. + +This patch does not handle some corner cases: symlinks which point +outside of the specified root might be interpreted differently than +they would be by the kernel if the specified root was the real root. +But systemctl does not create such symlinks by itself, and I think +this is enough of a corner case not to be worth the additional +complexity of reimplementing link chasing in systemd. + +Also, simplify the code in a few places and remove an hypothetical +memory leak on error. + +Conflicts: + TODO + src/shared/install.c + +(cherry picked from commit 12ed81d9c88406234c20e9261ae8c8b992d8bc4d) + +Related: #1111199 +--- + src/core/manager.c | 2 ++ + src/shared/install.c | 34 +++++++++++++++++++++----------- + src/shared/path-lookup.c | 12 ++++-------- + src/shared/path-lookup.h | 8 +++++++- + src/shared/path-util.c | 49 ++++++++++++++++++++++++++++++++++++----------- + src/systemctl/systemctl.c | 2 +- + 6 files changed, 75 insertions(+), 32 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index 57a88b0..a2810b4 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -891,6 +891,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + + r = lookup_paths_init( + &m->lookup_paths, m->running_as, true, ++ NULL, + m->generator_unit_path, + m->generator_unit_path_early, + m->generator_unit_path_late); +@@ -2383,6 +2384,7 @@ int manager_reload(Manager *m) { + + q = lookup_paths_init( + &m->lookup_paths, m->running_as, true, ++ NULL, + m->generator_unit_path, + m->generator_unit_path_early, + m->generator_unit_path_late); +diff --git a/src/shared/install.c b/src/shared/install.c +index b9c85b7..672dcc2 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -47,7 +47,9 @@ typedef struct { + #define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free) + #define _cleanup_install_context_done_ _cleanup_(install_context_done) + +-static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) { ++static int lookup_paths_init_from_scope(LookupPaths *paths, ++ UnitFileScope scope, ++ const char *root_dir) { + assert(paths); + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); +@@ -57,6 +59,7 @@ static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) + return lookup_paths_init(paths, + scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER, + scope == UNIT_FILE_USER, ++ root_dir, + NULL, NULL, NULL); + } + +@@ -705,7 +708,7 @@ int unit_file_link( + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + +- r = lookup_paths_init_from_scope(&paths, scope); ++ r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; + +@@ -1476,7 +1479,7 @@ int unit_file_enable( + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + +- r = lookup_paths_init_from_scope(&paths, scope); ++ r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; + +@@ -1516,7 +1519,7 @@ int unit_file_disable( + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + +- r = lookup_paths_init_from_scope(&paths, scope); ++ r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; + +@@ -1578,7 +1581,7 @@ int unit_file_set_default( + if (unit_name_to_type(file) != UNIT_TARGET) + return -EINVAL; + +- r = lookup_paths_init_from_scope(&paths, scope); ++ r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; + +@@ -1613,7 +1616,11 @@ int unit_file_get_default( + char **p; + int r; + +- r = lookup_paths_init_from_scope(&paths, scope); ++ assert(scope >= 0); ++ assert(scope < _UNIT_FILE_SCOPE_MAX); ++ assert(name); ++ ++ r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; + +@@ -1665,12 +1672,13 @@ UnitFileState unit_file_get_state( + if (!unit_name_is_valid(name, true)) + return -EINVAL; + +- r = lookup_paths_init_from_scope(&paths, scope); ++ r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; + + STRV_FOREACH(i, paths.unit_path) { + struct stat st; ++ char *partial; + + free(path); + path = NULL; +@@ -1679,10 +1687,14 @@ UnitFileState unit_file_get_state( + asprintf(&path, "%s/%s/%s", root_dir, *i, name); + else + asprintf(&path, "%s/%s", *i, name); +- + if (!path) + return -ENOMEM; + ++ if (root_dir) ++ partial = path + strlen(root_dir) + 1; ++ else ++ partial = path; ++ + /* + * Search for a unit file in our default paths, to + * be sure, that there are no broken symlinks. +@@ -1714,7 +1726,7 @@ UnitFileState unit_file_get_state( + else if (r > 0) + return state; + +- r = unit_file_can_install(&paths, root_dir, path, true); ++ r = unit_file_can_install(&paths, root_dir, partial, true); + if (r < 0 && errno != ENOENT) + return r; + else if (r > 0) +@@ -1822,7 +1834,7 @@ int unit_file_preset( + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + +- r = lookup_paths_init_from_scope(&paths, scope); ++ r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; + +@@ -1891,7 +1903,7 @@ int unit_file_get_list( + if (root_dir && scope != UNIT_FILE_SYSTEM) + return -EINVAL; + +- r = lookup_paths_init_from_scope(&paths, scope); ++ r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; + +diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c +index 03c1380..b62f302 100644 +--- a/src/shared/path-lookup.c ++++ b/src/shared/path-lookup.c +@@ -239,6 +239,7 @@ int lookup_paths_init( + LookupPaths *p, + SystemdRunningAs running_as, + bool personal, ++ const char *root_dir, + const char *generator, + const char *generator_early, + const char *generator_late) { +@@ -316,11 +317,9 @@ int lookup_paths_init( + } + } + +- if (!path_strv_canonicalize_absolute(p->unit_path, NULL)) ++ if (!path_strv_canonicalize_absolute_uniq(p->unit_path, root_dir)) + return -ENOMEM; + +- strv_uniq(p->unit_path); +- + if (!strv_isempty(p->unit_path)) { + _cleanup_free_ char *t = strv_join(p->unit_path, "\n\t"); + if (!t) +@@ -372,15 +371,12 @@ int lookup_paths_init( + return -ENOMEM; + } + +- if (!path_strv_canonicalize_absolute(p->sysvinit_path, NULL)) ++ if (!path_strv_canonicalize_absolute_uniq(p->sysvinit_path, root_dir)) + return -ENOMEM; + +- if (!path_strv_canonicalize_absolute(p->sysvrcnd_path, NULL)) ++ if (!path_strv_canonicalize_absolute_uniq(p->sysvrcnd_path, root_dir)) + return -ENOMEM; + +- strv_uniq(p->sysvinit_path); +- strv_uniq(p->sysvrcnd_path); +- + if (!strv_isempty(p->sysvinit_path)) { + _cleanup_free_ char *t = strv_join(p->sysvinit_path, "\n\t"); + if (!t) +diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h +index 9dee85f..0db9bfb 100644 +--- a/src/shared/path-lookup.h ++++ b/src/shared/path-lookup.h +@@ -41,5 +41,11 @@ SystemdRunningAs systemd_running_as_from_string(const char *s) _pure_; + + int user_config_home(char **config_home); + +-int lookup_paths_init(LookupPaths *p, SystemdRunningAs running_as, bool personal, const char *generator, const char *generator_early, const char *generator_late); ++int lookup_paths_init(LookupPaths *p, ++ SystemdRunningAs running_as, ++ bool personal, ++ const char *root_dir, ++ const char *generator, ++ const char *generator_early, ++ const char *generator_late); + void lookup_paths_free(LookupPaths *p); +diff --git a/src/shared/path-util.c b/src/shared/path-util.c +index de291a5..0aa5d61 100644 +--- a/src/shared/path-util.c ++++ b/src/shared/path-util.c +@@ -179,36 +179,63 @@ char **path_strv_canonicalize_absolute(char **l, const char *prefix) { + + STRV_FOREACH(s, l) { + char *t, *u; ++ _cleanup_free_ char *orig = NULL; + +- if (!path_is_absolute(*s)) ++ if (!path_is_absolute(*s)) { ++ free(*s); + continue; ++ } + + if (prefix) { +- t = strappend(prefix, *s); +- free(*s); +- *s = NULL; +- ++ orig = *s; ++ t = strappend(prefix, orig); + if (!t) { + enomem = true; + continue; + } +- } else { ++ } else + t = *s; +- *s = NULL; +- } + + errno = 0; + u = canonicalize_file_name(t); + if (!u) { +- if (errno == ENOENT) +- u = t; +- else { ++ if (errno == ENOENT) { ++ if (prefix) { ++ u = orig; ++ orig = NULL; ++ free(t); ++ } else ++ u = t; ++ } else { + free(t); + if (errno == ENOMEM || errno == 0) + enomem = true; + + continue; + } ++ } else if (prefix) { ++ char *x; ++ ++ free(t); ++ x = path_startswith(u, prefix); ++ if (x) { ++ /* restore the slash if it was lost */ ++ if (!startswith(x, "/")) ++ *(--x) = '/'; ++ ++ t = strdup(x); ++ free(u); ++ if (!t) { ++ enomem = true; ++ continue; ++ } ++ u = t; ++ } else { ++ /* canonicalized path goes outside of ++ * prefix, keep the original path instead */ ++ u = orig; ++ orig = NULL; ++ } + } else + free(t); + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 1ca4fd3..1cbcd20 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -4258,7 +4258,7 @@ static int enable_sysv_units(const char *verb, char **args) { + /* Processes all SysV units, and reshuffles the array so that + * afterwards only the native units remain */ + +- r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL); ++ r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL); + if (r < 0) + return r; + diff --git a/SOURCES/0265-tmpfiles-fix-memory-leak-of-exclude_prefixes.patch b/SOURCES/0265-tmpfiles-fix-memory-leak-of-exclude_prefixes.patch new file mode 100644 index 0000000..edeb5cf --- /dev/null +++ b/SOURCES/0265-tmpfiles-fix-memory-leak-of-exclude_prefixes.patch @@ -0,0 +1,43 @@ +From 0ec33b41e2fddd714851b444d85c4bd8a4fae879 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 30 Jan 2014 21:40:27 -0500 +Subject: [PATCH] tmpfiles: fix memory leak of exclude_prefixes + +Missed in 5c795114. + +(cherry picked from commit 498f8a39e66a62d015ac78e67e2504658bbba5f2) + +Related: #1111199 +--- + src/tmpfiles/tmpfiles.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 32f9088..1337d02 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -1332,12 +1332,12 @@ static int parse_argv(int argc, char *argv[]) { + break; + + case ARG_PREFIX: +- if (strv_extend(&include_prefixes, optarg) < 0) ++ if (strv_push(&include_prefixes, optarg) < 0) + return log_oom(); + break; + + case ARG_EXCLUDE_PREFIX: +- if (strv_extend(&exclude_prefixes, optarg) < 0) ++ if (strv_push(&exclude_prefixes, optarg) < 0) + return log_oom(); + break; + +@@ -1498,7 +1498,8 @@ finish: + hashmap_free(items); + hashmap_free(globs); + +- strv_free(include_prefixes); ++ free(include_prefixes); ++ free(exclude_prefixes); + + set_free_free(unix_sockets); + diff --git a/SOURCES/0266-tmpfiles-add-root-option-to-operate-on-an-alternate-.patch b/SOURCES/0266-tmpfiles-add-root-option-to-operate-on-an-alternate-.patch new file mode 100644 index 0000000..7210d8b --- /dev/null +++ b/SOURCES/0266-tmpfiles-add-root-option-to-operate-on-an-alternate-.patch @@ -0,0 +1,150 @@ +From 14f32b5e62d7f0973302080488a0f0fce897b2d0 Mon Sep 17 00:00:00 2001 +From: Michael Marineau +Date: Thu, 13 Mar 2014 21:32:13 -0700 +Subject: [PATCH] tmpfiles: add --root option to operate on an alternate fs + tree + +This makes it possible to initialize or cleanup an arbitrary filesystem +hierarchy in the same way that it would be during system boot. + +Conflicts: + src/tmpfiles/tmpfiles.c + +(cherry picked from commit cf9a4abdc24c43565d0890fcb88c00169057c0c4) + +Resolves: #1111199 +--- + man/systemd-tmpfiles.xml | 12 ++++++++++-- + src/tmpfiles/tmpfiles.c | 29 +++++++++++++++++++++++++---- + 2 files changed, 35 insertions(+), 6 deletions(-) + +diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml +index 64f9cf9..8d1db16 100644 +--- a/man/systemd-tmpfiles.xml ++++ b/man/systemd-tmpfiles.xml +@@ -139,19 +139,27 @@ + + + +- ++ + Only apply rules that + apply to paths with the specified + prefix. This option can be specified + multiple times. + + +- ++ + Ignore rules that + apply to paths with the specified + prefix. This option can be specified + multiple times. + ++ ++ ++ Takes a directory path ++ as an argument. All paths will be ++ prefixed with the given alternate root ++ path, including config search paths. ++ ++ + + + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 1337d02..ff51062 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -110,6 +110,7 @@ static bool arg_boot = false; + + static char **include_prefixes = NULL; + static char **exclude_prefixes = NULL; ++static char *arg_root = NULL; + + static const char conf_file_dirs[] = + "/etc/tmpfiles.d\0" +@@ -1186,6 +1187,15 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { + if (!should_include_path(i->path)) + return 0; + ++ if (arg_root) { ++ char *p = strappend(arg_root, i->path); ++ if (!p) ++ return log_oom(); ++ ++ free(i->path); ++ i->path = p; ++ } ++ + if (user && !streq(user, "-")) { + const char *u = user; + +@@ -1274,7 +1284,8 @@ static int help(void) { + " --remove Remove marked files/directories\n" + " --boot Execute actions only safe at boot\n" + " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n" +- " --exclude-prefix=PATH Ignore rules that apply to paths with the specified prefix\n", ++ " --exclude-prefix=PATH Ignore rules that apply to paths with the specified prefix\n" ++ " --root=PATH Operate on an alternate filesystem root\n", + program_invocation_short_name); + + return 0; +@@ -1289,6 +1300,7 @@ static int parse_argv(int argc, char *argv[]) { + ARG_BOOT, + ARG_PREFIX, + ARG_EXCLUDE_PREFIX, ++ ARG_ROOT, + }; + + static const struct option options[] = { +@@ -1299,7 +1311,8 @@ static int parse_argv(int argc, char *argv[]) { + { "boot", no_argument, NULL, ARG_BOOT }, + { "prefix", required_argument, NULL, ARG_PREFIX }, + { "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX }, +- { NULL, 0, NULL, 0 } ++ { "root", required_argument, NULL, ARG_ROOT }, ++ {} + }; + + int c; +@@ -1341,6 +1354,13 @@ static int parse_argv(int argc, char *argv[]) { + return log_oom(); + break; + ++ case ARG_ROOT: ++ arg_root = path_make_absolute_cwd(optarg); ++ if (!arg_root) ++ return log_oom(); ++ path_kill_slashes(arg_root); ++ break; ++ + case '?': + return -EINVAL; + +@@ -1368,7 +1388,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) { + + assert(fn); + +- r = search_and_fopen_nulstr(fn, "re", NULL, conf_file_dirs, &f); ++ r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f); + if (r < 0) { + if (ignore_enoent && r == -ENOENT) + return 0; +@@ -1469,7 +1489,7 @@ int main(int argc, char *argv[]) { + _cleanup_strv_free_ char **files = NULL; + char **f; + +- r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); ++ r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs); + if (r < 0) { + log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r)); + goto finish; +@@ -1500,6 +1520,7 @@ finish: + + free(include_prefixes); + free(exclude_prefixes); ++ free(arg_root); + + set_free_free(unix_sockets); + diff --git a/SOURCES/0267-conf-files-include-root-in-returned-file-paths.patch b/SOURCES/0267-conf-files-include-root-in-returned-file-paths.patch new file mode 100644 index 0000000..21f7c01 --- /dev/null +++ b/SOURCES/0267-conf-files-include-root-in-returned-file-paths.patch @@ -0,0 +1,89 @@ +From c73f2c0db1e35c80ea3cff7b1eb2bece09be4793 Mon Sep 17 00:00:00 2001 +From: Michael Marineau +Date: Thu, 19 Jun 2014 19:07:04 -0700 +Subject: [PATCH] conf-files: include root in returned file paths + +This restores the original root handling logic that was present prior to +112cfb18 when path expansion moved to path_strv_canonicalize_absolute. +That behavior partially went away in 12ed81d9. + +Alternatively all users of conf_files_list* could be updated to +concatenate the paths themselves as unit_file_query_preset did but since +no user needs the un-concatenated form that is pointless duplication. + +Conflicts: + src/shared/install.c + +(cherry picked from commit cba2ef02722114da2b730d57f1e3bb43013d8921) + +Related: #1111199 +--- + src/shared/conf-files.c | 16 ++++++---------- + src/shared/install.c | 6 +++--- + 2 files changed, 9 insertions(+), 13 deletions(-) + +diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c +index 4ec8bed..fc5f1fe 100644 +--- a/src/shared/conf-files.c ++++ b/src/shared/conf-files.c +@@ -37,20 +37,16 @@ + #include "hashmap.h" + #include "conf-files.h" + +-static int files_add(Hashmap *h, const char *dirpath, const char *suffix, const char *root) { ++static int files_add(Hashmap *h, const char *root, const char *path, const char *suffix) { + _cleanup_closedir_ DIR *dir = NULL; ++ char *dirpath; + +- assert(dirpath); ++ assert(path); + assert(suffix); + +- if (isempty(root)) +- dir = opendir(dirpath); +- else { +- const char *p; ++ dirpath = strappenda(root ? root : "", path); + +- p = strappenda3(root, "/", dirpath); +- dir = opendir(p); +- } ++ dir = opendir(dirpath); + if (!dir) { + if (errno == ENOENT) + return 0; +@@ -118,7 +114,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const + return -ENOMEM; + + STRV_FOREACH(p, dirs) { +- r = files_add(fh, *p, suffix, root); ++ r = files_add(fh, root, *p, suffix); + if (r == -ENOMEM) { + hashmap_free_free(fh); + return r; +diff --git a/src/shared/install.c b/src/shared/install.c +index 672dcc2..871de78 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1740,7 +1740,7 @@ UnitFileState unit_file_get_state( + + int unit_file_query_preset(UnitFileScope scope, const char *name) { + _cleanup_strv_free_ char **files = NULL; +- char **i; ++ char **p; + int r; + + assert(scope >= 0); +@@ -1768,10 +1768,10 @@ int unit_file_query_preset(UnitFileScope scope, const char *name) { + if (r < 0) + return r; + +- STRV_FOREACH(i, files) { ++ STRV_FOREACH(p, files) { + _cleanup_fclose_ FILE *f; + +- f = fopen(*i, "re"); ++ f = fopen(*p, "re"); + if (!f) { + if (errno == ENOENT) + continue; diff --git a/SOURCES/0268-install-make-sure-that-root-mode-doesn-t-make-us-con.patch b/SOURCES/0268-install-make-sure-that-root-mode-doesn-t-make-us-con.patch new file mode 100644 index 0000000..82a76c2 --- /dev/null +++ b/SOURCES/0268-install-make-sure-that-root-mode-doesn-t-make-us-con.patch @@ -0,0 +1,148 @@ +From 8d32393e5a3fbc12371edf69830d0258a097211f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 17 Jun 2014 00:53:49 +0200 +Subject: [PATCH] install: make sure that --root= mode doesn't make us consider + all units outside of search path + +(cherry picked from commit 8f294b45cbb627d31342f6a79444be59ce7e2274) + +Related: #1111199 +--- + src/shared/install.c | 41 +++++++++++++++++++++++++++++++++++++---- + src/shared/util.c | 16 ---------------- + src/shared/util.h | 1 - + 3 files changed, 37 insertions(+), 21 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 871de78..7dad66d 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -47,6 +47,37 @@ typedef struct { + #define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free) + #define _cleanup_install_context_done_ _cleanup_(install_context_done) + ++static int in_search_path(const char *path, char **search, const char *root_dir) { ++ _cleanup_free_ char *parent = NULL; ++ char **i; ++ int r; ++ ++ assert(path); ++ ++ r = path_get_parent(path, &parent); ++ if (r < 0) ++ return r; ++ ++ STRV_FOREACH(i, search) { ++ _cleanup_free_ char *buf = NULL; ++ const char *p; ++ ++ if (root_dir) { ++ buf = strjoin(root_dir, "/", *i, NULL); ++ if (!buf) ++ return -ENOMEM; ++ ++ p = buf; ++ } else ++ p = *i; ++ ++ if (path_equal(parent, p)) ++ return 1; ++ } ++ ++ return 0; ++} ++ + static int lookup_paths_init_from_scope(LookupPaths *paths, + UnitFileScope scope, + const char *root_dir) { +@@ -741,7 +772,7 @@ int unit_file_link( + continue; + } + +- q = in_search_path(*i, paths.unit_path); ++ q = in_search_path(*i, paths.unit_path, root_dir); + if (q < 0) + return q; + +@@ -1296,6 +1327,7 @@ static int install_info_symlink_link( + InstallInfo *i, + LookupPaths *paths, + const char *config_path, ++ const char *root_dir, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { +@@ -1308,7 +1340,7 @@ static int install_info_symlink_link( + assert(config_path); + assert(i->path); + +- r = in_search_path(i->path, paths->unit_path); ++ r = in_search_path(i->path, paths->unit_path, root_dir); + if (r != 0) + return r; + +@@ -1323,6 +1355,7 @@ static int install_info_apply( + InstallInfo *i, + LookupPaths *paths, + const char *config_path, ++ const char *root_dir, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { +@@ -1343,7 +1376,7 @@ static int install_info_apply( + if (r == 0) + r = q; + +- q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes); ++ q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes); + if (r == 0) + r = q; + +@@ -1383,7 +1416,7 @@ static int install_context_apply( + } else if (r >= 0) + r += q; + +- q = install_info_apply(i, paths, config_path, force, changes, n_changes); ++ q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes); + if (r >= 0 && q < 0) + r = q; + } +diff --git a/src/shared/util.c b/src/shared/util.c +index e313ea9..fc1f765 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -4490,22 +4490,6 @@ int dirent_ensure_type(DIR *d, struct dirent *de) { + return 0; + } + +-int in_search_path(const char *path, char **search) { +- char **i; +- _cleanup_free_ char *parent = NULL; +- int r; +- +- r = path_get_parent(path, &parent); +- if (r < 0) +- return r; +- +- STRV_FOREACH(i, search) +- if (path_equal(parent, *i)) +- return 1; +- +- return 0; +-} +- + int get_files_in_directory(const char *path, char ***list) { + _cleanup_closedir_ DIR *d = NULL; + size_t bufsize = 0, n = 0; +diff --git a/src/shared/util.h b/src/shared/util.h +index 3f30917..ec18d2c 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -475,7 +475,6 @@ int glob_extend(char ***strv, const char *path); + + int dirent_ensure_type(DIR *d, struct dirent *de); + +-int in_search_path(const char *path, char **search); + int get_files_in_directory(const char *path, char ***list); + + char *strjoin(const char *x, ...) _sentinel_; diff --git a/SOURCES/0269-shared-install-do-not-prefix-created-symlink-with-ro.patch b/SOURCES/0269-shared-install-do-not-prefix-created-symlink-with-ro.patch new file mode 100644 index 0000000..8060501 --- /dev/null +++ b/SOURCES/0269-shared-install-do-not-prefix-created-symlink-with-ro.patch @@ -0,0 +1,130 @@ +From 6dadf44d7062c38c3f4f782da3cd88114dceb959 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 21 Apr 2014 19:17:40 -0400 +Subject: [PATCH] shared/install: do not prefix created symlink with root path + +Before: /var/tmp/inst1//etc/systemd/system/default.target -> /var/tmp/inst1//usr/lib/systemd/system/graphical.target +After: /var/tmp/inst1/etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.target + +(cherry picked from commit 62b002337727093c21d020c730bd65971f7783a7) + +Related: #1111199 +--- + src/shared/install.c | 89 +++++++++++++++++++++++++--------------------------- + 1 file changed, 43 insertions(+), 46 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 7dad66d..955a9bc 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1073,67 +1073,64 @@ static int unit_file_search( + assert(info); + assert(paths); + +- if (info->path) +- return unit_file_load(c, info, info->path, allow_symlink); ++ if (info->path) { ++ char *full_path = NULL; ++ ++ if (!isempty(root_dir)) ++ full_path = strappenda(root_dir, info->path); ++ ++ return unit_file_load(c, info, full_path ?: info->path, allow_symlink); ++ } + + assert(info->name); + + STRV_FOREACH(p, paths->unit_path) { +- char *path = NULL; +- +- if (isempty(root_dir)) +- asprintf(&path, "%s/%s", *p, info->name); +- else +- asprintf(&path, "%s/%s/%s", root_dir, *p, info->name); ++ _cleanup_free_ char *path = NULL, *full_path = NULL; + ++ path = strjoin(*p, "/", info->name, NULL); + if (!path) + return -ENOMEM; + +- r = unit_file_load(c, info, path, allow_symlink); ++ if (!isempty(root_dir)) { ++ full_path = strappend(root_dir, path); ++ if (!full_path) ++ return -ENOMEM; ++ } + +- if (r >= 0) ++ r = unit_file_load(c, info, full_path ?: path, allow_symlink); ++ if (r >= 0) { + info->path = path; +- else { +- if (r == -ENOENT && unit_name_is_instance(info->name)) { +- /* Unit file doesn't exist, however instance enablement was requested. +- * We will check if it is possible to load template unit file. */ +- char *template = NULL, +- *template_path = NULL, +- *template_dir = NULL; +- +- template = unit_name_template(info->name); +- if (!template) { +- free(path); +- return -ENOMEM; +- } ++ path = NULL; ++ } else if (r == -ENOENT && unit_name_is_instance(info->name)) { ++ /* Unit file doesn't exist, however instance enablement was requested. ++ * We will check if it is possible to load template unit file. */ ++ _cleanup_free_ char *template = NULL, *template_dir = NULL; ++ ++ template = unit_name_template(info->name); ++ if (!template) ++ return -ENOMEM; + +- /* We will reuse path variable since we don't need it anymore. */ +- template_dir = path; +- *(strrchr(path, '/') + 1) = '\0'; ++ /* We will reuse path variable since we don't need it anymore. */ ++ template_dir = path; ++ *(strrchr(template_dir, '/') + 1) = '\0'; + +- template_path = strjoin(template_dir, template, NULL); +- if (!template_path) { +- free(path); +- free(template); +- return -ENOMEM; +- } ++ path = strappend(template_dir, template); ++ if (!path) ++ return -ENOMEM; + +- /* Let's try to load template unit. */ +- r = unit_file_load(c, info, template_path, allow_symlink); +- if (r >= 0) { +- info->path = strdup(template_path); +- if (!info->path) { +- free(path); +- free(template); +- free(template_path); +- return -ENOMEM; +- } +- } ++ if (!isempty(root_dir)) { ++ free(full_path); ++ full_path = strappend(root_dir, path); ++ if (!full_path) ++ return -ENOMEM; ++ } + +- free(template); +- free(template_path); ++ /* Let's try to load template unit. */ ++ r = unit_file_load(c, info, full_path ?: path, allow_symlink); ++ if (r >= 0) { ++ info->path = path; ++ path = NULL; + } +- free(path); + } + + if (r != -ENOENT && r != -ELOOP) diff --git a/SOURCES/0270-systemctl-fail-in-the-case-that-no-unit-files-were-f.patch b/SOURCES/0270-systemctl-fail-in-the-case-that-no-unit-files-were-f.patch new file mode 100644 index 0000000..392e694 --- /dev/null +++ b/SOURCES/0270-systemctl-fail-in-the-case-that-no-unit-files-were-f.patch @@ -0,0 +1,56 @@ +From 9e42758bf5dcaff2120856556ef1c3cafff7d581 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 19 Aug 2014 20:53:29 +0200 +Subject: [PATCH] systemctl: fail in the case that no unit files were found + +Previously systemctl died with message + +-bash-4.2# systemctl --root /rawhi list-unit-files +(src/systemctl/systemctl.c:868) Out of memory. + +in the case that no unit files were found in the --root +or the directory did not exist. + +So lets return ENOENT in the case that --root does not exist +and empty list in the case that there are no unit files. + +(cherry picked from commit fdbdf6ec29bda40763d7d3e7bb2a63e2f5d60c4c) + +Related: #1111199 +--- + src/shared/install.c | 6 ++++++ + src/systemctl/systemctl.c | 4 ++++ + 2 files changed, 10 insertions(+) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 955a9bc..598323a 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1933,6 +1933,12 @@ int unit_file_get_list( + if (root_dir && scope != UNIT_FILE_SYSTEM) + return -EINVAL; + ++ if (root_dir) { ++ r = access(root_dir, F_OK); ++ if (r < 0) ++ return -errno; ++ } ++ + r = lookup_paths_init_from_scope(&paths, scope, root_dir); + if (r < 0) + return r; +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 1cbcd20..90a80bd 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -862,6 +862,10 @@ static int list_unit_files(DBusConnection *bus, char **args) { + } + + n_units = hashmap_size(h); ++ ++ if (n_units == 0) ++ return 0; ++ + units = new(UnitFileList, n_units); + if (!units) { + unit_file_list_free(h); diff --git a/SOURCES/0271-units-make-ExecStopPost-action-part-of-ExecStart.patch b/SOURCES/0271-units-make-ExecStopPost-action-part-of-ExecStart.patch new file mode 100644 index 0000000..f2dd649 --- /dev/null +++ b/SOURCES/0271-units-make-ExecStopPost-action-part-of-ExecStart.patch @@ -0,0 +1,54 @@ +From 9af28110933ae9cdd96477dd2911c19295bc74ce Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 8 Jul 2014 17:42:23 +0200 +Subject: [PATCH] units: make ExecStopPost action part of ExecStart + +Currently after exiting rescue shell we isolate default target. User +might want to isolate to some other target than default one. However +issuing systemctl isolate command to desired target would bring system +to default target as a consequence of running ExecStopPost action. + +Having common ancestor for rescue shell and possible followup systemctl +default command should fix this. If user exits rescue shell we will +proceed with isolating default target, otherwise, on manual isolate, +parent shell process is terminated and we don't isolate default target, +but target chosen by user. + +Suggested-by: Michal Schmidt + +(cherry picked from commit d3381512282f2ca1c7669f77fb736a90fdce6982) + +Resolves: #1036276 +--- + units/emergency.service.in | 3 +-- + units/rescue.service.m4.in | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/units/emergency.service.in b/units/emergency.service.in +index 94c090f..91fc1bb 100644 +--- a/units/emergency.service.in ++++ b/units/emergency.service.in +@@ -17,8 +17,7 @@ Environment=HOME=/root + WorkingDirectory=/root + ExecStartPre=-/bin/plymouth quit + ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" to try again\\nto boot into default mode.' +-ExecStart=-/sbin/sulogin +-ExecStopPost=@SYSTEMCTL@ --fail --no-block default ++ExecStart=-/bin/sh -c "/sbin/sulogin; @SYSTEMCTL@ --fail --no-block default" + Type=idle + StandardInput=tty-force + StandardOutput=inherit +diff --git a/units/rescue.service.m4.in b/units/rescue.service.m4.in +index 552ef89..ef54369 100644 +--- a/units/rescue.service.m4.in ++++ b/units/rescue.service.m4.in +@@ -18,8 +18,7 @@ Environment=HOME=/root + WorkingDirectory=/root + ExecStartPre=-/bin/plymouth quit + ExecStartPre=-/bin/echo -e 'Welcome to rescue mode! Type "systemctl default" or ^D to enter default mode.\\nType "journalctl -xb" to view system logs. Type "systemctl reboot" to reboot.' +-ExecStart=-/sbin/sulogin +-ExecStopPost=-@SYSTEMCTL@ --fail --no-block default ++ExecStart=-/bin/sh -c "/sbin/sulogin; @SYSTEMCTL@ --fail --no-block default" + Type=idle + StandardInput=tty-force + StandardOutput=inherit diff --git a/SOURCES/0272-systemctl-fix-broken-list-unit-files-with-root.patch b/SOURCES/0272-systemctl-fix-broken-list-unit-files-with-root.patch new file mode 100644 index 0000000..6c211b2 --- /dev/null +++ b/SOURCES/0272-systemctl-fix-broken-list-unit-files-with-root.patch @@ -0,0 +1,40 @@ +From 736a7f8c5d6c711ece23b0f347d3b89ac7464b08 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 26 Aug 2014 13:33:08 +0200 +Subject: [PATCH] systemctl: fix broken list-unit-files with --root + +(cherry picked from commit 81fc054dc7c365545bca86d78bf36a12658cedb3) + +Related: #1111199 + +Conflicts: + src/shared/install.c +--- + src/shared/install.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 598323a..2c8f907 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1973,6 +1973,7 @@ int unit_file_get_list( + union dirent_storage buffer; + UnitFileList __attribute__((cleanup(unitfilelist_free))) + *f = NULL; ++ _cleanup_free_ char *path = NULL; + + r = readdir_r(d, &buffer.de, &de); + if (r != 0) +@@ -2027,7 +2028,11 @@ int unit_file_get_list( + goto found; + } + +- r = unit_file_can_install(&paths, root_dir, f->path, true); ++ path = path_make_absolute(de->d_name, *i); ++ if (!path) ++ return -ENOMEM; ++ ++ r = unit_file_can_install(&paths, root_dir, path, true); + if (r == -EINVAL || /* Invalid setting? */ + r == -EBADMSG || /* Invalid format? */ + r == -ENOENT /* Included file not found? */) diff --git a/SOURCES/0273-machine-id-only-look-into-KVM-uuid-when-we-are-not-r.patch b/SOURCES/0273-machine-id-only-look-into-KVM-uuid-when-we-are-not-r.patch new file mode 100644 index 0000000..f84f577 --- /dev/null +++ b/SOURCES/0273-machine-id-only-look-into-KVM-uuid-when-we-are-not-r.patch @@ -0,0 +1,87 @@ +From a777218d241e52279039da5a2ba9b5a69576583c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 28 Apr 2014 18:11:40 +0200 +Subject: [PATCH] machine-id: only look into KVM uuid when we are not running + in a container + +Resolves: #1123452 + +(cherry picked from commit 0b36bbc42d3a408531517a02acaf56105b863d55) + +Conflicts: + src/core/machine-id-setup.c +--- + src/core/machine-id-setup.c | 53 +++++++++++++++++++++++---------------------- + 1 file changed, 27 insertions(+), 26 deletions(-) + +diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c +index 291930e..8cfcf51 100644 +--- a/src/core/machine-id-setup.c ++++ b/src/core/machine-id-setup.c +@@ -92,32 +92,9 @@ static int generate(char id[34], const char *root) { + } + } + +- /* If that didn't work, see if we are running in qemu/kvm and a +- * machine ID was passed in via -uuid on the qemu/kvm command +- * line */ +- +- r = detect_vm(&vm_id); +- if (r > 0 && streq(vm_id, "kvm")) { +- char uuid[37]; +- +- fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); +- if (fd >= 0) { +- k = loop_read(fd, uuid, 36, false); +- close_nointr_nofail(fd); +- +- if (k >= 36) { +- r = shorten_uuid(id, uuid); +- if (r >= 0) { +- log_info("Initializing machine ID from KVM UUID."); +- return 0; +- } +- } +- } +- } +- +- /* If that didn't work either, see if we are running in a +- * container, and a machine ID was passed in via +- * $container_uuid the way libvirt/LXC does it */ ++ /* If that didn't work, see if we are running in a container, ++ * and a machine ID was passed in via $container_uuid the way ++ * libvirt/LXC does it */ + r = detect_container(NULL); + if (r > 0) { + _cleanup_free_ char *e = NULL; +@@ -132,6 +109,30 @@ static int generate(char id[34], const char *root) { + } + } + } ++ ++ } else { ++ /* If we are not running in a container, see if we are ++ * running in qemu/kvm and a machine ID was passed in ++ * via -uuid on the qemu/kvm command line */ ++ ++ r = detect_vm(&vm_id); ++ if (r > 0 && streq(vm_id, "kvm")) { ++ char uuid[37]; ++ ++ fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); ++ if (fd >= 0) { ++ k = loop_read(fd, uuid, 36, false); ++ close_nointr_nofail(fd); ++ ++ if (k >= 36) { ++ r = shorten_uuid(id, uuid); ++ if (r >= 0) { ++ log_info("Initializing machine ID from KVM UUID."); ++ return 0; ++ } ++ } ++ } ++ } + } + + /* If that didn't work, generate a random machine id */ diff --git a/SOURCES/0274-util-reset-signals-when-we-fork-off-agents.patch b/SOURCES/0274-util-reset-signals-when-we-fork-off-agents.patch new file mode 100644 index 0000000..a55fd51 --- /dev/null +++ b/SOURCES/0274-util-reset-signals-when-we-fork-off-agents.patch @@ -0,0 +1,70 @@ +From 72be8870f1ab5d8753d966ee6c81f88734053a95 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 26 Aug 2014 21:04:21 +0200 +Subject: [PATCH] util: reset signals when we fork off agents + +If we invoke agents, we should make sure we actually can kill them +again. I mean, it's probably not our job to cleanup the signals if our +tools are invoked in weird contexts, but at least we should make sure, +that the subprocesses we invoke and intend to control work as intended. + +Also see: + +http://lists.freedesktop.org/archives/systemd-devel/2014-August/022460.html + +(cherry picked from commit 8a7c93d858c342744adf481565d8bb03b9713dcf) + +Resolves: #1134818 +--- + src/shared/util.c | 18 ++++++++++++++++++ + src/shared/util.h | 1 + + 2 files changed, 19 insertions(+) + +diff --git a/src/shared/util.c b/src/shared/util.c +index fc1f765..e4448ff 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -935,6 +935,18 @@ int reset_all_signal_handlers(void) { + return 0; + } + ++int reset_signal_mask(void) { ++ sigset_t ss; ++ ++ if (sigemptyset(&ss) < 0) ++ return -errno; ++ ++ if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) ++ return -errno; ++ ++ return 0; ++} ++ + char *strstrip(char *s) { + char *e; + +@@ -5028,6 +5040,12 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa + /* Don't leak fds to the agent */ + close_all_fds(except, n_except); + ++ /* Make sure we actually can kill the agent, if we need to, in ++ * case somebody invoked us from a shell script that trapped ++ * SIGTERM or so... */ ++ reset_all_signal_handlers(); ++ reset_signal_mask(); ++ + stdout_is_tty = isatty(STDOUT_FILENO); + stderr_is_tty = isatty(STDERR_FILENO); + +diff --git a/src/shared/util.h b/src/shared/util.h +index ec18d2c..5a9bc99 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -207,6 +207,7 @@ int readlink_and_make_absolute(const char *p, char **r); + int readlink_and_canonicalize(const char *p, char **r); + + int reset_all_signal_handlers(void); ++int reset_signal_mask(void); + + char *strstrip(char *s); + char *delete_chars(char *s, const char *bad); diff --git a/SOURCES/0275-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch b/SOURCES/0275-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch new file mode 100644 index 0000000..5cdd581 --- /dev/null +++ b/SOURCES/0275-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch @@ -0,0 +1,95 @@ +From f0fdbdb003cb3e8d8188c1c01701b510505b5b8b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 Aug 2014 21:42:20 +0200 +Subject: [PATCH] util: fix minimal race where we might miss SIGTERMs when + forking off an agent + +Before forking, block all signals, and unblock them afterwards. This way +the child will have them blocked, and we won't lose them. + +(cherry picked from commit 8a7c93d858c342744adf481565d8bb03b9713dcf) + +Related: #1134818 +--- + src/shared/util.c | 35 +++++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 12 deletions(-) + +diff --git a/src/shared/util.c b/src/shared/util.c +index e4448ff..9f25b15 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -5002,9 +5002,9 @@ int fd_inc_rcvbuf(int fd, size_t n) { + } + + int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) { +- pid_t parent_pid, agent_pid; +- int fd; + bool stdout_is_tty, stderr_is_tty; ++ pid_t parent_pid, agent_pid; ++ sigset_t ss, saved_ss; + unsigned n, i; + va_list ap; + char **l; +@@ -5012,16 +5012,25 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa + assert(pid); + assert(path); + +- parent_pid = getpid(); +- + /* Spawns a temporary TTY agent, making sure it goes away when + * we go away */ + ++ parent_pid = getpid(); ++ ++ /* First we temporarily block all signals, so that the new ++ * child has them blocked initially. This way, we can be sure ++ * that SIGTERMs are not lost we might send to the agent. */ ++ assert_se(sigfillset(&ss) >= 0); ++ assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0); ++ + agent_pid = fork(); +- if (agent_pid < 0) ++ if (agent_pid < 0) { ++ assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0); + return -errno; ++ } + + if (agent_pid != 0) { ++ assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0); + *pid = agent_pid; + return 0; + } +@@ -5032,24 +5041,26 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + _exit(EXIT_FAILURE); + ++ /* Make sure we actually can kill the agent, if we need to, in ++ * case somebody invoked us from a shell script that trapped ++ * SIGTERM or so... */ ++ reset_all_signal_handlers(); ++ reset_signal_mask(); ++ + /* Check whether our parent died before we were able +- * to set the death signal */ ++ * to set the death signal and unblock the signals */ + if (getppid() != parent_pid) + _exit(EXIT_SUCCESS); + + /* Don't leak fds to the agent */ + close_all_fds(except, n_except); + +- /* Make sure we actually can kill the agent, if we need to, in +- * case somebody invoked us from a shell script that trapped +- * SIGTERM or so... */ +- reset_all_signal_handlers(); +- reset_signal_mask(); +- + stdout_is_tty = isatty(STDOUT_FILENO); + stderr_is_tty = isatty(STDERR_FILENO); + + if (!stdout_is_tty || !stderr_is_tty) { ++ int fd; ++ + /* Detach from stdout/stderr. and reopen + * /dev/tty for them. This is important to + * ensure that when systemctl is started via diff --git a/SOURCES/0276-udev-do-not-skip-the-execution-of-RUN-when-renaming-.patch b/SOURCES/0276-udev-do-not-skip-the-execution-of-RUN-when-renaming-.patch new file mode 100644 index 0000000..89c26df --- /dev/null +++ b/SOURCES/0276-udev-do-not-skip-the-execution-of-RUN-when-renaming-.patch @@ -0,0 +1,163 @@ +From 426a65ac5d56264b1890539eff96a1fa1d460217 Mon Sep 17 00:00:00 2001 +From: Kay Sievers +Date: Wed, 14 May 2014 00:34:49 +0200 +Subject: [PATCH] udev: do not skip the execution of RUN when renaming a + network device fails + +(cherry picked from commit 1ea972174baba40dbc80c51cbfc4edc49764b59b) + +Resolves: #1102135 +--- + src/test/test-udev.c | 5 ++--- + src/udev/udev-event.c | 9 ++++----- + src/udev/udev.h | 2 +- + src/udev/udevadm-test.c | 13 +++++-------- + src/udev/udevd.c | 13 ++++++------- + 5 files changed, 18 insertions(+), 24 deletions(-) + +diff --git a/src/test/test-udev.c b/src/test/test-udev.c +index 17825f1..3fcf728 100644 +--- a/src/test/test-udev.c ++++ b/src/test/test-udev.c +@@ -156,9 +156,8 @@ int main(int argc, char *argv[]) + } + } + +- err = udev_event_execute_rules(event, rules, &sigmask_orig); +- if (err == 0) +- udev_event_execute_run(event, NULL); ++ udev_event_execute_rules(event, rules, &sigmask_orig); ++ udev_event_execute_run(event, NULL); + out: + if (event != NULL && event->fd_signal >= 0) + close(event->fd_signal); +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index 3db2cb7..d69d7ba 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -776,13 +776,12 @@ static int rename_netif(struct udev_event *event) + return err; + } + +-int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask) ++void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask) + { + struct udev_device *dev = event->dev; +- int err = 0; + + if (udev_device_get_subsystem(dev) == NULL) +- return -1; ++ return; + + if (streq(udev_device_get_action(dev), "remove")) { + udev_device_read_db(dev, NULL); +@@ -816,9 +815,10 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, + event->name != NULL && !streq(event->name, udev_device_get_sysname(dev))) { + char syspath[UTIL_PATH_SIZE]; + char *pos; ++ int err; + + err = rename_netif(event); +- if (err == 0) { ++ if (err >= 0) { + log_debug("renamed netif to '%s'\n", event->name); + + /* remember old name */ +@@ -881,7 +881,6 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, + udev_device_unref(event->dev_db); + event->dev_db = NULL; + } +- return err; + } + + void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask) +diff --git a/src/udev/udev.h b/src/udev/udev.h +index 8395926..900b1d6 100644 +--- a/src/udev/udev.h ++++ b/src/udev/udev.h +@@ -83,7 +83,7 @@ int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string, + int udev_event_spawn(struct udev_event *event, + const char *cmd, char **envp, const sigset_t *sigmask, + char *result, size_t ressize); +-int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset); ++void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset); + void udev_event_execute_run(struct udev_event *event, const sigset_t *sigset); + int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]); + +diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c +index df1409b..dc292c2 100644 +--- a/src/udev/udevadm-test.c ++++ b/src/udev/udevadm-test.c +@@ -42,7 +42,6 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) + struct udev_rules *rules = NULL; + struct udev_list_entry *entry; + sigset_t mask, sigmask_orig; +- int err; + int rc = 0; + + static const struct option options[] = { +@@ -141,18 +140,16 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) + goto out; + } + +- err = udev_event_execute_rules(event, rules, &sigmask_orig); ++ udev_event_execute_rules(event, rules, &sigmask_orig); + + udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) + printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry)); + +- if (err == 0) { +- udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) { +- char program[UTIL_PATH_SIZE]; ++ udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) { ++ char program[UTIL_PATH_SIZE]; + +- udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program)); +- printf("run: '%s'\n", program); +- } ++ udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program)); ++ printf("run: '%s'\n", program); + } + out: + if (event != NULL && event->fd_signal >= 0) +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 7c6c5d6..3d5feb4 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -272,7 +272,7 @@ static void worker_new(struct event *event) + for (;;) { + struct udev_event *udev_event; + struct worker_message msg; +- int err; ++ int err = 0; + + log_debug("seq %llu running\n", udev_device_get_seqnum(dev)); + udev_event = udev_event_new(dev); +@@ -288,13 +288,12 @@ static void worker_new(struct event *event) + udev_event->exec_delay = exec_delay; + + /* apply rules, create node, symlinks */ +- err = udev_event_execute_rules(udev_event, rules, &sigmask_orig); ++ udev_event_execute_rules(udev_event, rules, &sigmask_orig); + +- if (err == 0) +- udev_event_execute_run(udev_event, &sigmask_orig); ++ udev_event_execute_run(udev_event, &sigmask_orig); + + /* apply/restore inotify watch */ +- if (err == 0 && udev_event->inotify_watch) { ++ if (udev_event->inotify_watch) { + udev_watch_begin(udev, dev); + udev_device_update_db(dev); + } +@@ -304,8 +303,8 @@ static void worker_new(struct event *event) + + /* send udevd the result of the event execution */ + memset(&msg, 0, sizeof(struct worker_message)); +- if (err != 0) +- msg.exitcode = err; ++ ++ msg.exitcode = err; + msg.pid = getpid(); + send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0); + diff --git a/SOURCES/0277-man-mention-System-Administrator-s-Guide-in-systemct.patch b/SOURCES/0277-man-mention-System-Administrator-s-Guide-in-systemct.patch new file mode 100644 index 0000000..7e82917 --- /dev/null +++ b/SOURCES/0277-man-mention-System-Administrator-s-Guide-in-systemct.patch @@ -0,0 +1,33 @@ +From 28d352847cea4cacab45fe56e9f452eb45bc0708 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 28 Aug 2014 15:12:10 +0200 +Subject: [PATCH] man: mention System Administrator's Guide in systemctl + manpage + +Resolves: #978948 +--- + man/systemctl.xml | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index 25b03d8..d1fda61 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -1350,6 +1350,17 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service + + + ++ Examples ++ ++ For examples how to use systemctl in comparsion ++ with old service and chkconfig command please see: ++ ++ Managing System Services ++ ++ ++ ++ ++ + See Also + + systemd1, diff --git a/SOURCES/0278-vconsole-also-copy-character-maps-not-just-fonts-fro.patch b/SOURCES/0278-vconsole-also-copy-character-maps-not-just-fonts-fro.patch new file mode 100644 index 0000000..2bd6874 --- /dev/null +++ b/SOURCES/0278-vconsole-also-copy-character-maps-not-just-fonts-fro.patch @@ -0,0 +1,57 @@ +From e39ab9b0f4d2cbc9fab10c64c2527908526ea86e Mon Sep 17 00:00:00 2001 +From: Carl Schaefer +Date: Mon, 23 Jun 2014 18:23:48 +0200 +Subject: [PATCH] vconsole: also copy character maps (not just fonts) from vt1 + to vt2, vt3, ... + +https://bugs.freedesktop.org/show_bug.cgi?id=78796 + +(cherry picked from commit ff452e76e2c0f89a32542b7179bb2fd538335933) + +Resolves: #1002450 +--- + src/vconsole/vconsole-setup.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c +index 1bbf737..7196ddf 100644 +--- a/src/vconsole/vconsole-setup.c ++++ b/src/vconsole/vconsole-setup.c +@@ -180,6 +180,10 @@ static int font_load(const char *vc, const char *font, const char *map, const ch + */ + static void font_copy_to_all_vcs(int fd) { + struct vt_stat vcs = {}; ++ unsigned char map8[E_TABSZ]; ++ unsigned short map16[E_TABSZ]; ++ struct unimapdesc unimapd; ++ struct unipair unipairs[USHRT_MAX]; + int i, r; + + /* get active, and 16 bit mask of used VT numbers */ +@@ -209,6 +213,26 @@ static void font_copy_to_all_vcs(int fd) { + cfo.op = KD_FONT_OP_COPY; + cfo.height = vcs.v_active-1; /* tty1 == index 0 */ + ioctl(vcfd, KDFONTOP, &cfo); ++ ++ /* copy map of 8bit chars */ ++ if (ioctl(fd, GIO_SCRNMAP, map8) >= 0) ++ ioctl(vcfd, PIO_SCRNMAP, map8); ++ ++ /* copy map of 8bit chars -> 16bit Unicode values */ ++ if (ioctl(fd, GIO_UNISCRNMAP, map16) >= 0) ++ ioctl(vcfd, PIO_UNISCRNMAP, map16); ++ ++ /* copy unicode translation table */ ++ /* unimapd is a ushort count and a pointer to an ++ array of struct unipair { ushort, ushort } */ ++ unimapd.entries = unipairs; ++ unimapd.entry_ct = USHRT_MAX; ++ if (ioctl(fd, GIO_UNIMAP, &unimapd) >= 0) { ++ struct unimapinit adv = { 0, 0, 0 }; ++ ++ ioctl(vcfd, PIO_UNIMAPCLR, &adv); ++ ioctl(vcfd, PIO_UNIMAP, &unimapd); ++ } + } + } + diff --git a/SOURCES/0279-vconsole-setup-run-setfont-before-loadkeys.patch b/SOURCES/0279-vconsole-setup-run-setfont-before-loadkeys.patch new file mode 100644 index 0000000..2a543f3 --- /dev/null +++ b/SOURCES/0279-vconsole-setup-run-setfont-before-loadkeys.patch @@ -0,0 +1,99 @@ +From a5236c816e1b8f7a56b2b4b0fa5ac2d5998e5b84 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 1 Jul 2014 22:20:11 -0400 +Subject: [PATCH] vconsole-setup: run setfont before loadkeys + +https://bugs.freedesktop.org/show_bug.cgi?id=80685 + +(cherry picked from commit abee28c56d523e55751b0c007d0bf812cc285c00) + +Conflicts: + src/vconsole/vconsole-setup.c + +Related: #1002450 +--- + src/vconsole/vconsole-setup.c | 49 ++++++++++++++++++++----------------------- + 1 file changed, 23 insertions(+), 26 deletions(-) + +diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c +index 7196ddf..25d15af 100644 +--- a/src/vconsole/vconsole-setup.c ++++ b/src/vconsole/vconsole-setup.c +@@ -238,12 +238,10 @@ static void font_copy_to_all_vcs(int fd) { + + int main(int argc, char **argv) { + const char *vc; +- char *vc_keymap = NULL; +- char *vc_keymap_toggle = NULL; +- char *vc_font = NULL; +- char *vc_font_map = NULL; +- char *vc_font_unimap = NULL; +- int fd = -1; ++ _cleanup_free_ char ++ *vc_keymap = NULL, *vc_keymap_toggle = NULL, ++ *vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL; ++ _cleanup_close_ int fd = -1; + bool utf8; + pid_t font_pid = 0, keymap_pid = 0; + bool font_copy = false; +@@ -265,12 +263,12 @@ int main(int argc, char **argv) { + fd = open_terminal(vc, O_RDWR|O_CLOEXEC); + if (fd < 0) { + log_error("Failed to open %s: %m", vc); +- goto finish; ++ return EXIT_FAILURE; + } + + if (!is_vconsole(fd)) { + log_error("Device %s is not a virtual console.", vc); +- goto finish; ++ return EXIT_FAILURE; + } + + utf8 = is_locale_utf8(); +@@ -305,28 +303,27 @@ int main(int argc, char **argv) { + else + disable_utf8(fd); + +- r = EXIT_FAILURE; +- if (keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid) >= 0 && +- font_load(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0) +- r = EXIT_SUCCESS; +- +-finish: +- if (keymap_pid > 0) +- wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); ++ r = font_load(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid); ++ if (r < 0) { ++ log_error("Failed to start " KBD_LOADKEYS ": %s", strerror(-r)); ++ return EXIT_FAILURE; ++ } + +- if (font_pid > 0) { ++ if (font_pid > 0) + wait_for_terminate_and_warn(KBD_SETFONT, font_pid); +- if (font_copy) +- font_copy_to_all_vcs(fd); ++ ++ r = keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid); ++ if (r < 0) { ++ log_error("Failed to start " KBD_SETFONT ": %s", strerror(-r)); ++ return EXIT_FAILURE; + } + +- free(vc_keymap); +- free(vc_font); +- free(vc_font_map); +- free(vc_font_unimap); ++ if (keymap_pid > 0) ++ wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); + +- if (fd >= 0) +- close_nointr_nofail(fd); ++ /* Only copy the font when we started setfont successfully */ ++ if (font_copy && font_pid > 0) ++ font_copy_to_all_vcs(fd); + +- return r; ++ return EXIT_SUCCESS; + } diff --git a/SOURCES/0280-vconsole-setup-fix-inverted-error-messages.patch b/SOURCES/0280-vconsole-setup-fix-inverted-error-messages.patch new file mode 100644 index 0000000..b48682d --- /dev/null +++ b/SOURCES/0280-vconsole-setup-fix-inverted-error-messages.patch @@ -0,0 +1,38 @@ +From ef543bf1d0011c0c7bfe38e097c1ef53e7027591 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 7 Jul 2014 08:55:30 -0400 +Subject: [PATCH] vconsole-setup: fix inverted error messages + +Introduced in abee28c56d. + +Pointed-out-by: Werner Fink + +(cherry picked from commit 3dde3f819732aaa66ab8e881305488adaea17641) + +Related: #1002450 +--- + src/vconsole/vconsole-setup.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c +index 25d15af..645b1e6 100644 +--- a/src/vconsole/vconsole-setup.c ++++ b/src/vconsole/vconsole-setup.c +@@ -305,7 +305,7 @@ int main(int argc, char **argv) { + + r = font_load(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid); + if (r < 0) { +- log_error("Failed to start " KBD_LOADKEYS ": %s", strerror(-r)); ++ log_error("Failed to start " KBD_SETFONT ": %s", strerror(-r)); + return EXIT_FAILURE; + } + +@@ -314,7 +314,7 @@ int main(int argc, char **argv) { + + r = keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid); + if (r < 0) { +- log_error("Failed to start " KBD_SETFONT ": %s", strerror(-r)); ++ log_error("Failed to start " KBD_LOADKEYS ": %s", strerror(-r)); + return EXIT_FAILURE; + } + diff --git a/SOURCES/0281-localed-consider-an-unset-model-as-a-wildcard.patch b/SOURCES/0281-localed-consider-an-unset-model-as-a-wildcard.patch new file mode 100644 index 0000000..1ebefe1 --- /dev/null +++ b/SOURCES/0281-localed-consider-an-unset-model-as-a-wildcard.patch @@ -0,0 +1,42 @@ +From a27bc4778ef4579a954846cb75435226655ad31a Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 30 May 2014 18:20:16 +0200 +Subject: [PATCH] localed: consider an unset model as a wildcard + +(cherry picked from commit 387066c2e5bda159201896b194711965b52f34a9) + +Conflicts: + src/locale/localed.c + +Resolves: #903776 +--- + src/locale/localed.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/src/locale/localed.c b/src/locale/localed.c +index b9b98f4..a93b309 100644 +--- a/src/locale/localed.c ++++ b/src/locale/localed.c +@@ -871,15 +871,16 @@ static int find_legacy_keymap(char **new_keymap) { + } + } + +- if (matching > 0 && +- streq_ptr(state.x11_model, a[2])) { +- matching++; +- +- if (streq_ptr(state.x11_variant, a[3])) { ++ if (matching > 0) { ++ if (isempty(state.x11_model) || streq_ptr(state.x11_model, a[2])) { + matching++; + +- if (streq_ptr(state.x11_options, a[4])) ++ if (streq_ptr(state.x11_variant, a[3])) { + matching++; ++ ++ if (streq_ptr(state.x11_options, a[4])) ++ matching++; ++ } + } + } + diff --git a/SOURCES/0282-systemd-detect-virt-detect-s390-virtualization.patch b/SOURCES/0282-systemd-detect-virt-detect-s390-virtualization.patch new file mode 100644 index 0000000..33c6bfa --- /dev/null +++ b/SOURCES/0282-systemd-detect-virt-detect-s390-virtualization.patch @@ -0,0 +1,75 @@ +From 50bb38a3dc24eb252097e958387d5a7075717a5a Mon Sep 17 00:00:00 2001 +From: Thomas Blume +Date: Fri, 18 Jul 2014 09:13:36 -0400 +Subject: [PATCH] systemd-detect-virt: detect s390 virtualization + +A system that is running on a logical partition (LPAR) provided by +PR/SM has access to physical hardware (except CPU). It is true that +PR/SM abstracts the hardware, but only for sharing purposes. + +Details are statet at: + +http://publib.boulder.ibm.com/infocenter/eserver/v1r2/topic/eicaz/eicazzlpar.htm + +-->-- +In other words, PR/SM transforms physical resources into virtual resources so +that many logical partitions can share the same physical resources. +--<-- + +Still, from the OS point of view, the shared virtual resource is real +hardware. ConditionVirtualization must be set to false if the OS runs +directly on PR/SM (e.g. in an LPAR). + +[zj: reorder code so that variables are not allocated when #if-def is +false. Add commit message.] + +Conflicts: + src/shared/virt.c + +(cherry picked from commit f41925b4e442a34c93ad120ef1426c974a047ed1) + +Resolves: #1139149 +--- + man/systemd.unit.xml | 1 + + src/shared/virt.c | 16 ++++++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 4704352..c500953 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -969,6 +969,7 @@ + virtualization solution, or one of + qemu, + kvm, ++ zvm, + vmware, + microsoft, + oracle, +diff --git a/src/shared/virt.c b/src/shared/virt.c +index 4f8134a..5466d97 100644 +--- a/src/shared/virt.c ++++ b/src/shared/virt.c +@@ -175,6 +175,22 @@ int detect_vm(const char **id) { + return 1; + } + ++#if defined(__s390__) ++ { ++ _cleanup_free_ char *t = NULL; ++ ++ r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t); ++ if (r >= 0) { ++ if (streq(t, "z/VM")) ++ _id = "zvm"; ++ else ++ _id = "kvm"; ++ ++ return 1; ++ } ++ } ++#endif ++ + return 0; + } + diff --git a/SOURCES/0283-systemctl-unbreak-switchroot.patch b/SOURCES/0283-systemctl-unbreak-switchroot.patch new file mode 100644 index 0000000..8183aa5 --- /dev/null +++ b/SOURCES/0283-systemctl-unbreak-switchroot.patch @@ -0,0 +1,75 @@ +From e1036b1b5133141949bea166fb2cb6cdbfec3be0 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Fri, 12 Sep 2014 13:27:36 +0200 +Subject: [PATCH] systemctl: unbreak switchroot + +rhel-only patch +cad8ec5980d63253586d9f884649c45eed0667a1 backport broke it + +Related: #1138546 +--- + src/systemctl/systemctl.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 90a80bd..ebc8caa 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -4147,8 +4147,8 @@ static int show_enviroment(DBusConnection *bus, char **args) { + } + + static int switch_root(DBusConnection *bus, char **args) { +- _cleanup_free_ char *cmdline_init = NULL; +- const char *root, *init; ++ _cleanup_free_ char *init = NULL; ++ const char *root; + unsigned l; + int r; + +@@ -4161,23 +4161,20 @@ static int switch_root(DBusConnection *bus, char **args) { + root = args[1]; + + if (l >= 3) +- init = args[2]; ++ init = strdup(args[2]); + else { + r = parse_env_file("/proc/cmdline", WHITESPACE, +- "init", &cmdline_init, ++ "init", &init, + NULL); + if (r < 0) + log_debug("Failed to parse /proc/cmdline: %s", strerror(-r)); + +- init = cmdline_init; ++ if (!init) ++ init = strdup(""); + } +- if (!init) +- return log_oom(); + +- if (isempty(init)) +- init = NULL; + +- if (init) { ++ if (!isempty(init)) { + const char *root_systemd_path = NULL, *root_init_path = NULL; + + root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH); +@@ -4185,10 +4182,15 @@ static int switch_root(DBusConnection *bus, char **args) { + + /* If the passed init is actually the same as the + * systemd binary, then let's suppress it. */ +- if (files_same(root_init_path, root_systemd_path) > 0) +- init = NULL; ++ if (files_same(root_init_path, root_systemd_path) > 0) { ++ free(init); ++ init = strdup(""); ++ } + } + ++ if (!init) ++ return log_oom(); ++ + log_debug("Switching root - root: %s; init: %s", root, strna(init)); + + return bus_method_call_with_reply( diff --git a/SOURCES/0284-systemd-detect-virt-fix-detect-s390-virtualization.patch b/SOURCES/0284-systemd-detect-virt-fix-detect-s390-virtualization.patch new file mode 100644 index 0000000..4b96c27 --- /dev/null +++ b/SOURCES/0284-systemd-detect-virt-fix-detect-s390-virtualization.patch @@ -0,0 +1,28 @@ +From 4c05a1381fbedaebe3832da433e4e10c682d6384 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Fri, 12 Sep 2014 15:23:50 +0200 +Subject: [PATCH] systemd-detect-virt: fix detect s390 virtualization + +rhel-only patch + +Related: #1139149 +--- + src/shared/virt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/shared/virt.c b/src/shared/virt.c +index 5466d97..fca8515 100644 +--- a/src/shared/virt.c ++++ b/src/shared/virt.c +@@ -182,9 +182,9 @@ int detect_vm(const char **id) { + r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t); + if (r >= 0) { + if (streq(t, "z/VM")) +- _id = "zvm"; ++ *id = "zvm"; + else +- _id = "kvm"; ++ *id = "kvm"; + + return 1; + } diff --git a/SOURCES/0285-exec-Add-SELinuxContext-configuration-item.patch b/SOURCES/0285-exec-Add-SELinuxContext-configuration-item.patch new file mode 100644 index 0000000..d98ae1d --- /dev/null +++ b/SOURCES/0285-exec-Add-SELinuxContext-configuration-item.patch @@ -0,0 +1,180 @@ +From d0a2b8832732d297321fddcad56872511ff212f2 Mon Sep 17 00:00:00 2001 +From: Michael Scherer +Date: Thu, 6 Feb 2014 10:05:16 +0100 +Subject: [PATCH] exec: Add SELinuxContext configuration item +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This permit to let system administrators decide of the domain of a service. +This can be used with templated units to have each service in a différent +domain ( for example, a per customer database, using MLS or anything ), +or can be used to force a non selinux enabled system (jvm, erlang, etc) +to start in a different domain for each service. + +Conflicts: + src/core/dbus-execute.c + src/core/execute.c + src/core/execute.h + src/shared/exit-status.c + src/shared/exit-status.h + +(cherry picked from commit 7b52a628f8b43ba521c302a7f32bccf9d0dc8bfd) + +Related: #1113790 +--- + man/systemd.exec.xml | 11 +++++++++++ + src/core/dbus-execute.c | 1 + + src/core/execute.c | 27 +++++++++++++++++++++++++++ + src/core/execute.h | 2 ++ + src/core/load-fragment-gperf.gperf.m4 | 3 ++- + src/shared/exit-status.c | 3 +++ + src/shared/exit-status.h | 1 + + 7 files changed, 47 insertions(+), 1 deletion(-) + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index 612b4d2..a68cfa7 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -919,6 +919,17 @@ + + + ++ SELinuxContext= ++ ++ Set the SELinux context of the ++ executed process. If set, this will override the ++ automated domain transition. However, the policy ++ still need to autorize the transition. See ++ setexeccon3 ++ for details. ++ ++ ++ + IgnoreSIGPIPE= + + Takes a boolean +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 2402e8c..97d75fa 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -429,6 +429,7 @@ const BusProperty bus_exec_context_properties[] = { + { "PrivateNetwork", bus_property_append_bool, "b", offsetof(ExecContext, private_network) }, + { "SameProcessGroup", bus_property_append_bool, "b", offsetof(ExecContext, same_pgrp) }, + { "UtmpIdentifier", bus_property_append_string, "s", offsetof(ExecContext, utmp_id), true }, ++ { "SELinuxContext", bus_property_append_string, "s", offsetof(ExecContext, selinux_context), true }, + { "IgnoreSIGPIPE", bus_property_append_bool, "b", offsetof(ExecContext, ignore_sigpipe) }, + { "NoNewPrivileges", bus_property_append_bool, "b", offsetof(ExecContext, no_new_privileges) }, + { "SystemCallFilter", bus_execute_append_syscall_filter, "au", 0 }, +diff --git a/src/core/execute.c b/src/core/execute.c +index 981b9e4..cf9d24e 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -46,6 +46,10 @@ + #include + #endif + ++#ifdef HAVE_SELINUX ++#include ++#endif ++ + #include "execute.h" + #include "strv.h" + #include "macro.h" +@@ -1467,6 +1471,20 @@ int exec_spawn(ExecCommand *command, + goto fail_child; + } + } ++#ifdef HAVE_SELINUX ++ if (context->selinux_context) { ++ err = security_check_context(context->selinux_context); ++ if (err < 0) { ++ r = EXIT_SELINUX_CONTEXT; ++ goto fail_child; ++ } ++ err = setexeccon(context->selinux_context); ++ if (err < 0) { ++ r = EXIT_SELINUX_CONTEXT; ++ goto fail_child; ++ } ++ } ++#endif + } + + our_env = new0(char*, 7); +@@ -1696,6 +1714,9 @@ void exec_context_done(ExecContext *c, bool reloading_or_reexecuting) { + free(c->utmp_id); + c->utmp_id = NULL; + ++ free(c->selinux_context); ++ c->selinux_context = NULL; ++ + free(c->syscall_filter); + c->syscall_filter = NULL; + +@@ -2067,6 +2088,12 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { + fprintf(f, + "%sUtmpIdentifier: %s\n", + prefix, c->utmp_id); ++ ++ if (c->selinux_context) ++ fprintf(f, ++ "%sSELinuxContext: %s\n", ++ prefix, c->selinux_context); ++ + } + + void exec_status_start(ExecStatus *s, pid_t pid) { +diff --git a/src/core/execute.h b/src/core/execute.h +index c1e9717..92ac8dd 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -124,6 +124,8 @@ struct ExecContext { + + char *utmp_id; + ++ char *selinux_context; ++ + char **read_write_dirs, **read_only_dirs, **inaccessible_dirs; + unsigned long mount_flags; + +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 0991cb9..935f04e 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -75,7 +75,8 @@ $1.MountFlags, config_parse_exec_mount_flags, 0, + $1.TCPWrapName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.tcpwrap_name) + $1.PAMName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.pam_name) + $1.IgnoreSIGPIPE, config_parse_bool, 0, offsetof($1, exec_context.ignore_sigpipe) +-$1.UtmpIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.utmp_id)' ++$1.UtmpIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.utmp_id) ++$1.SELinuxContext, config_parse_unit_string_printf, 0, offsetof($1, exec_context.selinux_context)' + )m4_dnl + m4_define(`KILL_CONTEXT_CONFIG_ITEMS', + `$1.SendSIGKILL, config_parse_bool, 0, offsetof($1, kill_context.send_sigkill) +diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c +index f15fdba..676291b 100644 +--- a/src/shared/exit-status.c ++++ b/src/shared/exit-status.c +@@ -131,6 +131,9 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) { + case EXIT_SECCOMP: + return "SECCOMP"; + ++ case EXIT_SELINUX_CONTEXT: ++ return "SELINUX_CONTEXT"; ++ + case EXIT_CHOWN: + return "CHOWN"; + +diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h +index 52dd3d0..798f1e1 100644 +--- a/src/shared/exit-status.h ++++ b/src/shared/exit-status.h +@@ -68,6 +68,7 @@ typedef enum ExitStatus { + EXIT_NAMESPACE, + EXIT_NO_NEW_PRIVILEGES, + EXIT_SECCOMP, ++ EXIT_SELINUX_CONTEXT, + EXIT_CHOWN + } ExitStatus; + diff --git a/SOURCES/0286-exec-Ignore-the-setting-SELinuxContext-if-selinux-is.patch b/SOURCES/0286-exec-Ignore-the-setting-SELinuxContext-if-selinux-is.patch new file mode 100644 index 0000000..53183d4 --- /dev/null +++ b/SOURCES/0286-exec-Ignore-the-setting-SELinuxContext-if-selinux-is.patch @@ -0,0 +1,26 @@ +From 602f5a2c2a7ed23ebd61a728f6e16f63024e3c1f Mon Sep 17 00:00:00 2001 +From: Michael Scherer +Date: Thu, 6 Feb 2014 10:05:17 +0100 +Subject: [PATCH] exec: Ignore the setting SELinuxContext if selinux is not + enabled + +(cherry picked from commit 5c56a259e07661a66e806cc2fbc71de96a75f78e) + +Related: #1113790 +--- + src/core/execute.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index cf9d24e..cb6f146 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1472,7 +1472,7 @@ int exec_spawn(ExecCommand *command, + } + } + #ifdef HAVE_SELINUX +- if (context->selinux_context) { ++ if (context->selinux_context && use_selinux()) { + err = security_check_context(context->selinux_context); + if (err < 0) { + r = EXIT_SELINUX_CONTEXT; diff --git a/SOURCES/0287-exec-Add-support-for-ignoring-errors-on-SELinuxConte.patch b/SOURCES/0287-exec-Add-support-for-ignoring-errors-on-SELinuxConte.patch new file mode 100644 index 0000000..24e2e9a --- /dev/null +++ b/SOURCES/0287-exec-Add-support-for-ignoring-errors-on-SELinuxConte.patch @@ -0,0 +1,70 @@ +From 5c2592bf519dc7b2b28cde77f5f35422ec7a9320 Mon Sep 17 00:00:00 2001 +From: Michael Scherer +Date: Thu, 6 Feb 2014 10:05:18 +0100 +Subject: [PATCH] exec: Add support for ignoring errors on SELinuxContext by + prefixing it with -, like for others settings. + +Also remove call to security_check_context, as this doesn't serve anything, since +setexeccon will fail anyway. + +(cherry picked from commit 0d3f7bb3a5bc6d5c0712f88a080fed388981bca3) + +Related: #1113790 +--- + man/systemd.exec.xml | 4 +++- + src/core/execute.c | 20 +++++++++++++------- + 2 files changed, 16 insertions(+), 8 deletions(-) + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index a68cfa7..7608489 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -924,7 +924,9 @@ + Set the SELinux context of the + executed process. If set, this will override the + automated domain transition. However, the policy +- still need to autorize the transition. See ++ still need to autorize the transition. This directive ++ is ignored if SELinux is disabled. If prefixed by -, ++ all errors will be ignored. See + setexeccon3 + for details. + +diff --git a/src/core/execute.c b/src/core/execute.c +index cb6f146..9fc5090 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -72,6 +72,7 @@ + #include "fileio.h" + #include "unit.h" + #include "async.h" ++#include "selinux-util.h" + + #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC) + #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC) +@@ -1473,13 +1474,18 @@ int exec_spawn(ExecCommand *command, + } + #ifdef HAVE_SELINUX + if (context->selinux_context && use_selinux()) { +- err = security_check_context(context->selinux_context); +- if (err < 0) { +- r = EXIT_SELINUX_CONTEXT; +- goto fail_child; +- } +- err = setexeccon(context->selinux_context); +- if (err < 0) { ++ bool ignore; ++ char* c; ++ ++ c = context->selinux_context; ++ if (c[0] == '-') { ++ c++; ++ ignore = true; ++ } else ++ ignore = false; ++ ++ err = setexeccon(c); ++ if (err < 0 && !ignore) { + r = EXIT_SELINUX_CONTEXT; + goto fail_child; + } diff --git a/SOURCES/0288-core-store-and-expose-SELinuxContext-field-normalize.patch b/SOURCES/0288-core-store-and-expose-SELinuxContext-field-normalize.patch new file mode 100644 index 0000000..3bf7ac7 --- /dev/null +++ b/SOURCES/0288-core-store-and-expose-SELinuxContext-field-normalize.patch @@ -0,0 +1,199 @@ +From f71db1f834f639a16a38e7314ba7ca0dd0d060d8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 17 Feb 2014 16:52:52 +0100 +Subject: [PATCH] core: store and expose SELinuxContext field normalized as + bool + string + +Conflicts: + src/core/dbus-execute.c + src/core/execute.c + src/core/load-fragment.h + +(cherry picked from commit 5f8640fb628cb034981e02d741fd9ddf26fdf38d) + +Related: #1113790 +--- + src/core/dbus-execute.c | 26 ++++++++++++++++++- + src/core/execute.c | 18 +++---------- + src/core/execute.h | 1 + + src/core/load-fragment-gperf.gperf.m4 | 2 +- + src/core/load-fragment.c | 48 +++++++++++++++++++++++++++++++++++ + src/core/load-fragment.h | 1 + + 6 files changed, 80 insertions(+), 16 deletions(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 97d75fa..8162f1c 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -372,6 +372,30 @@ static int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *pro + return 0; + } + ++static int bus_execute_append_selinux_context(DBusMessageIter *i, const char *property, void *data) { ++ ExecContext *c = data; ++ dbus_bool_t selinux_context_ignore; ++ const char *selinux_context = NULL; ++ ++ assert(i); ++ assert(property); ++ assert(c); ++ ++ selinux_context = c->selinux_context; ++ if (!selinux_context) ++ selinux_context = ""; ++ ++ selinux_context_ignore = c->selinux_context_ignore; ++ ++ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &selinux_context_ignore)) ++ return -ENOMEM; ++ ++ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &selinux_context)) ++ return -ENOMEM; ++ ++ return 0; ++} ++ + const BusProperty bus_exec_context_properties[] = { + { "Environment", bus_property_append_strv, "as", offsetof(ExecContext, environment), true }, + { "EnvironmentFiles", bus_execute_append_env_files, "a(sb)", offsetof(ExecContext, environment_files), true }, +@@ -429,7 +453,7 @@ const BusProperty bus_exec_context_properties[] = { + { "PrivateNetwork", bus_property_append_bool, "b", offsetof(ExecContext, private_network) }, + { "SameProcessGroup", bus_property_append_bool, "b", offsetof(ExecContext, same_pgrp) }, + { "UtmpIdentifier", bus_property_append_string, "s", offsetof(ExecContext, utmp_id), true }, +- { "SELinuxContext", bus_property_append_string, "s", offsetof(ExecContext, selinux_context), true }, ++ { "SELinuxContext", bus_execute_append_selinux_context, "(bs)", 0 }, + { "IgnoreSIGPIPE", bus_property_append_bool, "b", offsetof(ExecContext, ignore_sigpipe) }, + { "NoNewPrivileges", bus_property_append_bool, "b", offsetof(ExecContext, no_new_privileges) }, + { "SystemCallFilter", bus_execute_append_syscall_filter, "au", 0 }, +diff --git a/src/core/execute.c b/src/core/execute.c +index 9fc5090..a20301d 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1474,18 +1474,8 @@ int exec_spawn(ExecCommand *command, + } + #ifdef HAVE_SELINUX + if (context->selinux_context && use_selinux()) { +- bool ignore; +- char* c; +- +- c = context->selinux_context; +- if (c[0] == '-') { +- c++; +- ignore = true; +- } else +- ignore = false; +- +- err = setexeccon(c); +- if (err < 0 && !ignore) { ++ err = setexeccon(context->selinux_context); ++ if (err < 0 && !context->selinux_context_ignore) { + r = EXIT_SELINUX_CONTEXT; + goto fail_child; + } +@@ -2097,8 +2087,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { + + if (c->selinux_context) + fprintf(f, +- "%sSELinuxContext: %s\n", +- prefix, c->selinux_context); ++ "%sSELinuxContext: %s%s\n", ++ prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context); + + } + +diff --git a/src/core/execute.h b/src/core/execute.h +index 92ac8dd..2452126 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -124,6 +124,7 @@ struct ExecContext { + + char *utmp_id; + ++ bool selinux_context_ignore; + char *selinux_context; + + char **read_write_dirs, **read_only_dirs, **inaccessible_dirs; +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 935f04e..759fbd8 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -76,7 +76,7 @@ $1.TCPWrapName, config_parse_unit_string_printf, 0, + $1.PAMName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.pam_name) + $1.IgnoreSIGPIPE, config_parse_bool, 0, offsetof($1, exec_context.ignore_sigpipe) + $1.UtmpIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.utmp_id) +-$1.SELinuxContext, config_parse_unit_string_printf, 0, offsetof($1, exec_context.selinux_context)' ++$1.SELinuxContext, config_parse_exec_selinux_context, 0, offsetof($1, exec_context)' + )m4_dnl + m4_define(`KILL_CONTEXT_CONFIG_ITEMS', + `$1.SendSIGKILL, config_parse_bool, 0, offsetof($1, kill_context.send_sigkill) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index f01843d..8e6e428 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -1139,6 +1139,54 @@ int config_parse_exec_mount_flags(const char *unit, + return 0; + } + ++int config_parse_exec_selinux_context( ++ const char *unit, ++ const char *filename, ++ unsigned line, ++ const char *section, ++ const char *lvalue, ++ int ltype, ++ const char *rvalue, ++ void *data, ++ void *userdata) { ++ ++ ExecContext *c = data; ++ Unit *u = userdata; ++ bool ignore; ++ char *k; ++ int r; ++ ++ assert(filename); ++ assert(lvalue); ++ assert(rvalue); ++ assert(data); ++ ++ if (isempty(rvalue)) { ++ free(c->selinux_context); ++ c->selinux_context = NULL; ++ c->selinux_context_ignore = false; ++ return 0; ++ } ++ ++ if (rvalue[0] == '-') { ++ ignore = true; ++ rvalue++; ++ } else ++ ignore = false; ++ ++ r = unit_name_printf(u, rvalue, &k); ++ if (r < 0) { ++ log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", strerror(-r)); ++ return 0; ++ } ++ ++ free(c->selinux_context); ++ c->selinux_context = k; ++ c->selinux_context_ignore = ignore; ++ ++ return 0; ++} ++ + int config_parse_timer(const char *unit, + const char *filename, + unsigned line, +diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h +index 90e5e3a..de48436 100644 +--- a/src/core/load-fragment.h ++++ b/src/core/load-fragment.h +@@ -83,6 +83,7 @@ int config_parse_device_allow(const char *unit, const char *filename, unsigned l + int config_parse_blockio_weight(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + int config_parse_blockio_device_weight(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + int config_parse_blockio_bandwidth(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); ++int config_parse_exec_selinux_context(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + + /* gperf prototypes */ + const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length); diff --git a/SOURCES/0289-socket-introduce-SELinuxContextFromNet-option.patch b/SOURCES/0289-socket-introduce-SELinuxContextFromNet-option.patch new file mode 100644 index 0000000..d1a60da --- /dev/null +++ b/SOURCES/0289-socket-introduce-SELinuxContextFromNet-option.patch @@ -0,0 +1,431 @@ +From 98bb285648a68c89820fe7415737ee97da74ec69 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 24 Jul 2014 10:40:28 +0200 +Subject: [PATCH] socket: introduce SELinuxContextFromNet option + +This makes possible to spawn service instances triggered by socket with +MLS/MCS SELinux labels which are created based on information provided by +connected peer. + +Implementation of label_get_child_mls_label derived from xinetd. + +Reviewed-by: Paul Moore + +Resolves: #1113790 +--- + man/systemd.socket.xml | 26 ++++++++ + src/core/execute.c | 30 +++++++-- + src/core/execute.h | 1 + + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/mount.c | 1 + + src/core/service.c | 4 +- + src/core/service.h | 3 +- + src/core/socket.c | 16 +++-- + src/core/socket.h | 2 + + src/core/swap.c | 1 + + src/shared/label.c | 113 ++++++++++++++++++++++++++++++++++ + src/shared/label.h | 2 + + 12 files changed, 189 insertions(+), 11 deletions(-) + +diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml +index d146b3b..75ba15f 100644 +--- a/man/systemd.socket.xml ++++ b/man/systemd.socket.xml +@@ -585,6 +585,32 @@ + + + ++ SELinuxContextFromNet= ++ Takes a boolean ++ argument. When true systemd will attempt ++ to figure out the SELinux label used ++ for the instantiated service from the ++ information handed by the peer over the ++ network. Note that only the security ++ level is used from the information ++ provided by the peer. Other parts of ++ the resulting SELinux context originate ++ from either the target binary that is ++ effectively triggered by socket unit ++ are taken from the value of the ++ SELinuxContext= ++ option.This configuration option only ++ affects sockets with ++ Accept= mode set to ++ true. Also note that ++ this option is useful only when ++ MLS/MCS SELinux policy is ++ deployed. Defaults to ++ false. ++ ++ ++ ++ + PipeSize= + Takes an integer + value. Controls the pipe buffer size +diff --git a/src/core/execute.c b/src/core/execute.c +index a20301d..0894156 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -73,6 +73,7 @@ + #include "unit.h" + #include "async.h" + #include "selinux-util.h" ++#include "label.h" + + #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC) + #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC) +@@ -1038,6 +1039,7 @@ int exec_spawn(ExecCommand *command, + bool apply_chroot, + bool apply_tty_stdin, + bool confirm_spawn, ++ bool selinux_context_net, + CGroupControllerMask cgroup_supported, + const char *cgroup_path, + const char *unit_id, +@@ -1473,11 +1475,29 @@ int exec_spawn(ExecCommand *command, + } + } + #ifdef HAVE_SELINUX +- if (context->selinux_context && use_selinux()) { +- err = setexeccon(context->selinux_context); +- if (err < 0 && !context->selinux_context_ignore) { +- r = EXIT_SELINUX_CONTEXT; +- goto fail_child; ++ if (use_selinux()) { ++ if (context->selinux_context) { ++ err = setexeccon(context->selinux_context); ++ if (err < 0 && !context->selinux_context_ignore) { ++ r = EXIT_SELINUX_CONTEXT; ++ goto fail_child; ++ } ++ } ++ ++ if (selinux_context_net && socket_fd >= 0) { ++ _cleanup_free_ char *label = NULL; ++ ++ err = label_get_child_mls_label(socket_fd, command->path, &label); ++ if (err < 0) { ++ r = EXIT_SELINUX_CONTEXT; ++ goto fail_child; ++ } ++ ++ err = setexeccon(label); ++ if (err < 0) { ++ r = EXIT_SELINUX_CONTEXT; ++ goto fail_child; ++ } + } + } + #endif +diff --git a/src/core/execute.h b/src/core/execute.h +index 2452126..5055890 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -174,6 +174,7 @@ int exec_spawn(ExecCommand *command, + bool apply_chroot, + bool apply_tty_stdin, + bool confirm_spawn, ++ bool selinux_context_net, + CGroupControllerMask cgroup_mask, + const char *cgroup_path, + const char *unit_id, +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 759fbd8..ee7cd5d 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -221,6 +221,7 @@ Socket.Service, config_parse_socket_service, 0, + Socket.SmackLabel, config_parse_string, 0, offsetof(Socket, smack) + Socket.SmackLabelIPIn, config_parse_string, 0, offsetof(Socket, smack_ip_in) + Socket.SmackLabelIPOut, config_parse_string, 0, offsetof(Socket, smack_ip_out) ++Socket.SELinuxContextFromNet, config_parse_bool, 0, offsetof(Socket, selinux_context_from_net), + EXEC_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl + CGROUP_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl + KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl +diff --git a/src/core/mount.c b/src/core/mount.c +index 3672338..bbceb92 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -791,6 +791,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { + true, + true, + UNIT(m)->manager->confirm_spawn, ++ false, + UNIT(m)->manager->cgroup_supported, + UNIT(m)->cgroup_path, + UNIT(m)->id, +diff --git a/src/core/service.c b/src/core/service.c +index 4366e1b..7ef2b3a 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1867,6 +1867,7 @@ static int service_spawn( + apply_chroot, + apply_tty_stdin, + UNIT(s)->manager->confirm_spawn, ++ false, + UNIT(s)->manager->cgroup_supported, + path, + UNIT(s)->id, +@@ -3806,7 +3807,7 @@ static void service_bus_query_pid_done( + } + } + +-int service_set_socket_fd(Service *s, int fd, Socket *sock) { ++int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context_net) { + + assert(s); + assert(fd >= 0); +@@ -3825,6 +3826,7 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock) { + return -EAGAIN; + + s->socket_fd = fd; ++ s->socket_fd_selinux_context_net = selinux_context_net; + s->got_socket_fd = true; + + unit_ref_set(&s->accept_socket, UNIT(sock)); +diff --git a/src/core/service.h b/src/core/service.h +index fa4ef2b..24e6b4e 100644 +--- a/src/core/service.h ++++ b/src/core/service.h +@@ -156,6 +156,7 @@ struct Service { + + pid_t main_pid, control_pid; + int socket_fd; ++ bool socket_fd_selinux_context_net; + + int fsck_passno; + +@@ -204,7 +205,7 @@ extern const UnitVTable service_vtable; + + struct Socket; + +-int service_set_socket_fd(Service *s, int fd, struct Socket *socket); ++int service_set_socket_fd(Service *s, int fd, struct Socket *socket, bool selinux_context_net); + + const char* service_state_to_string(ServiceState i) _const_; + ServiceState service_state_from_string(const char *s) _pure_; +diff --git a/src/core/socket.c b/src/core/socket.c +index 32e0d35..35fc204 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -431,7 +431,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { + "%sBroadcast: %s\n" + "%sPassCredentials: %s\n" + "%sPassSecurity: %s\n" +- "%sTCPCongestion: %s\n", ++ "%sTCPCongestion: %s\n" ++ "%sSELinuxContextFromNet: %s\n", + prefix, socket_state_to_string(s->state), + prefix, socket_result_to_string(s->result), + prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only), +@@ -444,7 +445,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { + prefix, yes_no(s->broadcast), + prefix, yes_no(s->pass_cred), + prefix, yes_no(s->pass_sec), +- prefix, strna(s->tcp_congestion)); ++ prefix, strna(s->tcp_congestion), ++ prefix, yes_no(s->selinux_context_from_net)); + + if (s->control_pid > 0) + fprintf(f, +@@ -994,7 +996,12 @@ static int socket_open_fds(Socket *s) { + + if (p->type == SOCKET_SOCKET) { + +- if (!know_label) { ++ if (!know_label && s->selinux_context_from_net) { ++ r = label_get_our_label(&label); ++ if (r < 0) ++ return r; ++ know_label = true; ++ } else if (!know_label) { + + if ((r = socket_instantiate_service(s)) < 0) + return r; +@@ -1227,6 +1234,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + true, + true, + UNIT(s)->manager->confirm_spawn, ++ s->selinux_context_from_net, + UNIT(s)->manager->cgroup_supported, + UNIT(s)->cgroup_path, + UNIT(s)->id, +@@ -1666,7 +1674,7 @@ static void socket_enter_running(Socket *s, int cfd) { + unit_choose_id(UNIT(service), name); + free(name); + +- r = service_set_socket_fd(service, cfd, s); ++ r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net); + if (r < 0) + goto fail; + +diff --git a/src/core/socket.h b/src/core/socket.h +index 6a24883..ddddf4c 100644 +--- a/src/core/socket.h ++++ b/src/core/socket.h +@@ -154,6 +154,8 @@ struct Socket { + char *smack_ip_in; + char *smack_ip_out; + ++ bool selinux_context_from_net; ++ + char *user; + char *group; + }; +diff --git a/src/core/swap.c b/src/core/swap.c +index 727bb95..b72034f 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -589,6 +589,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { + true, + true, + UNIT(s)->manager->confirm_spawn, ++ false, + UNIT(s)->manager->cgroup_supported, + UNIT(s)->cgroup_path, + UNIT(s)->id, +diff --git a/src/shared/label.c b/src/shared/label.c +index fde39f2..4dab93e 100644 +--- a/src/shared/label.c ++++ b/src/shared/label.c +@@ -38,6 +38,13 @@ + #include "selinux-util.h" + #include + #include ++#include ++ ++define_trivial_cleanup_func(security_context_t, freecon); ++define_trivial_cleanup_func(context_t, context_free); ++ ++#define _cleanup_security_context_free_ _cleanup_(freeconp) ++#define _cleanup_context_free_ _cleanup_(context_freep) + + static struct selabel_handle *label_hnd = NULL; + +@@ -180,6 +187,112 @@ fail: + return r; + } + ++int label_get_our_label(char **label) { ++ int r = -EOPNOTSUPP; ++ char *l = NULL; ++ ++#ifdef HAVE_SELINUX ++ r = getcon(&l); ++ if (r < 0) ++ return r; ++ ++ *label = l; ++#endif ++ ++ return r; ++} ++ ++int label_get_child_mls_label(int socket_fd, const char *exe, char **label) { ++ int r = -EOPNOTSUPP; ++ ++#ifdef HAVE_SELINUX ++ ++ _cleanup_security_context_free_ security_context_t mycon = NULL, peercon = NULL, fcon = NULL, ret = NULL; ++ _cleanup_context_free_ context_t pcon = NULL, bcon = NULL; ++ security_class_t sclass; ++ ++ const char *range = NULL; ++ ++ assert(socket_fd >= 0); ++ assert(exe); ++ assert(label); ++ ++ r = getcon(&mycon); ++ if (r < 0) { ++ r = -EINVAL; ++ goto out; ++ } ++ ++ r = getpeercon(socket_fd, &peercon); ++ if (r < 0) { ++ r = -EINVAL; ++ goto out; ++ } ++ ++ r = getexeccon(&fcon); ++ if (r < 0) { ++ r = -EINVAL; ++ goto out; ++ } ++ ++ if (!fcon) { ++ /* If there is no context set for next exec let's use context ++ of target executable */ ++ r = getfilecon(exe, &fcon); ++ if (r < 0) { ++ r = -errno; ++ goto out; ++ } ++ } ++ ++ bcon = context_new(mycon); ++ if (!bcon) { ++ r = -ENOMEM; ++ goto out; ++ } ++ ++ pcon = context_new(peercon); ++ if (!pcon) { ++ r = -ENOMEM; ++ goto out; ++ } ++ ++ range = context_range_get(pcon); ++ if (!range) { ++ r = -errno; ++ goto out; ++ } ++ ++ r = context_range_set(bcon, range); ++ if (r) { ++ r = -errno; ++ goto out; ++ } ++ ++ freecon(mycon); ++ mycon = context_str(bcon); ++ if (!mycon) { ++ r = -errno; ++ goto out; ++ } ++ ++ sclass = string_to_security_class("process"); ++ r = security_compute_create(mycon, fcon, sclass, &ret); ++ if (r < 0) { ++ r = -EINVAL; ++ goto out; ++ } ++ ++ *label = ret; ++ r = 0; ++ ++out: ++ if (r < 0 && security_getenforce() == 1) ++ return r; ++#endif ++ return r; ++} ++ + int label_context_set(const char *path, mode_t mode) { + int r = 0; + +diff --git a/src/shared/label.h b/src/shared/label.h +index 09e15e3..d8a281c 100644 +--- a/src/shared/label.h ++++ b/src/shared/label.h +@@ -39,6 +39,8 @@ void label_context_clear(void); + void label_free(const char *label); + + int label_get_create_label_from_exe(const char *exe, char **label); ++int label_get_our_label(char **label); ++int label_get_child_mls_label(int socket_fd, const char *exec, char **label); + + int label_mkdir(const char *path, mode_t mode); + diff --git a/SOURCES/0290-sysctl-make-prefix-allow-all-kinds-of-sysctl-paths.patch b/SOURCES/0290-sysctl-make-prefix-allow-all-kinds-of-sysctl-paths.patch new file mode 100644 index 0000000..943dccf --- /dev/null +++ b/SOURCES/0290-sysctl-make-prefix-allow-all-kinds-of-sysctl-paths.patch @@ -0,0 +1,101 @@ +From 5024f01fec5e6c8fd05ca5451176878084e3f18f Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Wed, 17 Sep 2014 09:06:49 +0200 +Subject: [PATCH] sysctl: make --prefix allow all kinds of sysctl paths + +Currently, we save arguments passed as --prefix directly and compare them +later to absolute sysctl file-system paths. That is, you are required to +specify arguments to --prefix with leading /proc/sys/. This is kinda +uselesss. Furthermore, we replace dots by slashes in the name, which makes +it impossible to match on specific sysfs paths that have dots in their +name (like netdev names). The intention of this argument is clear, but it +never worked as expected. + +This patch modifies --prefix to accept any kind of sysctl paths. It +supports paths prefixed with /proc/sys for compatibility (but drops the +erroneous dot->slash conversion), but instead applies normalize_sysctl() +which turns any name or path into a proper path. It then appends +/proc/sys/ so we can properly use it in matches. + +Thanks to Jan Synacek for catching this! + +Conflicts: + src/sysctl/sysctl.c + +(cherry picked from commit 0e1f579227b08832437a7ac2227c7e4007a89d23) + +Resolves: #1138591 +--- + src/sysctl/sysctl.c | 40 +++++++++++++++++++++++++++++----------- + 1 file changed, 29 insertions(+), 11 deletions(-) + +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index a9d4d53..d6f48dd 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -51,9 +51,23 @@ static const char conf_file_dirs[] = + static char *normalize_sysctl(char *s) { + char *n; + +- for (n = s; *n; n++) ++ n = strpbrk(s, "/."); ++ /* If the first separator is a slash, the path is ++ * assumed to be normalized and slashes remain slashes ++ * and dots remains dots. */ ++ if (!n || *n == '/') ++ return s; ++ ++ /* Otherwise, dots become slashes and slashes become ++ * dots. Fun. */ ++ while (n) { + if (*n == '.') + *n = '/'; ++ else ++ *n = '.'; ++ ++ n = strpbrk(n + 1, "/."); ++ } + + return s; + } +@@ -205,7 +219,7 @@ static int help(void) { + printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" + "Applies kernel sysctl settings.\n\n" + " -h --help Show this help\n" +- " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n", ++ " --prefix=PATH Only apply rules with the specified prefix\n", + program_invocation_short_name); + + return 0; +@@ -238,18 +252,22 @@ static int parse_argv(int argc, char *argv[]) { + + case ARG_PREFIX: { + char *p; +- char **l; + +- for (p = optarg; *p; p++) +- if (*p == '.') +- *p = '/'; +- +- l = strv_append(arg_prefixes, optarg); +- if (!l) ++ /* We used to require people to specify absolute paths ++ * in /proc/sys in the past. This is kinda useless, but ++ * we need to keep compatibility. We now support any ++ * sysctl name available. */ ++ normalize_sysctl(optarg); ++ if (startswith(optarg, "/proc/sys")) ++ p = strdup(optarg); ++ else ++ p = strappend("/proc/sys/", optarg); ++ ++ if (!p) + return log_oom(); + +- strv_free(arg_prefixes); +- arg_prefixes = l; ++ if (strv_push(&arg_prefixes, p) < 0) ++ return log_oom(); + + break; + } diff --git a/SOURCES/0291-core-make-sure-to-serialize-jobs-for-all-units.patch b/SOURCES/0291-core-make-sure-to-serialize-jobs-for-all-units.patch new file mode 100644 index 0000000..b3b713e --- /dev/null +++ b/SOURCES/0291-core-make-sure-to-serialize-jobs-for-all-units.patch @@ -0,0 +1,112 @@ +From bbfce083901a7c7b0ca93297453796c2183a237d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 May 2014 01:15:03 +0200 +Subject: [PATCH] core: make sure to serialize jobs for all units + +Previously we wouldn't serialize jobs for units that themselves have +nothing to serialize. + +http://lists.freedesktop.org/archives/systemd-devel/2014-May/019051.html + +Conflicts: + src/core/unit.c + +(cherry-picked from 9bdb98c59451ed090f8d35d470a54710f389ce71) + +Related: #1138546 +--- + src/core/manager.c | 3 --- + src/core/unit.c | 45 +++++++++++++++++++++------------------------ + 2 files changed, 21 insertions(+), 27 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index a2810b4..4ad26e1 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2169,9 +2169,6 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) { + if (u->id != t) + continue; + +- if (!unit_can_serialize(u)) +- continue; +- + /* Start marker */ + fputs(u->id, f); + fputc('\n', f); +diff --git a/src/core/unit.c b/src/core/unit.c +index 17792d1..855e135 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2296,24 +2296,10 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { + assert(f); + assert(fds); + +- if (!unit_can_serialize(u)) +- return 0; +- +- r = UNIT_VTABLE(u)->serialize(u, f, fds); +- if (r < 0) +- return r; +- +- +- if (serialize_jobs) { +- if (u->job) { +- fprintf(f, "job\n"); +- job_serialize(u->job, f, fds); +- } +- +- if (u->nop_job) { +- fprintf(f, "job\n"); +- job_serialize(u->nop_job, f, fds); +- } ++ if (unit_can_serialize(u)) { ++ r = UNIT_VTABLE(u)->serialize(u, f, fds); ++ if (r < 0) ++ return r; + } + + dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp); +@@ -2330,6 +2316,18 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { + if (u->cgroup_path) + unit_serialize_item(u, f, "cgroup", u->cgroup_path); + ++ if (serialize_jobs) { ++ if (u->job) { ++ fprintf(f, "job\n"); ++ job_serialize(u->job, f, fds); ++ } ++ ++ if (u->nop_job) { ++ fprintf(f, "job\n"); ++ job_serialize(u->nop_job, f, fds); ++ } ++ } ++ + /* End marker */ + fputc('\n', f); + return 0; +@@ -2369,9 +2367,6 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + assert(f); + assert(fds); + +- if (!unit_can_serialize(u)) +- return 0; +- + for (;;) { + char line[LINE_MAX], *l, *v; + size_t k; +@@ -2484,9 +2479,11 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + continue; + } + +- r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds); +- if (r < 0) +- return r; ++ if (unit_can_serialize(u)) { ++ r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds); ++ if (r < 0) ++ return r; ++ } + } + } + diff --git a/SOURCES/0292-man-mention-localectl-in-locale.conf.patch b/SOURCES/0292-man-mention-localectl-in-locale.conf.patch new file mode 100644 index 0000000..7ae99b0 --- /dev/null +++ b/SOURCES/0292-man-mention-localectl-in-locale.conf.patch @@ -0,0 +1,35 @@ +From 6c3574cb20ee440a2293a64ef140dc0d073a93a5 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 18 Sep 2014 14:13:31 +0200 +Subject: [PATCH] man: mention localectl in locale.conf + +rhel-only (in other patch in upstream) + +Resolves: #1049286 +--- + man/locale.conf.xml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/man/locale.conf.xml b/man/locale.conf.xml +index e970921..408f18f 100644 +--- a/man/locale.conf.xml ++++ b/man/locale.conf.xml +@@ -96,6 +96,10 @@ + configuration files might be checked for locale + configuration as well, however only as + fallback. ++ ++ localectl1 ++ may be used to alter the settings in this file during ++ runtime from the command line. + + + +@@ -142,6 +146,7 @@ LC_MESSAGES=en_US.UTF-8 + + systemd1, + locale7, ++ localectl1, + systemd-localed.service8 + + diff --git a/SOURCES/0293-rules-automatically-online-hot-added-CPUs.patch b/SOURCES/0293-rules-automatically-online-hot-added-CPUs.patch new file mode 100644 index 0000000..29beacc --- /dev/null +++ b/SOURCES/0293-rules-automatically-online-hot-added-CPUs.patch @@ -0,0 +1,37 @@ +From fa5a7d49ecbe40e2e33f1d165a4522d9b4315531 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 22 Sep 2014 07:41:06 +0200 +Subject: [PATCH] rules: automatically online hot-added CPUs + +RHEL-only patch + +Resolves: #968811 +--- + Makefile.am | 3 ++- + rules/40-redhat.rules | 3 +++ + 2 files changed, 5 insertions(+), 1 deletion(-) + create mode 100644 rules/40-redhat.rules + +diff --git a/Makefile.am b/Makefile.am +index 30ab13c..54941c0 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -2220,7 +2220,8 @@ dist_udevrules_DATA += \ + rules/75-tty-description.rules \ + rules/78-sound-card.rules \ + rules/80-net-name-slot.rules \ +- rules/95-udev-late.rules ++ rules/95-udev-late.rules \ ++ rules/40-redhat.rules + + dist_udevhwdb_DATA = \ + hwdb/20-pci-vendor-model.hwdb \ +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +new file mode 100644 +index 0000000..2b494e5 +--- /dev/null ++++ b/rules/40-redhat.rules +@@ -0,0 +1,3 @@ ++# do not edit this file, it will be overwritten on update ++ ++SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1" diff --git a/SOURCES/0294-rules-add-rule-for-naming-Dell-iDRAC-USB-Virtual-NIC.patch b/SOURCES/0294-rules-add-rule-for-naming-Dell-iDRAC-USB-Virtual-NIC.patch new file mode 100644 index 0000000..5168276 --- /dev/null +++ b/SOURCES/0294-rules-add-rule-for-naming-Dell-iDRAC-USB-Virtual-NIC.patch @@ -0,0 +1,41 @@ +From eb8c33c65906ba721c6becb4053b8e0b56447aec Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 22 Sep 2014 07:53:52 +0200 +Subject: [PATCH] rules: add rule for naming Dell iDRAC USB Virtual NIC as + 'idrac' + +RHEL-only patch + +Resolves: #1054477 +--- + Makefile.am | 3 ++- + rules/73-idrac.rules | 6 ++++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + create mode 100644 rules/73-idrac.rules + +diff --git a/Makefile.am b/Makefile.am +index 54941c0..d54a556 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -2221,7 +2221,8 @@ dist_udevrules_DATA += \ + rules/78-sound-card.rules \ + rules/80-net-name-slot.rules \ + rules/95-udev-late.rules \ +- rules/40-redhat.rules ++ rules/40-redhat.rules \ ++ rules/73-idrac.rules + + dist_udevhwdb_DATA = \ + hwdb/20-pci-vendor-model.hwdb \ +diff --git a/rules/73-idrac.rules b/rules/73-idrac.rules +new file mode 100644 +index 0000000..d67fc42 +--- /dev/null ++++ b/rules/73-idrac.rules +@@ -0,0 +1,6 @@ ++# do not edit this file, it will be overwritten on update ++ ++# On Dell PowerEdge systems, the iDRAC7 and later support a USB Virtual NIC ++# with terminates in the iDRAC. Help identify this with 'idrac' ++ ++ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", ATTRS{idVendor}=="413c", ATTRS{idProduct}=="a102", NAME="idrac" diff --git a/SOURCES/0295-bash-completion-add-verb-set-property.patch b/SOURCES/0295-bash-completion-add-verb-set-property.patch new file mode 100644 index 0000000..1fbd4e9 --- /dev/null +++ b/SOURCES/0295-bash-completion-add-verb-set-property.patch @@ -0,0 +1,54 @@ +From 233b0373a3d75e277ad5a232a65567395da57f0e Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 23 Sep 2014 14:59:11 +0200 +Subject: [PATCH] bash-completion: add verb set-property + +Resolves: #1064487 +--- + shell-completion/bash/systemctl | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl +index 84149e3..efe8485 100644 +--- a/shell-completion/bash/systemctl ++++ b/shell-completion/bash/systemctl +@@ -25,7 +25,7 @@ __systemctl() { + __systemd_properties() { + local mode=$1 + { __systemctl -a $mode show; +- systemd --dump-configuration-items; } | ++ /usr/lib/systemd/systemd --dump-configuration-items; } | + while IFS='=' read -r key value; do + [[ $value ]] && echo "$key" + done +@@ -77,6 +77,8 @@ _systemctl () { + [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --state --root' + ) + ++ local -A PROPS='CPUAccounting= MemoryAccounting= BlockIOAccounting= MemoryLimit= CPUShares= BlockIOWeight= DevicePolicy= DeviceAllow= BlockIOReadBandwidth= BlockIOWriteBandwidth= BlockIODeviceWeight=' ++ + if __contains_word "--user" ${COMP_WORDS[*]}; then + mode=--user + else +@@ -136,6 +138,7 @@ _systemctl () { + [MASKED_UNITS]='unmask' + [JOBS]='cancel' + [SNAPSHOTS]='delete' ++ [PROPERTIES]='set-property' + [ENVS]='set-environment unset-environment' + [STANDALONE]='daemon-reexec daemon-reload default + emergency exit halt hibernate hybrid-sleep kexec list-jobs +@@ -220,6 +223,13 @@ _systemctl () { + elif __contains_word "$verb" ${VERBS[TARGETS]}; then + comps=$( __systemctl $mode list-unit-files --type target --full --all \ + | { while read -r a b; do echo " $a"; done; } ) ++ elif __contains_word "$verb" ${VERBS[PROPERTIES]}; then ++ if __contains_word "$prev" ${VERBS[PROPERTIES]}; then ++ comps=$( __get_active_units $mode ) ++ else ++ comps=$PROPS ++ compopt -o nospace ++ fi + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) diff --git a/SOURCES/0296-man-update-journald-rate-limit-defaults.patch b/SOURCES/0296-man-update-journald-rate-limit-defaults.patch new file mode 100644 index 0000000..40d490d --- /dev/null +++ b/SOURCES/0296-man-update-journald-rate-limit-defaults.patch @@ -0,0 +1,29 @@ +From e11d039c50d13ac638c2ef77285af3543805a2f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mantas=20Mikul=C4=97nas?= +Date: Wed, 30 Apr 2014 19:53:13 +0300 +Subject: [PATCH] man: update journald rate limit defaults + +This brings the man page back into sync with the actual code. + +(cherry picked from commit 8f18f550e7023948f199616fdfbb0f09711fd615) + +Resolves: #1145352 +--- + man/journald.conf.xml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/man/journald.conf.xml b/man/journald.conf.xml +index b362c5d..87e13b2 100644 +--- a/man/journald.conf.xml ++++ b/man/journald.conf.xml +@@ -190,8 +190,8 @@ + limiting is applied per-service, so + that two services which log do not + interfere with each other's +- limits. Defaults to 200 messages in +- 10s. The time specification for ++ limits. Defaults to 1000 messages in ++ 30s. The time specification for + RateLimitInterval= + may be specified in the following + units: s, diff --git a/SOURCES/0297-core-don-t-try-to-connect-to-d-bus-after-switchroot.patch b/SOURCES/0297-core-don-t-try-to-connect-to-d-bus-after-switchroot.patch new file mode 100644 index 0000000..d585e6b --- /dev/null +++ b/SOURCES/0297-core-don-t-try-to-connect-to-d-bus-after-switchroot.patch @@ -0,0 +1,25 @@ +From 376c59b17a8d90b623533f639c2045276d1009d7 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Wed, 24 Sep 2014 13:20:29 +0200 +Subject: [PATCH] core: don't try to connect to d-bus after switchroot + +rhel-only + +Resolves: #1083300 +--- + src/core/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/main.c b/src/core/main.c +index afd5f6f..d4bf8ba 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1543,7 +1543,7 @@ int main(int argc, char *argv[]) { + if (arg_running_as == SYSTEMD_SYSTEM) + bump_rlimit_nofile(&saved_rlimit_nofile); + +- r = manager_new(arg_running_as, !!serialization, &m); ++ r = manager_new(arg_running_as, !!serialization && !arg_switched_root, &m); + if (r < 0) { + log_error("Failed to allocate manager object: %s", strerror(-r)); + goto finish; diff --git a/SOURCES/0298-localed-log-locale-keymap-changes-in-detail.patch b/SOURCES/0298-localed-log-locale-keymap-changes-in-detail.patch new file mode 100644 index 0000000..d5ed8ac --- /dev/null +++ b/SOURCES/0298-localed-log-locale-keymap-changes-in-detail.patch @@ -0,0 +1,244 @@ +From d522b56345f2fe53a5ccac396c669d8f74088a6b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 3 Sep 2014 22:55:16 -0400 +Subject: [PATCH] localed: log locale/keymap changes in detail + +Converting X11 to legacy keymaps and back is a fucking mess. Let's +make it at least possible to request detailed logs of what is being +changed and why (LOG_DEBUG level). + +At LOG_INFO level, we would log the requested change of X11 or console +keymap, but not the resulting change after conversion to console or X11. +Make sure that every change of configuration on disk has a matching +line in the logs. + +Conflicts: + src/locale/localed.c + +(cherry picked from commit 502f961425f9dea1a85239766a3189695194da63) + +Related: #1109145 +--- + src/locale/localed.c | 84 ++++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 61 insertions(+), 23 deletions(-) + +diff --git a/src/locale/localed.c b/src/locale/localed.c +index a93b309..c22e12d 100644 +--- a/src/locale/localed.c ++++ b/src/locale/localed.c +@@ -337,9 +337,11 @@ static int read_data(void) { + return r < 0 ? r : q < 0 ? q : p; + } + +-static int write_data_locale(void) { ++static int write_data_locale(char ***settings) { + int r, p; +- char **l = NULL; ++ _cleanup_strv_free_ char **l = NULL; ++ ++ /* Set values will be returned as strv in *settings on success. */ + + r = load_env_file("/etc/locale.conf", NULL, &l); + if (r < 0 && r != -ENOENT) +@@ -355,14 +357,12 @@ static int write_data_locale(void) { + continue; + } + +- if (asprintf(&t, "%s=%s", names[p], data[p]) < 0) { +- strv_free(l); ++ if (asprintf(&t, "%s=%s", names[p], data[p]) < 0) + return -ENOMEM; +- } ++ + + u = strv_env_set(l, t); + free(t); +- strv_free(l); + + if (!u) + return -ENOMEM; +@@ -371,8 +371,6 @@ static int write_data_locale(void) { + } + + if (strv_isempty(l)) { +- strv_free(l); +- + if (unlink("/etc/locale.conf") < 0) + return errno == ENOENT ? 0 : -errno; + +@@ -380,7 +378,11 @@ static int write_data_locale(void) { + } + + r = write_env_file_label("/etc/locale.conf", l); +- strv_free(l); ++ if (r < 0) ++ return r; ++ ++ *settings = l; ++ l = NULL; + + return r; + } +@@ -771,6 +773,12 @@ static int convert_vconsole_to_x11(DBusConnection *connection) { + if (r < 0) + log_error("Failed to set X11 keyboard layout: %s", strerror(-r)); + ++ log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'", ++ strempty(state.x11_layout), ++ strempty(state.x11_model), ++ strempty(state.x11_variant), ++ strempty(state.x11_options)); ++ + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", +@@ -787,7 +795,8 @@ static int convert_vconsole_to_x11(DBusConnection *connection) { + + if (!b) + return -ENOMEM; +- } ++ } else ++ log_debug("X11 keyboard layout was not modified."); + + return 0; + } +@@ -805,13 +814,18 @@ static int find_converted_keymap(char **new_keymap) { + + NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) { + _cleanup_free_ char *p = NULL, *pz = NULL; ++ bool uncompressed; + + p = strjoin(dir, "xkb/", n, ".map", NULL); + pz = strjoin(dir, "xkb/", n, ".map.gz", NULL); + if (!p || !pz) + return -ENOMEM; + +- if (access(p, F_OK) == 0 || access(pz, F_OK) == 0) { ++ uncompressed = access(p, F_OK) == 0; ++ if (uncompressed || access(pz, F_OK) == 0) { ++ log_debug("Found converted keymap %s at %s", ++ n, uncompressed ? p : pz); ++ + *new_keymap = n; + n = NULL; + return 1; +@@ -885,13 +899,19 @@ static int find_legacy_keymap(char **new_keymap) { + } + + /* The best matching entry so far, then let's save that */ +- if (matching > best_matching) { +- best_matching = matching; ++ if (matching >= MAX(best_matching, 1u)) { ++ log_debug("Found legacy keymap %s with score %u", ++ a[0], matching); + +- free(*new_keymap); +- *new_keymap = strdup(a[0]); +- if (!*new_keymap) +- return -ENOMEM; ++ if (matching > best_matching) { ++ best_matching = matching; ++ ++ free(*new_keymap); ++ *new_keymap = strdup(a[0]); ++ ++ if (!*new_keymap) ++ return -ENOMEM; ++ } + } + } + +@@ -943,6 +963,9 @@ static int convert_x11_to_vconsole(DBusConnection *connection) { + if (r < 0) + log_error("Failed to set virtual console keymap: %s", strerror(-r)); + ++ log_info("Changed virtual console keymap to '%s' toggle '%s'", ++ strempty(state.vc_keymap), strempty(state.vc_keymap_toggle)); ++ + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", +@@ -959,7 +982,8 @@ static int convert_x11_to_vconsole(DBusConnection *connection) { + return -ENOMEM; + + return load_vconsole_keymap(connection, NULL); +- } ++ } else ++ log_debug("Virtual console keymap was not modified."); + + return 0; + } +@@ -968,6 +992,7 @@ static int append_locale(DBusMessageIter *i, const char *property, void *userdat + int r, c = 0, p; + char **l; + ++ /* Check whether a variable changed and if it is valid */ + l = new0(char*, _PROP_MAX+1); + if (!l) + return -ENOMEM; +@@ -1086,6 +1111,7 @@ static DBusHandlerResult locale_message_handler( + } + + if (modified) { ++ _cleanup_strv_free_ char **settings = NULL; + + r = verify_polkit(connection, message, "org.freedesktop.locale1.set-locale", interactive, NULL, &error); + if (r < 0) { +@@ -1127,7 +1153,7 @@ static DBusHandlerResult locale_message_handler( + + simplify(); + +- r = write_data_locale(); ++ r = write_data_locale(&settings); + if (r < 0) { + log_error("Failed to set locale: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); +@@ -1135,7 +1161,13 @@ static DBusHandlerResult locale_message_handler( + + push_data(connection); + +- log_info("Changed locale information."); ++ if (settings) { ++ _cleanup_free_ char *line; ++ ++ line = strv_join(settings, ", "); ++ log_info("Changed locale to %s.", strnull(line)); ++ } else ++ log_info("Changed locale to unset."); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", +@@ -1143,8 +1175,10 @@ static DBusHandlerResult locale_message_handler( + "Locale\0"); + if (!changed) + goto oom; +- } else ++ } else { ++ log_debug("Locale settings were not modified."); + strv_free(l); ++ } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetVConsoleKeyboard")) { + +@@ -1188,7 +1222,8 @@ static DBusHandlerResult locale_message_handler( + return bus_send_error_reply(connection, message, NULL, r); + } + +- log_info("Changed virtual console keymap to '%s'", strempty(state.vc_keymap)); ++ log_info("Changed virtual console keymap to '%s' toggle '%s'", ++ strempty(state.vc_keymap), strempty(state.vc_keymap_toggle)); + + r = load_vconsole_keymap(connection, NULL); + if (r < 0) +@@ -1266,7 +1301,10 @@ static DBusHandlerResult locale_message_handler( + return bus_send_error_reply(connection, message, NULL, r); + } + +- log_info("Changed X11 keyboard layout to '%s'", strempty(state.x11_layout)); ++ log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'", strempty(state.x11_layout), ++ strempty(state.x11_model), ++ strempty(state.x11_variant), ++ strempty(state.x11_options)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", diff --git a/SOURCES/0299-localed-introduce-helper-function-to-simplify-matchi.patch b/SOURCES/0299-localed-introduce-helper-function-to-simplify-matchi.patch new file mode 100644 index 0000000..2440a08 --- /dev/null +++ b/SOURCES/0299-localed-introduce-helper-function-to-simplify-matchi.patch @@ -0,0 +1,63 @@ +From 31ad188e3cec2909ce0041aa43ca816d0eee6ed1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 3 Sep 2014 22:55:52 -0400 +Subject: [PATCH] localed: introduce helper function to simplify matching + +Conflicts: + src/locale/localed.c + +(cherry picked from commit 81fd105a5f9762fa2f2e42bc949876e32b3a126f) + +Related: #1109145 +--- + src/locale/localed.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/src/locale/localed.c b/src/locale/localed.c +index c22e12d..56900a6 100644 +--- a/src/locale/localed.c ++++ b/src/locale/localed.c +@@ -145,6 +145,12 @@ static int free_and_set(char **s, const char *v) { + return 0; + } + ++static bool startswith_comma(const char *s, const char *prefix) { ++ const char *t; ++ ++ return s && (t = startswith(s, prefix)) && (*t == ','); ++} ++ + static void free_data_locale(void) { + int p; + +@@ -861,26 +867,18 @@ static int find_legacy_keymap(char **new_keymap) { + /* If we got an exact match, this is best */ + matching = 10; + else { +- size_t x; +- +- x = strcspn(state.x11_layout, ","); +- + /* We have multiple X layouts, look for an + * entry that matches our key with everything + * but the first layout stripped off. */ +- if (x > 0 && +- strlen(a[1]) == x && +- strneq(state.x11_layout, a[1], x)) ++ if (startswith_comma(state.x11_layout, a[1])) + matching = 5; + else { +- size_t w; ++ char *x; + + /* If that didn't work, strip off the + * other layouts from the entry, too */ +- w = strcspn(a[1], ","); +- +- if (x > 0 && x == w && +- memcmp(state.x11_layout, a[1], x) == 0) ++ x = strndupa(a[1], strcspn(a[1], ",")); ++ if (startswith_comma(state.x11_layout, x)) + matching = 1; + } + } diff --git a/SOURCES/0300-localed-check-for-partially-matching-converted-keyma.patch b/SOURCES/0300-localed-check-for-partially-matching-converted-keyma.patch new file mode 100644 index 0000000..64bddd1 --- /dev/null +++ b/SOURCES/0300-localed-check-for-partially-matching-converted-keyma.patch @@ -0,0 +1,113 @@ +From 6dd719fad5521a24f6278cf005c250c99292a762 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 3 Sep 2014 22:55:54 -0400 +Subject: [PATCH] localed: check for partially matching converted keymaps + +If a user specifies multiple X11 keymaps, with a (at least the first +one) nonempty variant, and we don't match the whole combo, use +a converted keymap which includes the variant in preference to +the default, variantless, keymap. + +E.g.: We would convert X11 config "layout=fr variant=mac" to "fr-mac", +but "layout=fr,us variant=mac," to "fr", because we don't have a +converted keymap which would match "fr,us", and we don't have a legacy +mapping for "fr,us". This is unexpected, and if we cannot match both, +it is still better to match the primary mapping and use "fr-mac". + +Conflicts: + src/locale/localed.c + +(cherry picked from commit 78bd12a05a9252cf573da28394b23e2b891cbba8) + +Resolves: #1109145 +--- + src/locale/localed.c | 36 ++++++++++++++++++++++++++++-------- + 1 file changed, 28 insertions(+), 8 deletions(-) + +diff --git a/src/locale/localed.c b/src/locale/localed.c +index 56900a6..592fab9 100644 +--- a/src/locale/localed.c ++++ b/src/locale/localed.c +@@ -776,8 +776,10 @@ static int convert_vconsole_to_x11(DBusConnection *connection) { + int r; + + r = write_data_x11(); +- if (r < 0) ++ if (r < 0) { + log_error("Failed to set X11 keyboard layout: %s", strerror(-r)); ++ return r; ++ } + + log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'", + strempty(state.x11_layout), +@@ -807,14 +809,14 @@ static int convert_vconsole_to_x11(DBusConnection *connection) { + return 0; + } + +-static int find_converted_keymap(char **new_keymap) { ++static int find_converted_keymap(const char *x11_layout, const char *x11_variant, char **new_keymap) { + const char *dir; + _cleanup_free_ char *n; + +- if (state.x11_variant) +- n = strjoin(state.x11_layout, "-", state.x11_variant, NULL); ++ if (x11_variant) ++ n = strjoin(x11_layout, "-", x11_variant, NULL); + else +- n = strdup(state.x11_layout); ++ n = strdup(x11_layout); + if (!n) + return -ENOMEM; + +@@ -845,7 +847,7 @@ static int find_legacy_keymap(char **new_keymap) { + _cleanup_fclose_ FILE *f; + unsigned n = 0; + unsigned best_matching = 0; +- ++ int r; + + f = fopen(SYSTEMD_KBD_MODEL_MAP, "re"); + if (!f) +@@ -854,7 +856,6 @@ static int find_legacy_keymap(char **new_keymap) { + for (;;) { + _cleanup_strv_free_ char **a = NULL; + unsigned matching = 0; +- int r; + + r = read_next_mapping(f, &n, &a); + if (r < 0) +@@ -913,6 +914,25 @@ static int find_legacy_keymap(char **new_keymap) { + } + } + ++ if (best_matching < 10 && state.x11_layout) { ++ /* The best match is only the first part of the X11 ++ * keymap. Check if we have a converted map which ++ * matches just the first layout. ++ */ ++ char *l, *v = NULL, *converted; ++ ++ l = strndupa(state.x11_layout, strcspn(state.x11_layout, ",")); ++ if (state.x11_variant) ++ v = strndupa(state.x11_variant, strcspn(state.x11_variant, ",")); ++ r = find_converted_keymap(l, v, &converted); ++ if (r < 0) ++ return r; ++ if (r > 0) { ++ free(*new_keymap); ++ *new_keymap = converted; ++ } ++ } ++ + return 0; + } + +@@ -932,7 +952,7 @@ static int convert_x11_to_vconsole(DBusConnection *connection) { + } else { + char *new_keymap = NULL; + +- r = find_converted_keymap(&new_keymap); ++ r = find_converted_keymap(state.x11_layout, state.x11_variant, &new_keymap); + if (r < 0) + return r; + else if (r == 0) { diff --git a/SOURCES/0301-fileio-make-parse_env_file-return-number-of-parsed-i.patch b/SOURCES/0301-fileio-make-parse_env_file-return-number-of-parsed-i.patch new file mode 100644 index 0000000..97a7897 --- /dev/null +++ b/SOURCES/0301-fileio-make-parse_env_file-return-number-of-parsed-i.patch @@ -0,0 +1,130 @@ +From 3a68febdb636924b941a84e123b6e51e042e1273 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 22 Sep 2014 09:38:38 +0200 +Subject: [PATCH] fileio: make parse_env_file() return number of parsed items + +This commit introduces possibility to call parse_env_file_internal() and hand +over extra argument where we will accumulate how many items were successfully +parsed and pushed by callback. We make use of this in parse_env_file() and +return number of parsed items on success instead of always returning zero. + +As a side-effect this commit should fix bug that locale settings in +/etc/locale.conf are not overriden by options passed via kernel command line. + +Conflicts: + src/shared/fileio.c + +(cherry picked from commit a5f6c30da3ac58081108221bf8a0f6f1d84b33a9) + +Resolves: #1069420 +--- + src/shared/fileio.c | 30 +++++++++++++++++++----------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +diff --git a/src/shared/fileio.c b/src/shared/fileio.c +index 733b320..fbc28bd 100644 +--- a/src/shared/fileio.c ++++ b/src/shared/fileio.c +@@ -180,8 +180,9 @@ static int parse_env_file_internal( + const char *fname, + const char *newline, + int (*push) (const char *filename, unsigned line, +- const char *key, char *value, void *userdata), +- void *userdata) { ++ const char *key, char *value, void *userdata, int *n_pushed), ++ void *userdata, ++ int *n_pushed) { + + _cleanup_free_ char *contents = NULL, *key = NULL; + size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1; +@@ -268,7 +269,7 @@ static int parse_env_file_internal( + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + +- r = push(fname, line, key, value, userdata); ++ r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + goto fail; + +@@ -313,7 +314,7 @@ static int parse_env_file_internal( + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + +- r = push(fname, line, key, value, userdata); ++ r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + goto fail; + +@@ -448,7 +449,7 @@ static int parse_env_file_internal( + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + +- r = push(fname, line, key, value, userdata); ++ r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + goto fail; + } +@@ -461,7 +462,7 @@ fail: + } + + static int parse_env_file_push(const char *filename, unsigned line, +- const char *key, char *value, void *userdata) { ++ const char *key, char *value, void *userdata, int *n_pushed) { + assert(utf8_is_valid(key)); + + if (value && !utf8_is_valid(value)) +@@ -484,6 +485,10 @@ static int parse_env_file_push(const char *filename, unsigned line, + va_end(aq); + free(*v); + *v = value; ++ ++ if (n_pushed) ++ (*n_pushed)++; ++ + return 1; + } + } +@@ -500,20 +505,20 @@ int parse_env_file( + const char *newline, ...) { + + va_list ap; +- int r; ++ int r, n_pushed = 0; + + if (!newline) + newline = NEWLINE; + + va_start(ap, newline); +- r = parse_env_file_internal(fname, newline, parse_env_file_push, &ap); ++ r = parse_env_file_internal(fname, newline, parse_env_file_push, &ap, &n_pushed); + va_end(ap); + +- return r; ++ return r < 0 ? r : n_pushed; + } + + static int load_env_file_push(const char *filename, unsigned line, +- const char *key, char *value, void *userdata) { ++ const char *key, char *value, void *userdata, int *n_pushed) { + assert(utf8_is_valid(key)); + + if (value && !utf8_is_valid(value)) +@@ -534,6 +539,9 @@ static int load_env_file_push(const char *filename, unsigned line, + free(p); + return r; + } ++ ++ if (n_pushed) ++ (*n_pushed)++; + } + + free(value); +@@ -547,7 +555,7 @@ int load_env_file(const char *fname, const char *newline, char ***rl) { + if (!newline) + newline = NEWLINE; + +- r = parse_env_file_internal(fname, newline, load_env_file_push, &m); ++ r = parse_env_file_internal(fname, newline, load_env_file_push, &m, NULL); + if (r < 0) { + strv_free(m); + return r; diff --git a/SOURCES/0302-localectl-print-warning-when-there-are-options-given.patch b/SOURCES/0302-localectl-print-warning-when-there-are-options-given.patch new file mode 100644 index 0000000..78d86bc --- /dev/null +++ b/SOURCES/0302-localectl-print-warning-when-there-are-options-given.patch @@ -0,0 +1,292 @@ +From 7664fb3e7ebba889d52c4e7ba653dbbba9035969 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 24 Sep 2014 13:17:43 +0200 +Subject: [PATCH] localectl: print warning when there are options given on + kernel cmdline + +Conflicts: + src/locale/localectl.c + +(cherry picked from commit a34286684ebb78dd3db0d7f34feb2c121c9d00cc) + +Related: #1069420 +--- + Makefile.am | 2 ++ + src/core/locale-setup.c | 47 +++++--------------------------------------- + src/locale/localectl.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ + src/shared/locale-util.c | 42 +++++++++++++++++++++++++++++++++++++++ + src/shared/locale-util.h | 47 ++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 147 insertions(+), 42 deletions(-) + create mode 100644 src/shared/locale-util.c + create mode 100644 src/shared/locale-util.h + +diff --git a/Makefile.am b/Makefile.am +index d54a556..dab55ba 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -656,6 +656,8 @@ libsystemd_shared_la_SOURCES = \ + src/shared/path-util.h \ + src/shared/time-util.c \ + src/shared/time-util.h \ ++ src/shared/locale-util.c \ ++ src/shared/locale-util.h \ + src/shared/hashmap.c \ + src/shared/hashmap.h \ + src/shared/set.c \ +diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c +index 276deb9..69e9bca 100644 +--- a/src/core/locale-setup.c ++++ b/src/core/locale-setup.c +@@ -30,48 +30,11 @@ + #include "fileio.h" + #include "strv.h" + #include "env-util.h" +- +-enum { +- /* We don't list LC_ALL here on purpose. People should be +- * using LANG instead. */ +- +- VARIABLE_LANG, +- VARIABLE_LANGUAGE, +- VARIABLE_LC_CTYPE, +- VARIABLE_LC_NUMERIC, +- VARIABLE_LC_TIME, +- VARIABLE_LC_COLLATE, +- VARIABLE_LC_MONETARY, +- VARIABLE_LC_MESSAGES, +- VARIABLE_LC_PAPER, +- VARIABLE_LC_NAME, +- VARIABLE_LC_ADDRESS, +- VARIABLE_LC_TELEPHONE, +- VARIABLE_LC_MEASUREMENT, +- VARIABLE_LC_IDENTIFICATION, +- _VARIABLE_MAX +-}; +- +-static const char * const variable_names[_VARIABLE_MAX] = { +- [VARIABLE_LANG] = "LANG", +- [VARIABLE_LANGUAGE] = "LANGUAGE", +- [VARIABLE_LC_CTYPE] = "LC_CTYPE", +- [VARIABLE_LC_NUMERIC] = "LC_NUMERIC", +- [VARIABLE_LC_TIME] = "LC_TIME", +- [VARIABLE_LC_COLLATE] = "LC_COLLATE", +- [VARIABLE_LC_MONETARY] = "LC_MONETARY", +- [VARIABLE_LC_MESSAGES] = "LC_MESSAGES", +- [VARIABLE_LC_PAPER] = "LC_PAPER", +- [VARIABLE_LC_NAME] = "LC_NAME", +- [VARIABLE_LC_ADDRESS] = "LC_ADDRESS", +- [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE", +- [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT", +- [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION" +-}; ++#include "locale-util.h" + + int locale_setup(char ***environment) { + char **add; +- char *variables[_VARIABLE_MAX] = {}; ++ char *variables[_VARIABLE_LC_MAX] = {}; + int r = 0, i; + + if (detect_container(NULL) <= 0) { +@@ -121,13 +84,13 @@ int locale_setup(char ***environment) { + } + + add = NULL; +- for (i = 0; i < _VARIABLE_MAX; i++) { ++ for (i = 0; i < _VARIABLE_LC_MAX; i++) { + char *s; + + if (!variables[i]) + continue; + +- s = strjoin(variable_names[i], "=", variables[i], NULL); ++ s = strjoin(locale_variable_to_string(i), "=", variables[i], NULL); + if (!s) { + r = -ENOMEM; + goto finish; +@@ -158,7 +121,7 @@ int locale_setup(char ***environment) { + finish: + strv_free(add); + +- for (i = 0; i < _VARIABLE_MAX; i++) ++ for (i = 0; i < _VARIABLE_LC_MAX; i++) + free(variables[i]); + + return r; +diff --git a/src/locale/localectl.c b/src/locale/localectl.c +index d3c6152..fdef3a0 100644 +--- a/src/locale/localectl.c ++++ b/src/locale/localectl.c +@@ -39,6 +39,9 @@ + #include "path-util.h" + #include "utf8.h" + #include "def.h" ++#include "virt.h" ++#include "fileio.h" ++#include "locale-util.h" + + static bool arg_no_pager = false; + static enum transport { +@@ -79,6 +82,53 @@ typedef struct StatusInfo { + const char *x11_options; + } StatusInfo; + ++static void print_overriden_variables(void) { ++ int r; ++ char *variables[_VARIABLE_LC_MAX] = {}; ++ LocaleVariable j; ++ bool print_warning = true; ++ ++ if (detect_container(NULL) > 0 || arg_host) ++ return; ++ ++ r = parse_env_file("/proc/cmdline", WHITESPACE, ++ "locale.LANG", &variables[VARIABLE_LANG], ++ "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], ++ "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); ++ ++ if (r < 0 && r != -ENOENT) { ++ log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); ++ goto finish; ++ } ++ ++ for (j = VARIABLE_LANG; j < _VARIABLE_LC_MAX; j++) ++ if (variables[j]) { ++ if (print_warning) { ++ printf("Warning: Settings on Kernel Command Line override system locale settings in /etc/locale.conf\n"); ++ printf(" Command Line: %s=%s\n", locale_variable_to_string(j), variables[j]); ++ ++ print_warning = false; ++ continue; ++ } ++ printf(" %s=%s\n", locale_variable_to_string(j), variables[j]); ++ } ++ finish: ++ for (j = VARIABLE_LANG; j < _VARIABLE_LC_MAX; j++) ++ free(variables[j]); ++} ++ + static void print_status_info(StatusInfo *i) { + assert(i); + +@@ -218,6 +268,7 @@ static int show_status(DBusConnection *bus, char **args, unsigned n) { + dbus_message_iter_next(&sub); + } + ++ print_overriden_variables(); + print_status_info(&info); + strv_free(info.locale); + return 0; +diff --git a/src/shared/locale-util.c b/src/shared/locale-util.c +new file mode 100644 +index 0000000..d53b16c +--- /dev/null ++++ b/src/shared/locale-util.c +@@ -0,0 +1,42 @@ ++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ ++ ++/*** ++ This file is part of systemd. ++ ++ Copyright 2014 Lennart Poettering ++ ++ systemd is free software; you can redistribute it and/or modify it ++ under the terms of the GNU Lesser General Public License as published by ++ the Free Software Foundation; either version 2.1 of the License, or ++ (at your option) any later version. ++ ++ systemd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with systemd; If not, see . ++***/ ++ ++#include "util.h" ++#include "locale-util.h" ++ ++static const char * const locale_variable_table[_VARIABLE_LC_MAX] = { ++ [VARIABLE_LANG] = "LANG", ++ [VARIABLE_LANGUAGE] = "LANGUAGE", ++ [VARIABLE_LC_CTYPE] = "LC_CTYPE", ++ [VARIABLE_LC_NUMERIC] = "LC_NUMERIC", ++ [VARIABLE_LC_TIME] = "LC_TIME", ++ [VARIABLE_LC_COLLATE] = "LC_COLLATE", ++ [VARIABLE_LC_MONETARY] = "LC_MONETARY", ++ [VARIABLE_LC_MESSAGES] = "LC_MESSAGES", ++ [VARIABLE_LC_PAPER] = "LC_PAPER", ++ [VARIABLE_LC_NAME] = "LC_NAME", ++ [VARIABLE_LC_ADDRESS] = "LC_ADDRESS", ++ [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE", ++ [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT", ++ [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION" ++}; ++ ++DEFINE_STRING_TABLE_LOOKUP(locale_variable, LocaleVariable); +diff --git a/src/shared/locale-util.h b/src/shared/locale-util.h +new file mode 100644 +index 0000000..420a89d +--- /dev/null ++++ b/src/shared/locale-util.h +@@ -0,0 +1,47 @@ ++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ ++ ++/*** ++ This file is part of systemd. ++ ++ Copyright 2014 Lennart Poettering ++ ++ systemd is free software; you can redistribute it and/or modify it ++ under the terms of the GNU Lesser General Public License as published by ++ the Free Software Foundation; either version 2.1 of the License, or ++ (at your option) any later version. ++ ++ systemd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with systemd; If not, see . ++***/ ++ ++#include "util.h" ++ ++typedef enum LocaleVariable { ++ /* We don't list LC_ALL here on purpose. People should be ++ * using LANG instead. */ ++ ++ VARIABLE_LANG, ++ VARIABLE_LANGUAGE, ++ VARIABLE_LC_CTYPE, ++ VARIABLE_LC_NUMERIC, ++ VARIABLE_LC_TIME, ++ VARIABLE_LC_COLLATE, ++ VARIABLE_LC_MONETARY, ++ VARIABLE_LC_MESSAGES, ++ VARIABLE_LC_PAPER, ++ VARIABLE_LC_NAME, ++ VARIABLE_LC_ADDRESS, ++ VARIABLE_LC_TELEPHONE, ++ VARIABLE_LC_MEASUREMENT, ++ VARIABLE_LC_IDENTIFICATION, ++ _VARIABLE_LC_MAX, ++ _VARIABLE_LC_INVALID = -1 ++} LocaleVariable; ++ ++const char* locale_variable_to_string(LocaleVariable i) _const_; ++LocaleVariable locale_variable_from_string(const char *s) _pure_; diff --git a/SOURCES/0303-dbus-fix-crash-when-appending-selinux-context.patch b/SOURCES/0303-dbus-fix-crash-when-appending-selinux-context.patch new file mode 100644 index 0000000..9aff9d2 --- /dev/null +++ b/SOURCES/0303-dbus-fix-crash-when-appending-selinux-context.patch @@ -0,0 +1,43 @@ +From 48a85bb45ff9d3ee302594ac41d102fa16b31350 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Sat, 27 Sep 2014 20:40:11 +0200 +Subject: [PATCH] dbus: fix crash when appending selinux context + +RHEL-only + +Related: #1113790 +--- + src/core/dbus-execute.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 8162f1c..ae65be1 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -376,6 +376,7 @@ static int bus_execute_append_selinux_context(DBusMessageIter *i, const char *pr + ExecContext *c = data; + dbus_bool_t selinux_context_ignore; + const char *selinux_context = NULL; ++ DBusMessageIter sub; + + assert(i); + assert(property); +@@ -387,10 +388,16 @@ static int bus_execute_append_selinux_context(DBusMessageIter *i, const char *pr + + selinux_context_ignore = c->selinux_context_ignore; + +- if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &selinux_context_ignore)) ++ if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) ++ return -ENOMEM; ++ ++ if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &selinux_context_ignore)) + return -ENOMEM; + +- if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &selinux_context)) ++ if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &selinux_context)) ++ return -ENOMEM; ++ ++ if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; diff --git a/SOURCES/0304-tmpfiles-minor-modernizations.patch b/SOURCES/0304-tmpfiles-minor-modernizations.patch new file mode 100644 index 0000000..29e507e --- /dev/null +++ b/SOURCES/0304-tmpfiles-minor-modernizations.patch @@ -0,0 +1,66 @@ +From 50720580bc5333e594032b124a9a1114e66dc7ae Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 12 Jun 2014 23:07:17 +0200 +Subject: [PATCH] tmpfiles: minor modernizations + +(cherry-picked from 753615e85d990077c303ae4a42a53e792ffb12ca) + +Resolves: #1147524 +--- + src/tmpfiles/tmpfiles.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index ff51062..df6c99a 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -990,7 +990,9 @@ static int process_item(Item *i) { + } + + static void item_free(Item *i) { +- assert(i); ++ ++ if (!i) ++ return; + + free(i->path); + free(i->argument); +@@ -1122,7 +1124,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { + } + } + +- switch(type) { ++ switch (type) { + + case CREATE_FILE: + case TRUNCATE_FILE: +@@ -1171,7 +1173,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { + } + + default: +- log_error("[%s:%u] Unknown file type '%c'.", fname, line, type); ++ log_error("[%s:%u] Unknown command type '%c'.", fname, line, type); + return -EBADMSG; + } + +@@ -1355,9 +1357,11 @@ static int parse_argv(int argc, char *argv[]) { + break; + + case ARG_ROOT: ++ free(arg_root); + arg_root = path_make_absolute_cwd(optarg); + if (!arg_root) + return log_oom(); ++ + path_kill_slashes(arg_root); + break; + +@@ -1456,7 +1460,7 @@ int main(int argc, char *argv[]) { + + r = parse_argv(argc, argv); + if (r <= 0) +- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; ++ goto finish; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); diff --git a/SOURCES/0305-install-when-looking-for-a-unit-file-for-enabling-se.patch b/SOURCES/0305-install-when-looking-for-a-unit-file-for-enabling-se.patch new file mode 100644 index 0000000..c00ae0c --- /dev/null +++ b/SOURCES/0305-install-when-looking-for-a-unit-file-for-enabling-se.patch @@ -0,0 +1,126 @@ +From f73a446c8a1db5c255e6cf1bf6c5d68fe6448f10 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 17 Jun 2014 00:13:48 +0200 +Subject: [PATCH] install: when looking for a unit file for enabling, search + for templates only after traversing all search directories + +Let's always make sure to look in all search directories for the full +unit names first, before looking for templates for them. + +(cherry-picked from e50bd775163cd96be1888943a8785a436be710e8) + +Resolves: #1147524 +--- + src/shared/install.c | 74 +++++++++++++++++++++++++++------------------------- + 1 file changed, 38 insertions(+), 36 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 2c8f907..dc8842b 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1074,67 +1074,69 @@ static int unit_file_search( + assert(paths); + + if (info->path) { +- char *full_path = NULL; ++ const char *path; + +- if (!isempty(root_dir)) +- full_path = strappenda(root_dir, info->path); ++ if (isempty(root_dir)) ++ path = info->path; ++ else ++ path = strappenda(root_dir, info->path); + +- return unit_file_load(c, info, full_path ?: info->path, allow_symlink); ++ return unit_file_load(c, info, path, allow_symlink); + } + + assert(info->name); + + STRV_FOREACH(p, paths->unit_path) { +- _cleanup_free_ char *path = NULL, *full_path = NULL; ++ _cleanup_free_ char *path = NULL; + +- path = strjoin(*p, "/", info->name, NULL); ++ if (isempty(root_dir)) ++ path = strjoin(*p, "/", info->name, NULL); ++ else ++ path = strjoin(root_dir, "/", *p, "/", info->name, NULL); + if (!path) + return -ENOMEM; + +- if (!isempty(root_dir)) { +- full_path = strappend(root_dir, path); +- if (!full_path) +- return -ENOMEM; +- } +- +- r = unit_file_load(c, info, full_path ?: path, allow_symlink); ++ r = unit_file_load(c, info, path, allow_symlink); + if (r >= 0) { + info->path = path; + path = NULL; +- } else if (r == -ENOENT && unit_name_is_instance(info->name)) { +- /* Unit file doesn't exist, however instance enablement was requested. +- * We will check if it is possible to load template unit file. */ +- _cleanup_free_ char *template = NULL, *template_dir = NULL; ++ return r; ++ } ++ if (r != -ENOENT && r != -ELOOP) ++ return r; ++ } + +- template = unit_name_template(info->name); +- if (!template) +- return -ENOMEM; ++ if (unit_name_is_instance(info->name)) { + +- /* We will reuse path variable since we don't need it anymore. */ +- template_dir = path; +- *(strrchr(template_dir, '/') + 1) = '\0'; ++ /* Unit file doesn't exist, however instance ++ * enablement was requested. We will check if it is ++ * possible to load template unit file. */ + +- path = strappend(template_dir, template); ++ _cleanup_free_ char *template = NULL, *template_dir = NULL; ++ ++ template = unit_name_template(info->name); ++ if (!template) ++ return -ENOMEM; ++ ++ STRV_FOREACH(p, paths->unit_path) { ++ _cleanup_free_ char *path = NULL; ++ ++ if (isempty(root_dir)) ++ path = strjoin(*p, "/", template, NULL); ++ else ++ path = strjoin(root_dir, "/", *p, "/", template, NULL); + if (!path) + return -ENOMEM; + +- if (!isempty(root_dir)) { +- free(full_path); +- full_path = strappend(root_dir, path); +- if (!full_path) +- return -ENOMEM; +- } +- +- /* Let's try to load template unit. */ +- r = unit_file_load(c, info, full_path ?: path, allow_symlink); ++ r = unit_file_load(c, info, path, allow_symlink); + if (r >= 0) { + info->path = path; + path = NULL; ++ return r; + } ++ if (r != -ENOENT && r != -ELOOP) ++ return r; + } +- +- if (r != -ENOENT && r != -ELOOP) +- return r; + } + + return -ENOENT; diff --git a/SOURCES/0306-install-remove-unused-variable.patch b/SOURCES/0306-install-remove-unused-variable.patch new file mode 100644 index 0000000..cfde10e --- /dev/null +++ b/SOURCES/0306-install-remove-unused-variable.patch @@ -0,0 +1,25 @@ +From 9d05d80b64a04e2bf9a61d992b7bd22b23949d1e Mon Sep 17 00:00:00 2001 +From: Thomas Hindoe Paaboel Andersen +Date: Tue, 17 Jun 2014 21:22:01 +0200 +Subject: [PATCH] install: remove unused variable + +(cherry-picked from de228aabc833901e7c75aab8d62e58229e2a8bfc) + +Resolves: #1147524 +--- + src/shared/install.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index dc8842b..dd5e22b 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1112,7 +1112,7 @@ static int unit_file_search( + * enablement was requested. We will check if it is + * possible to load template unit file. */ + +- _cleanup_free_ char *template = NULL, *template_dir = NULL; ++ _cleanup_free_ char *template = NULL; + + template = unit_name_template(info->name); + if (!template) diff --git a/SOURCES/0307-bootctl-typo-fix-in-help-message.patch b/SOURCES/0307-bootctl-typo-fix-in-help-message.patch new file mode 100644 index 0000000..909d4aa --- /dev/null +++ b/SOURCES/0307-bootctl-typo-fix-in-help-message.patch @@ -0,0 +1,25 @@ +From 5f9893fe56014642bbdb2d15eb829e3447dac265 Mon Sep 17 00:00:00 2001 +From: Thomas Hindoe Paaboel Andersen +Date: Wed, 6 Nov 2013 00:29:49 +0100 +Subject: [PATCH] bootctl: typo fix in help message + +(cherry-picked from 82de16f92ca5259e9ddb4f328f086cb6a9f043b0) + +Resolves: #1147524 +--- + src/boot/bootctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c +index af694fd..d25ddef 100644 +--- a/src/boot/bootctl.c ++++ b/src/boot/bootctl.c +@@ -34,7 +34,7 @@ + + static int help(void) { + printf("%s [OPTIONS...] COMMAND ...\n\n" +- "Query or change firmware and boot mananger settings.\n\n" ++ "Query or change firmware and boot manager settings.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + "Commands:\n" diff --git a/SOURCES/0308-logind-ignore-failing-close-on-session-devices.patch b/SOURCES/0308-logind-ignore-failing-close-on-session-devices.patch new file mode 100644 index 0000000..683440f --- /dev/null +++ b/SOURCES/0308-logind-ignore-failing-close-on-session-devices.patch @@ -0,0 +1,59 @@ +From b1c42aa11792c00cf359bec452022b73cbe2c79d Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Thu, 28 Nov 2013 14:51:40 +0100 +Subject: [PATCH] logind: ignore failing close() on session-devices + +Unfortunately, close() on a revoked/removed character-device fails with +ENODEV. I tried tracking this down in the kernel, but couldn't figure out +were exactly it comes from. However, can be easily reproduced with: + fd = open("/dev/input/event0", O_RDWR); + ioctl(fd, EVIOCREVOKE, 0); + r = close(fd); +A second close on @fd would return EBADF so the close is actually valid. + +We simply ignore close() errors for all session-devices as their access +may be revoked asynchronously, or the device might get unplugged. +We use close_nointr() in case anyone ever looks at the return value (or +anyone runs "grep 'close(' -r src/" to find broken close() calls). + +Fixes: + systemd-logind[31992]: Assertion 'close_nointr(fd) == 0' failed at src/shared/util.c:185, function close_nointr_nofail(). Aborting. + +(cherry-picked from d1107170f9e0fa2cb6e8d18586a003f0d96abfc3) + +Resolves: #1147524 +--- + src/login/logind-session-device.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c +index 6605935..fd02b43 100644 +--- a/src/login/logind-session-device.c ++++ b/src/login/logind-session-device.c +@@ -162,7 +162,7 @@ static int session_device_open(SessionDevice *sd, bool active) { + * state. */ + r = sd_drmsetmaster(fd); + if (r < 0) { +- close(fd); ++ close_nointr(fd); + return r; + } + } else { +@@ -209,7 +209,7 @@ static int session_device_start(SessionDevice *sd) { + r = session_device_open(sd, true); + if (r < 0) + return r; +- close_nointr_nofail(sd->fd); ++ close_nointr(sd->fd); + sd->fd = r; + break; + case DEVICE_TYPE_UNKNOWN: +@@ -407,7 +407,7 @@ void session_device_free(SessionDevice *sd) { + + session_device_stop(sd); + session_device_notify(sd, SESSION_DEVICE_RELEASE); +- close_nointr_nofail(sd->fd); ++ close_nointr(sd->fd); + + LIST_REMOVE(SessionDevice, sd_by_device, sd->device->session_devices, sd); + diff --git a/SOURCES/0309-sysfs-show.c-return-negative-error.patch b/SOURCES/0309-sysfs-show.c-return-negative-error.patch new file mode 100644 index 0000000..eeafc02 --- /dev/null +++ b/SOURCES/0309-sysfs-show.c-return-negative-error.patch @@ -0,0 +1,27 @@ +From 8d5952a7659d735958119b64d05ceab34be9e454 Mon Sep 17 00:00:00 2001 +From: Thomas Hindoe Paaboel Andersen +Date: Sat, 30 Nov 2013 21:59:40 +0100 +Subject: [PATCH] sysfs-show.c: return negative error + +introduced in 1ca208fb4f93e5869704af1812cbff7130a2fc03 + +(cherry-picked from a051da35ce96923e31a532c86a530bfd40d5dc76) + +Resolves: #1147524 +--- + src/login/sysfs-show.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c +index 9fc3054..cb12ebf 100644 +--- a/src/login/sysfs-show.c ++++ b/src/login/sysfs-show.c +@@ -164,7 +164,7 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { + + e = udev_enumerate_new(udev); + if (!e) +- return ENOMEM; ++ return -ENOMEM; + + if (!streq(seat, "seat0")) + r = udev_enumerate_add_match_tag(e, seat); diff --git a/SOURCES/0310-core-only-send-SIGHUP-when-doing-first-kill-not-when.patch b/SOURCES/0310-core-only-send-SIGHUP-when-doing-first-kill-not-when.patch new file mode 100644 index 0000000..b5cdad2 --- /dev/null +++ b/SOURCES/0310-core-only-send-SIGHUP-when-doing-first-kill-not-when.patch @@ -0,0 +1,61 @@ +From 2f960b84dad97c50c819f2c11812fe6f302ec2ca Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 6 Feb 2014 01:50:41 +0100 +Subject: [PATCH] core: only send SIGHUP when doing first kill, not when doing + final sigkill + +Conflicts: + src/core/unit.c + +(cherry-picked from 97e0691f85da6e7ea131ce80bd61e2d47a737a61) + +Resolves: #1147524 +--- + src/core/unit.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 855e135..fe1864a 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -3113,7 +3113,7 @@ int unit_kill_context( + } else { + wait_for_exit = !main_pid_alien; + +- if (c->send_sighup) ++ if (c->send_sighup && !sigkill) + kill(main_pid, SIGHUP); + } + } +@@ -3131,7 +3131,7 @@ int unit_kill_context( + } else { + wait_for_exit = true; + +- if (c->send_sighup) ++ if (c->send_sighup && !sigkill) + kill(control_pid, SIGHUP); + } + } +@@ -3149,8 +3149,20 @@ int unit_kill_context( + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) { +- wait_for_exit = true; +- if (c->send_sighup) { ++ ++ /* FIXME: Now, we don't actually wait for any ++ * of the processes that are neither control ++ * nor main process. We should wait for them ++ * of course, but that's hard since the cgroup ++ * notification logic is so unreliable. It is ++ * not available at all in containers, and on ++ * the host it gets confused by ++ * subgroups. Hence, for now, let's not wait ++ * for these processes -- but when the kernel ++ * gets fixed we really should correct ++ * that. */ ++ ++ if (c->send_sighup && !sigkill) { + set_free(pid_set); + + pid_set = unit_pid_set(main_pid, control_pid); diff --git a/SOURCES/0311-cgroup-make-sure-to-properly-send-SIGCONT-to-all-pro.patch b/SOURCES/0311-cgroup-make-sure-to-properly-send-SIGCONT-to-all-pro.patch new file mode 100644 index 0000000..f07310d --- /dev/null +++ b/SOURCES/0311-cgroup-make-sure-to-properly-send-SIGCONT-to-all-pro.patch @@ -0,0 +1,33 @@ +From 0c5ef7a5535c4b3aebfc61793c28919f696d5e99 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 6 Feb 2014 19:27:59 +0100 +Subject: [PATCH] cgroup: make sure to properly send SIGCONT to all processes + of a cgroup if that's requested + +(cherry-picked from 6e8314c420eb375847c9e526745c2caec802399d) + +Resolves: #1147524 +--- + src/shared/cgroup-util.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c +index 8a4edda..b58d8b8 100644 +--- a/src/shared/cgroup-util.c ++++ b/src/shared/cgroup-util.c +@@ -194,12 +194,12 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo + if (kill(pid, sig) < 0) { + if (ret >= 0 && errno != ESRCH) + ret = -errno; +- } else if (ret == 0) { +- ++ } else { + if (sigcont) + kill(pid, SIGCONT); + +- ret = 1; ++ if (ret == 0) ++ ret = 1; + } + + done = false; diff --git a/SOURCES/0312-core-don-t-send-duplicate-SIGCONT-when-killing-units.patch b/SOURCES/0312-core-don-t-send-duplicate-SIGCONT-when-killing-units.patch new file mode 100644 index 0000000..a0134d0 --- /dev/null +++ b/SOURCES/0312-core-don-t-send-duplicate-SIGCONT-when-killing-units.patch @@ -0,0 +1,25 @@ +From 1368259de25f91b0130fcf9a8dd1623b3354ba10 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 6 Feb 2014 19:46:46 +0100 +Subject: [PATCH] core: don't send duplicate SIGCONT when killing units + +(cherry-picked from 8190da36f71a887945297cd65d6426c78b466a50) + +Resolves: #1147524 +--- + src/core/unit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index fe1864a..87a6385 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -3169,7 +3169,7 @@ int unit_kill_context( + if (!pid_set) + return -ENOMEM; + +- cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, true, true, false, pid_set); ++ cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, false, true, false, pid_set); + } + } + } diff --git a/SOURCES/0313-efi-fix-Undefined-reference-efi_loader_get_boot_usec.patch b/SOURCES/0313-efi-fix-Undefined-reference-efi_loader_get_boot_usec.patch new file mode 100644 index 0000000..ea63c99 --- /dev/null +++ b/SOURCES/0313-efi-fix-Undefined-reference-efi_loader_get_boot_usec.patch @@ -0,0 +1,28 @@ +From d19e3171725a0afd00c094e8d2b9012309b91f21 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= +Date: Tue, 11 Feb 2014 09:54:49 -0300 +Subject: [PATCH] efi: fix Undefined reference efi_loader_get_boot_usec when + EFI support is disabled + +(cherry-picked from 70d9b9fc0a4fa1698ff00e364c61bb875244efa1) + +Resolves: #1147524 +--- + src/shared/boot-timestamps.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/shared/boot-timestamps.c b/src/shared/boot-timestamps.c +index 9449965..d656685 100644 +--- a/src/shared/boot-timestamps.c ++++ b/src/shared/boot-timestamps.c +@@ -40,8 +40,10 @@ int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_time + + r = acpi_get_boot_usec(&x, &y); + if (r < 0) { ++#ifdef ENABLE_EFI + r = efi_loader_get_boot_usec(&x, &y); + if (r < 0) ++#endif + return r; + } + diff --git a/SOURCES/0314-macro-better-make-IN_SET-macro-use-const-arrays.patch b/SOURCES/0314-macro-better-make-IN_SET-macro-use-const-arrays.patch new file mode 100644 index 0000000..ef19db1 --- /dev/null +++ b/SOURCES/0314-macro-better-make-IN_SET-macro-use-const-arrays.patch @@ -0,0 +1,38 @@ +From 87eaadf84215ef31e453d26c4935f82ec7ab1ef0 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 3 Dec 2013 16:41:06 +0100 +Subject: [PATCH] macro: better make IN_SET() macro use const arrays + +Conflicts: + src/shared/macro.h + +(cherry-picked from 059d9fbb) + +Resolves: #1147524 +--- + src/shared/macro.h | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/shared/macro.h b/src/shared/macro.h +index d4f92b6..27a02d4 100644 +--- a/src/shared/macro.h ++++ b/src/shared/macro.h +@@ -287,4 +287,18 @@ do { \ + #define SET_FLAG(v, flag, b) \ + (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag)) + ++#define IN_SET(x, ...) \ ++ ({ \ ++ const typeof(x) _x = (x); \ ++ unsigned _i; \ ++ bool _found = false; \ ++ for (_i = 0; _i < sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \ ++ if (((const typeof(_x)[]) { __VA_ARGS__ })[_i] == _x) { \ ++ _found = true; \ ++ break; \ ++ } \ ++ _found; \ ++ }) ++ ++ + #include "log.h" diff --git a/SOURCES/0315-macro-make-sure-we-can-use-IN_SET-also-with-complex-.patch b/SOURCES/0315-macro-make-sure-we-can-use-IN_SET-also-with-complex-.patch new file mode 100644 index 0000000..9cd02cc --- /dev/null +++ b/SOURCES/0315-macro-make-sure-we-can-use-IN_SET-also-with-complex-.patch @@ -0,0 +1,49 @@ +From 28a4b5dd0895ba41d1327dcaf824f8adffea73f7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 12 Mar 2014 22:26:22 +0100 +Subject: [PATCH] macro: make sure we can use IN_SET() also with complex + function calls as first argument + +(cherry-picked from dc36d78e) + +Resolves: #1147524 +--- + src/shared/macro.h | 9 +++++---- + src/test/test-util.c | 1 - + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/shared/macro.h b/src/shared/macro.h +index 27a02d4..21039eb 100644 +--- a/src/shared/macro.h ++++ b/src/shared/macro.h +@@ -287,13 +287,14 @@ do { \ + #define SET_FLAG(v, flag, b) \ + (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag)) + +-#define IN_SET(x, ...) \ ++#define IN_SET(x, y, ...) \ + ({ \ +- const typeof(x) _x = (x); \ ++ const typeof(y) _y = (y); \ ++ const typeof(_y) _x = (x); \ + unsigned _i; \ + bool _found = false; \ +- for (_i = 0; _i < sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \ +- if (((const typeof(_x)[]) { __VA_ARGS__ })[_i] == _x) { \ ++ for (_i = 0; _i < 1 + sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \ ++ if (((const typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \ + _found = true; \ + break; \ + } \ +diff --git a/src/test/test-util.c b/src/test/test-util.c +index c5762ed..8527f13 100644 +--- a/src/test/test-util.c ++++ b/src/test/test-util.c +@@ -571,7 +571,6 @@ static void test_fstab_node_to_udev_node(void) { + assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535")); + free(n); + +- + n = fstab_node_to_udev_node("PONIES=awesome"); + puts(n); + assert_se(streq(n, "PONIES=awesome")); diff --git a/SOURCES/0316-core-fix-property-changes-in-transient-units.patch b/SOURCES/0316-core-fix-property-changes-in-transient-units.patch new file mode 100644 index 0000000..e1a7765 --- /dev/null +++ b/SOURCES/0316-core-fix-property-changes-in-transient-units.patch @@ -0,0 +1,93 @@ +From e091fcc1cc628b9e2192104c47e2be103bc8577a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 17 Feb 2014 01:58:33 +0100 +Subject: [PATCH] core: fix property changes in transient units + +(cherry-picked from 6d2357247b198314d972932415d65a42f83a9b6e) + +Resolves: #1147524 +--- + src/core/dbus-unit.c | 3 --- + src/core/unit.c | 13 ++++++------- + 2 files changed, 6 insertions(+), 10 deletions(-) + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index 2ea59b2..a185f5c 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -962,9 +962,6 @@ int bus_unit_set_properties( + assert(u); + assert(iter); + +- if (u->transient) +- mode &= UNIT_RUNTIME; +- + /* We iterate through the array twice. First run we just check + * if all passed data is valid, second run actually applies + * it. This is to implement transaction-like behaviour without +diff --git a/src/core/unit.c b/src/core/unit.c +index 87a6385..e56971b 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2904,7 +2904,6 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c + assert(name); + assert(_p); + assert(_q); +- assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)); + + b = xescape(name, "/."); + if (!b) +@@ -2923,7 +2922,7 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c + return -ENOENT; + + p = strjoin(c, "/", u->id, ".d", NULL); +- } else if (mode & UNIT_PERSISTENT) ++ } else if (mode == UNIT_PERSISTENT && !u->transient) + p = strjoin("/etc/systemd/system/", u->id, ".d", NULL); + else + p = strjoin("/run/systemd/system/", u->id, ".d", NULL); +@@ -2949,7 +2948,7 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co + assert(name); + assert(data); + +- if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) ++ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) + return 0; + + r = drop_in_file(u, mode, name, &p, &q); +@@ -2969,7 +2968,7 @@ int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *n + assert(name); + assert(format); + +- if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) ++ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) + return 0; + + va_start(ap, format); +@@ -2992,7 +2991,7 @@ int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char * + if (!UNIT_VTABLE(u)->private_section) + return -EINVAL; + +- if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) ++ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) + return 0; + + ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL); +@@ -3011,7 +3010,7 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const + assert(name); + assert(format); + +- if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) ++ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) + return 0; + + va_start(ap, format); +@@ -3030,7 +3029,7 @@ int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { + + assert(u); + +- if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) ++ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) + return 0; + + r = drop_in_file(u, mode, name, &p, &q); diff --git a/SOURCES/0317-load-modules-properly-return-a-failing-error-code-if.patch b/SOURCES/0317-load-modules-properly-return-a-failing-error-code-if.patch new file mode 100644 index 0000000..1f5b8b5 --- /dev/null +++ b/SOURCES/0317-load-modules-properly-return-a-failing-error-code-if.patch @@ -0,0 +1,34 @@ +From 85658c05781da6137bf8c93d1454aa588ab98696 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 18 Feb 2014 21:23:16 +0100 +Subject: [PATCH] load-modules: properly return a failing error code if some + module fails to load + +This is the missing part of b857193b1def5172e3641ca1d5bc9e08ae81aac4. + +(cherry-picked from 4b462d1a28461b302586b117736ef288fba1012f) + +Resolves: #1147524 +--- + src/modules-load/modules-load.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c +index cba7c55..5d2ca4d 100644 +--- a/src/modules-load/modules-load.c ++++ b/src/modules-load/modules-load.c +@@ -306,9 +306,11 @@ int main(int argc, char *argv[]) { + r = k; + } + +- r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); +- if (r < 0) { +- log_error("Failed to enumerate modules-load.d files: %s", strerror(-r)); ++ k = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); ++ if (k < 0) { ++ log_error("Failed to enumerate modules-load.d files: %s", strerror(-k)); ++ if (r == 0) ++ r = k; + goto finish; + } + diff --git a/SOURCES/0318-core-unit-fix-unit_add_target_dependencies-for-units.patch b/SOURCES/0318-core-unit-fix-unit_add_target_dependencies-for-units.patch new file mode 100644 index 0000000..26b22bd --- /dev/null +++ b/SOURCES/0318-core-unit-fix-unit_add_target_dependencies-for-units.patch @@ -0,0 +1,34 @@ +From 22eebbf0b5ab380173b3d8bab558719b1f408a2e Mon Sep 17 00:00:00 2001 +From: Daniel Mack +Date: Thu, 20 Feb 2014 13:29:54 +0100 +Subject: [PATCH] core/unit: fix unit_add_target_dependencies() for units with + no dependencies + +For units without any dependencies, r needs to be initialized to 0. +Otherwise, the return value of unit_add_target_dependencies() is +unspecified. + +Conflicts: + src/core/unit.c + +(cherry-picked from db57f3c6d11864f4227bb6734a0d509695a32a7d) + +Resolves: #1147524 +--- + src/core/unit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index e56971b..b51e351 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -923,8 +923,8 @@ static int unit_add_default_dependencies(Unit *u) { + + Unit *target; + Iterator i; +- int r; + unsigned k; ++ int r = 0; + + assert(u); + diff --git a/SOURCES/0319-man-there-is-no-ExecStopPre-for-service-units.patch b/SOURCES/0319-man-there-is-no-ExecStopPre-for-service-units.patch new file mode 100644 index 0000000..1bce347 --- /dev/null +++ b/SOURCES/0319-man-there-is-no-ExecStopPre-for-service-units.patch @@ -0,0 +1,27 @@ +From 7d34b04e8dc4e1253d6360eeefbfaf686f58991b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 21 Feb 2014 15:06:44 +0100 +Subject: [PATCH] man: there is no ExecStopPre= for service units + +https://bugs.freedesktop.org/show_bug.cgi?id=73177 + +(cherry-picked from c32acc96ef74d13d0059a680cdede5f05db1981a) + +Resolves: #1147524 +--- + man/systemd.service.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index 4fb21ba..80d6951 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -678,7 +678,7 @@ ExecStart=/bin/echo $ONE $TWO ${TWO} + specified with + ExecStartPre=, + ExecStartPost=, +- ExecStopPre=, ++ ExecStop=, + ExecStopPost=, or + ExecReload=. + When the death of the process is a diff --git a/SOURCES/0320-man-document-that-per-interface-sysctl-variables-are.patch b/SOURCES/0320-man-document-that-per-interface-sysctl-variables-are.patch new file mode 100644 index 0000000..9a6d9a6 --- /dev/null +++ b/SOURCES/0320-man-document-that-per-interface-sysctl-variables-are.patch @@ -0,0 +1,36 @@ +From 1c06bbbcbc55b2404cdece020411f06b28b4b2b3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sun, 23 Feb 2014 16:43:19 +0100 +Subject: [PATCH] man: document that per-interface sysctl variables are applied + as network interfaces show up + +https://bugzilla.redhat.com/show_bug.cgi?id=1062955 + +(cherry-picked from 8f03fd08911016d8bbcad5892b2c07b30a4c2306) + +Resolves: #1147524 +--- + man/sysctl.d.xml | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml +index 5544283..00a857b 100644 +--- a/man/sysctl.d.xml ++++ b/man/sysctl.d.xml +@@ -103,6 +103,16 @@ + /dev/null in + /etc/sysctl.d/ bearing the + same filename. ++ ++ The settings configured with ++ sysctl.d files will be applied ++ early on boot. The network interface-specific options ++ will also be applied individually for each network ++ interface as it shows up in the system. (More ++ specifically, that is ++ net.ipv4.conf.*, ++ net.ipv6.conf.*, ++ net.ipv4.neigh.* and net.ipv6.neigh.*) + + + diff --git a/SOURCES/0321-journal-downgrade-vaccuum-message-to-debug-level.patch b/SOURCES/0321-journal-downgrade-vaccuum-message-to-debug-level.patch new file mode 100644 index 0000000..f136f6a --- /dev/null +++ b/SOURCES/0321-journal-downgrade-vaccuum-message-to-debug-level.patch @@ -0,0 +1,27 @@ +From 68272275166ad738ccf7c70ac0a6b8c72470c95f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sun, 23 Feb 2014 17:05:37 +0100 +Subject: [PATCH] journal: downgrade vaccuum message to debug level + +https://bugzilla.redhat.com/show_bug.cgi?id=1047148 + +(cherry-picked from 3bb621e1e66b704c0c2dcef31c66f7c646dd47f6) + +Resolves: #1147524 +--- + src/journal/journal-vacuum.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c +index d4a1c6c..88c67a1 100644 +--- a/src/journal/journal-vacuum.c ++++ b/src/journal/journal-vacuum.c +@@ -336,7 +336,7 @@ finish: + free(list[i].filename); + free(list); + +- log_info("Vacuuming done, freed %"PRIu64" bytes", freed); ++ log_debug("Vacuuming done, freed %"PRIu64" bytes", freed); + + return r; + } diff --git a/SOURCES/0322-logs-show-fix-corrupt-output-with-empty-messages.patch b/SOURCES/0322-logs-show-fix-corrupt-output-with-empty-messages.patch new file mode 100644 index 0000000..bc7025c --- /dev/null +++ b/SOURCES/0322-logs-show-fix-corrupt-output-with-empty-messages.patch @@ -0,0 +1,42 @@ +From b5915d4a5870668442d3ef08a3b1f6b0028ea97f Mon Sep 17 00:00:00 2001 +From: Uoti Urpala +Date: Thu, 20 Feb 2014 03:00:09 +0200 +Subject: [PATCH] logs-show: fix corrupt output with empty messages + +If a message had zero length, journalctl would print no newline, and +two output lines would be concatenated. Fix. The problem was +introduced in commit 31f7bf199452 ("logs-show: print multiline +messages"). Affected short and verbose output modes. + +Before fix: + +Feb 09 21:16:17 glyph dhclient[1323]: Feb 09 21:16:17 glyph NetworkManager[788]: (enp4s2): DHCPv4 state changed nbi -> preinit + +after: + +Feb 09 21:16:17 glyph dhclient[1323]: +Feb 09 21:16:17 glyph NetworkManager[788]: (enp4s2): DHCPv4 state changed nbi -> preinit + +(cherry-picked from 47d80904a1f72d559962cc5ad32fffd46672a34a) + +Resolves: #1147524 +--- + src/shared/logs-show.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c +index 7bb19b4..91eefb3 100644 +--- a/src/shared/logs-show.c ++++ b/src/shared/logs-show.c +@@ -121,6 +121,11 @@ static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output + } + } + ++ /* A special case: make sure that we print a newline when ++ the message is empty. */ ++ if (message_len == 0) ++ fputs("\n", f); ++ + for (pos = message; + pos < message + message_len; + pos = end + 1, line++) { diff --git a/SOURCES/0323-journalctl-refuse-extra-arguments-with-verify-and-si.patch b/SOURCES/0323-journalctl-refuse-extra-arguments-with-verify-and-si.patch new file mode 100644 index 0000000..289f375 --- /dev/null +++ b/SOURCES/0323-journalctl-refuse-extra-arguments-with-verify-and-si.patch @@ -0,0 +1,31 @@ +From f951a4b2dbbfdb8c387a802d0ae56ce47470f679 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 26 Feb 2014 23:01:43 -0500 +Subject: [PATCH] journalctl: refuse extra arguments with --verify and similar + +Positional arguments only make sense with the default action. +For other actions, complain instead of ignoring them silently. + +(cherry-picked from 0b6b7c2004317da48e5bbd3078c5662d8f0061b6) + +Resolves: #1147524 +--- + src/journal/journalctl.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c +index 54e3ddd..3113e65 100644 +--- a/src/journal/journalctl.c ++++ b/src/journal/journalctl.c +@@ -584,6 +584,11 @@ static int parse_argv(int argc, char *argv[]) { + return -EINVAL; + } + ++ if (arg_action != ACTION_SHOW && optind < argc) { ++ log_error("Extraneous arguments starting with '%s'", argv[optind]); ++ return -EINVAL; ++ } ++ + return 1; + } + diff --git a/SOURCES/0324-journal-assume-that-next-entry-is-after-previous-ent.patch b/SOURCES/0324-journal-assume-that-next-entry-is-after-previous-ent.patch new file mode 100644 index 0000000..6186ad2 --- /dev/null +++ b/SOURCES/0324-journal-assume-that-next-entry-is-after-previous-ent.patch @@ -0,0 +1,71 @@ +From 559cbd8367f3eb2c7ce49f923a688e7f83c5b439 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 27 Feb 2014 00:07:29 -0500 +Subject: [PATCH] journal: assume that next entry is after previous entry + +With a corrupted file, we can get in a situation where two entries +in the entry array point to the same object. Then journal_file_next_entry +will find the first one using generic_arrray_bisect, and try to move to +the second one, but since the address is the same, generic_array_get will +return the first one. journal_file_next_entry ends up in an infinite loop. + +https://bugzilla.redhat.com/show_bug.cgi?id=1047039 + +(cherry-picked from fb099c8d2af6620db2709e826a258089d10cdfe8) + +Resolves: #1147524 +--- + src/journal/journal-file.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c +index 9dbd674..f101a1f 100644 +--- a/src/journal/journal-file.c ++++ b/src/journal/journal-file.c +@@ -1359,7 +1359,7 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st + } + + typedef struct ChainCacheItem { +- uint64_t first; /* the array at the begin of the chain */ ++ uint64_t first; /* the array at the beginning of the chain */ + uint64_t array; /* the cached array */ + uint64_t begin; /* the first item in the cached array */ + uint64_t total; /* the total number of items in all arrays before this one in the chain */ +@@ -1945,7 +1945,7 @@ int journal_file_next_entry( + direction_t direction, + Object **ret, uint64_t *offset) { + +- uint64_t i, n; ++ uint64_t i, n, ofs; + int r; + + assert(f); +@@ -1986,10 +1986,24 @@ int journal_file_next_entry( + } + + /* And jump to it */ +- return generic_array_get(f, +- le64toh(f->header->entry_array_offset), +- i, +- ret, offset); ++ r = generic_array_get(f, ++ le64toh(f->header->entry_array_offset), ++ i, ++ ret, &ofs); ++ if (r <= 0) ++ return r; ++ ++ if (p > 0 && ++ (direction == DIRECTION_DOWN ? ofs <= p : ofs >= p)) { ++ log_debug("%s: entry array corrupted at entry %"PRIu64, ++ f->path, i); ++ return -EBADMSG; ++ } ++ ++ if (offset) ++ *offset = ofs; ++ ++ return 1; + } + + int journal_file_skip_entry( diff --git a/SOURCES/0325-journal-forget-file-after-encountering-an-error.patch b/SOURCES/0325-journal-forget-file-after-encountering-an-error.patch new file mode 100644 index 0000000..bce17cd --- /dev/null +++ b/SOURCES/0325-journal-forget-file-after-encountering-an-error.patch @@ -0,0 +1,75 @@ +From 1ff08dbb562d007bbca2323ab219324058fe8adb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 27 Feb 2014 00:11:54 -0500 +Subject: [PATCH] journal: forget file after encountering an error + +If we encounter an inconsistency in a file, let's just +ignore it. Otherwise, after previous patch, we would try, +and fail, to use this file in every invocation of sd_journal_next +or sd_journal_previous that happens afterwards. + +(cherry-picked from a9a245c128af6c0418085062c60251bc51fa4a94) + +Resolves: #1147524 +--- + src/journal/sd-journal.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index 67a77e6..8e3bb0c 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -50,6 +50,8 @@ + + #define DEFAULT_DATA_THRESHOLD (64*1024) + ++static void remove_file_real(sd_journal *j, JournalFile *f); ++ + static bool journal_pid_changed(sd_journal *j) { + assert(j); + +@@ -895,6 +897,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) { + r = next_beyond_location(j, f, direction, &o, &p); + if (r < 0) { + log_debug("Can't iterate through %s, ignoring: %s", f->path, strerror(-r)); ++ remove_file_real(j, f); + continue; + } else if (r == 0) + continue; +@@ -1368,7 +1371,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { + } + + static int remove_file(sd_journal *j, const char *prefix, const char *filename) { +- char *path; ++ _cleanup_free_ char *path; + JournalFile *f; + + assert(j); +@@ -1380,10 +1383,17 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename) + return -ENOMEM; + + f = hashmap_get(j->files, path); +- free(path); + if (!f) + return 0; + ++ remove_file_real(j, f); ++ return 0; ++} ++ ++static void remove_file_real(sd_journal *j, JournalFile *f) { ++ assert(j); ++ assert(f); ++ + hashmap_remove(j->files, f->path); + + log_debug("File %s removed.", f->path); +@@ -1401,8 +1411,6 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename) + journal_file_close(f); + + j->current_invalidate_counter ++; +- +- return 0; + } + + static int add_directory(sd_journal *j, const char *prefix, const char *dirname) { diff --git a/SOURCES/0326-man-update-link-to-LSB.patch b/SOURCES/0326-man-update-link-to-LSB.patch new file mode 100644 index 0000000..64a213c --- /dev/null +++ b/SOURCES/0326-man-update-link-to-LSB.patch @@ -0,0 +1,36 @@ +From da1a97ff0f6637cb2e1d68ab0289b0f1125dc4df Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 6 Mar 2014 08:10:19 -0500 +Subject: [PATCH] man: update link to LSB + +https://bugzilla.redhat.com/show_bug.cgi?id=1073402 + +(cherry-picked from 27d14fb331ba8144f99f4da2d13f15cf5c8b8a9f) + +Resolves: #1147524 +--- + man/daemon.xml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/man/daemon.xml b/man/daemon.xml +index 105826a..418a7e9 100644 +--- a/man/daemon.xml ++++ b/man/daemon.xml +@@ -251,7 +251,7 @@ + detect service errors and problems. It + is recommended to follow the exit code + scheme as defined in the LSB ++ url="http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB + recommendations for SysV init + scripts. + +@@ -394,7 +394,7 @@ + exclusively on boot (and manually by the + administrator) via SysV init scripts, as + detailed in the LSB ++ url="http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB + Linux Standard Base Core + Specification. This method of + activation is supported ubiquitously on Linux diff --git a/SOURCES/0327-man-systemd-bootchart-fix-spacing-in-command.patch b/SOURCES/0327-man-systemd-bootchart-fix-spacing-in-command.patch new file mode 100644 index 0000000..d3a958b --- /dev/null +++ b/SOURCES/0327-man-systemd-bootchart-fix-spacing-in-command.patch @@ -0,0 +1,29 @@ +From a7711e81f0192e06fbc97705bf757410fc33724c Mon Sep 17 00:00:00 2001 +From: Zachary Cook +Date: Thu, 6 Mar 2014 03:49:49 -0500 +Subject: [PATCH] man: systemd-bootchart - fix spacing in command + +Use the same formatting as the systemd-analyze man page, so that man shows a space. + +(cherry-picked from 82ed60080d327d7301fcd55f5a1f8511f894b9d5) + +Resolves: #1147524 +--- + man/systemd-bootchart.xml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/man/systemd-bootchart.xml b/man/systemd-bootchart.xml +index ae432b5..818afa1 100644 +--- a/man/systemd-bootchart.xml ++++ b/man/systemd-bootchart.xml +@@ -76,8 +76,8 @@ + in which order, and where possible problems + exist in the startup sequence of the system. + It is essentially a more detailed version of +- the systemd-analyze +- plot function. ++ the systemd-analyze plot ++ function. + + + Of course, bootchart can also be used at any diff --git a/SOURCES/0328-man-add-missing-comma.patch b/SOURCES/0328-man-add-missing-comma.patch new file mode 100644 index 0000000..91e4440 --- /dev/null +++ b/SOURCES/0328-man-add-missing-comma.patch @@ -0,0 +1,27 @@ +From 958e9706f20d69608c703808731bb9ff523d8462 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 6 Mar 2014 23:54:13 -0500 +Subject: [PATCH] man: add missing comma + +marcosf0> missing comma in udevadm "see also" section + +(cherry-picked from 7d06ef0a5cd2f0a4e021d3d12f3841cce529e0f2) + +Resolves: #1147524 +--- + man/udevadm.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/udevadm.xml b/man/udevadm.xml +index ca3713f..6fc6783 100644 +--- a/man/udevadm.xml ++++ b/man/udevadm.xml +@@ -514,7 +514,7 @@ + See Also + + udev7 +- ++ , + + systemd-udevd.service8 + diff --git a/SOURCES/0329-units-Do-not-unescape-instance-name-in-systemd-backl.patch b/SOURCES/0329-units-Do-not-unescape-instance-name-in-systemd-backl.patch new file mode 100644 index 0000000..3f9d6c3 --- /dev/null +++ b/SOURCES/0329-units-Do-not-unescape-instance-name-in-systemd-backl.patch @@ -0,0 +1,39 @@ +From 51aa47339565893e48a3533250d392fcdb80a675 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20B=C3=A4chler?= +Date: Fri, 7 Mar 2014 01:50:34 +0100 +Subject: [PATCH] units: Do not unescape instance name in + systemd-backlight@.service + +The instance name is never escaped in the udev rule, but unescaped in the unit. +This results in the following error message on Asus boards: + + Failed to get backlight or LED device 'backlight:eeepc/wmi': No such file or directory + +(cherry-picked from 6c49212741253dae05b89d22374186f092ef1e5a) + +Resolves: #1147524 +--- + units/systemd-backlight@.service.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/units/systemd-backlight@.service.in b/units/systemd-backlight@.service.in +index 5caa5d5..e945d87 100644 +--- a/units/systemd-backlight@.service.in ++++ b/units/systemd-backlight@.service.in +@@ -6,7 +6,7 @@ + # (at your option) any later version. + + [Unit] +-Description=Load/Save Screen Backlight Brightness of %I ++Description=Load/Save Screen Backlight Brightness of %i + Documentation=man:systemd-backlight@.service(8) + DefaultDependencies=no + RequiresMountsFor=/var/lib/systemd/backlight +@@ -17,5 +17,5 @@ Before=sysinit.target shutdown.target + [Service] + Type=oneshot + RemainAfterExit=yes +-ExecStart=@rootlibexecdir@/systemd-backlight load %I +-ExecStop=@rootlibexecdir@/systemd-backlight save %I ++ExecStart=@rootlibexecdir@/systemd-backlight load %i ++ExecStop=@rootlibexecdir@/systemd-backlight save %i diff --git a/SOURCES/0330-manager-flush-memory-stream-before-using-the-buffer.patch b/SOURCES/0330-manager-flush-memory-stream-before-using-the-buffer.patch new file mode 100644 index 0000000..c3ad052 --- /dev/null +++ b/SOURCES/0330-manager-flush-memory-stream-before-using-the-buffer.patch @@ -0,0 +1,75 @@ +From 0fca5aae90d5a4e292db8db7b9c31c8390799368 Mon Sep 17 00:00:00 2001 +From: Daniel Mack +Date: Fri, 7 Mar 2014 14:43:59 +0100 +Subject: [PATCH] manager: flush memory stream before using the buffer + +When the manager receives a SIGUSR2 signal, it opens a memory stream +with open_memstream(), uses the returned file handle for logging, and +dumps the logged content with log_dump(). + +However, the char* buffer is only safe to use after the file handle has +been flushed with fflush, as the man pages states: + + When the stream is closed (fclose(3)) or flushed (fflush(3)), the + locations pointed to by ptr and sizeloc are updated to contain, + respectively, a pointer to the buffer and the current size of the + buffer. + These values remain valid only as long as the caller performs no + further output on the stream. If further output is performed, then the + stream must again be flushed before trying to access these variables. + +Without that call, dump remains NULL and the daemon crashes in +log_dump(). + +Conflicts: + src/core/manager.c + +(cherry-picked from b2cdc6664ef6b56e47d38649d69b9943d9f9f5d0) + +Resolves: #1147524 +--- + src/core/manager.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index 4ad26e1..e48ea36 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1536,11 +1536,12 @@ static int manager_process_signal_fd(Manager *m) { + } + + case SIGUSR2: { +- FILE *f; +- char *dump = NULL; ++ _cleanup_free_ char *dump = NULL; ++ _cleanup_fclose_ FILE *f = NULL; + size_t size; + +- if (!(f = open_memstream(&dump, &size))) { ++ f = open_memstream(&dump, &size); ++ if (!f) { + log_warning("Failed to allocate memory stream."); + break; + } +@@ -1549,16 +1550,16 @@ static int manager_process_signal_fd(Manager *m) { + manager_dump_jobs(m, f, "\t"); + + if (ferror(f)) { +- fclose(f); +- free(dump); + log_warning("Failed to write status stream"); + break; + } + +- fclose(f); +- log_dump(LOG_INFO, dump); +- free(dump); ++ if (fflush(f)) { ++ log_warning("Failed to flush status stream"); ++ break; ++ } + ++ log_dump(LOG_INFO, dump); + break; + } + diff --git a/SOURCES/0331-man-multiple-sleep-modes-are-to-be-separated-by-whit.patch b/SOURCES/0331-man-multiple-sleep-modes-are-to-be-separated-by-whit.patch new file mode 100644 index 0000000..d52f697 --- /dev/null +++ b/SOURCES/0331-man-multiple-sleep-modes-are-to-be-separated-by-whit.patch @@ -0,0 +1,63 @@ +From ccbe3369a69af38dbf8fdf3a0a1b27ba534506ea Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 11 Mar 2014 05:23:39 +0100 +Subject: [PATCH] man: multiple sleep modes are to be separated by whitespace, + not commas + +As pointed out by Jason A. Donenfeld. + +Conflicts: + man/systemd-sleep.conf.xml + +(cherry-picked from 252094eb05c58270a0bc35b14ad30a126ddbb3bb) + +Resolves: #1147524 +--- + man/systemd-sleep.conf.xml | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +diff --git a/man/systemd-sleep.conf.xml b/man/systemd-sleep.conf.xml +index dc4b0da..d0ea6d8 100644 +--- a/man/systemd-sleep.conf.xml ++++ b/man/systemd-sleep.conf.xml +@@ -127,10 +127,10 @@ along with systemd; If not, see . + systemd-suspend.service8, + systemd-hibernate.service8, or + systemd-hybrid-sleep.service8. +- More than one value can be specified by seperating +- multiple values with commas. They will be tried ++ More than one value can be specified by separating ++ multiple values with whitespace. They will be tried + in turn, until one is written without error. If +- neither suceeds, the operation will be aborted. ++ neither succeeds, the operation will be aborted. + + + +@@ -145,10 +145,10 @@ along with systemd; If not, see . + systemd-suspend.service8, + systemd-hibernate.service8, or + systemd-hybrid-sleep.service8. +- More than one value can be specified by seperating +- multiple values with commas. They will be tried ++ More than one value can be specified by separating ++ multiple values with whitespace. They will be tried + in turn, until one is written without error. If +- neither suceeds, the operation will be aborted. ++ neither succeeds, the operation will be aborted. + + + +@@ -160,10 +160,8 @@ along with systemd; If not, see . + Example: to exploit the freeze mode added + in Linux 3.9, one can use systemctl suspend + with +- +-[Sleep] +-SuspendState=freeze +- ++ [Sleep] ++SuspendState=freeze + + + diff --git a/SOURCES/0332-man-fix-description-of-systemctl-after-before.patch b/SOURCES/0332-man-fix-description-of-systemctl-after-before.patch new file mode 100644 index 0000000..beb81e2 --- /dev/null +++ b/SOURCES/0332-man-fix-description-of-systemctl-after-before.patch @@ -0,0 +1,30 @@ +From 603f2c62ba1a64aa22223b66dfdd455ca6589b91 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Fri, 21 Feb 2014 20:44:06 +0400 +Subject: [PATCH] man: fix description of systemctl --after/--before + +It was backward - --after fetches After property, so units shown really +come *before* unit given as argument. Same for --before. + +(cherry-picked from 4a77ca700d1841c2b8a86ed5b7f3495db61c236d) + +Resolves: #1147524 +--- + man/systemctl.xml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index d1fda61..045d520 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -176,8 +176,8 @@ systemctl start foo + + + +- Show which units are started after or before +- with list-dependencies, respectively. ++ Show after (before) which units the specified unit is started ++ with list-dependencies. + + + diff --git a/SOURCES/0333-udev-properly-detect-reference-to-unexisting-part-of.patch b/SOURCES/0333-udev-properly-detect-reference-to-unexisting-part-of.patch new file mode 100644 index 0000000..8969cb5 --- /dev/null +++ b/SOURCES/0333-udev-properly-detect-reference-to-unexisting-part-of.patch @@ -0,0 +1,26 @@ +From 2e13dee991178518480d68e89d323666b047d182 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Mon, 24 Feb 2014 17:06:21 +0100 +Subject: [PATCH] udev: properly detect reference to unexisting part of + PROGRAM's result + +(cherry-picked from 66390abefae6530981446970ffd7ff4d1085e254) + +Resolves: #1147524 +--- + src/udev/udev-event.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index d69d7ba..aa7c793 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -254,6 +254,8 @@ subst: + cpos++; + while (isspace(cpos[0])) + cpos++; ++ if (cpos[0] == '\0') ++ break; + } + if (i > 0) { + log_error("requested part of result string not found\n"); diff --git a/SOURCES/0334-gpt-auto-generator-don-t-return-OOM-on-parentless-de.patch b/SOURCES/0334-gpt-auto-generator-don-t-return-OOM-on-parentless-de.patch new file mode 100644 index 0000000..ac3d6d0 --- /dev/null +++ b/SOURCES/0334-gpt-auto-generator-don-t-return-OOM-on-parentless-de.patch @@ -0,0 +1,25 @@ +From c8135d12561727f7ed8513cb5f113866ee963194 Mon Sep 17 00:00:00 2001 +From: Tomasz Torcz +Date: Wed, 12 Mar 2014 19:25:11 +0100 +Subject: [PATCH] gpt-auto-generator: don't return OOM on parentless devices + +(cherry-picked from 9c4495ca561624c2f0085507dd1288ed5f1247c5) + +Resolves: #1147524 +--- + src/gpt-auto-generator/gpt-auto-generator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c +index 8436d26..6a4c9d8 100644 +--- a/src/gpt-auto-generator/gpt-auto-generator.c ++++ b/src/gpt-auto-generator/gpt-auto-generator.c +@@ -252,7 +252,7 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { + + parent = udev_device_get_parent(d); + if (!parent) +- return log_oom(); ++ return 0; + + r = udev_enumerate_add_match_parent(e, parent); + if (r < 0) diff --git a/SOURCES/0335-man-improve-wording-of-systemctl-s-after-before.patch b/SOURCES/0335-man-improve-wording-of-systemctl-s-after-before.patch new file mode 100644 index 0000000..eaaf62b --- /dev/null +++ b/SOURCES/0335-man-improve-wording-of-systemctl-s-after-before.patch @@ -0,0 +1,57 @@ +From 8c346633426ec3476f87e7558407b75d9da1d5a4 Mon Sep 17 00:00:00 2001 +From: "Jason St. John" +Date: Mon, 17 Mar 2014 00:03:46 -0400 +Subject: [PATCH] man: improve wording of systemctl's --after/--before + +Commit 4a77ca7 was an attempt at fixing the wording of --after and --before, +but the new wording was unclear. + +Split the combined --after/--before section into a separate section for +each, explicitly state what each option does, and add information about +how these lists are generated. + +Reported-by: Andrey Borzenkov +Reported-by: Lennart Poettering + +(cherry-picked from 9029f64298cb70c12ecf638fddee7f41b056fcf1) + +Resolves: #1147524 +--- + man/systemctl.xml | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index 045d520..cb63bb0 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -173,12 +173,27 @@ systemctl start foo + + + ++ ++ ++ With list-dependencies, show the ++ units that are ordered before the specified unit. In other ++ words, list the units that are in the After= ++ directive of the specified unit, have the specified unit in ++ their Before= directive, or are otherwise ++ implicit dependencies of the specified unit. ++ ++ ++ ++ + + + +- Show after (before) which units the specified unit is started +- with list-dependencies. +- ++ With list-dependencies, show the ++ units that are ordered after the specified unit. In other ++ words, list the units that are in the Before= ++ directive of the specified unit, have the specified unit in ++ their After= directive, or otherwise depend ++ on the specified unit. + + + diff --git a/SOURCES/0336-cgroup-it-s-not-OK-to-invoke-alloca-in-loops.patch b/SOURCES/0336-cgroup-it-s-not-OK-to-invoke-alloca-in-loops.patch new file mode 100644 index 0000000..25952cb --- /dev/null +++ b/SOURCES/0336-cgroup-it-s-not-OK-to-invoke-alloca-in-loops.patch @@ -0,0 +1,80 @@ +From aab1a9e316bfa55ab41ecad102c90c6b7eeac52e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 18 Mar 2014 04:06:36 +0100 +Subject: [PATCH] cgroup: it's not OK to invoke alloca() in loops + +(cherry-picked from a641dcd9bf05418d6a6c165e1c0cff615b4a0f47) + +Resolves: #1147524 +--- + src/core/mount-setup.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c +index 4359f59..679f289 100644 +--- a/src/core/mount-setup.c ++++ b/src/core/mount-setup.c +@@ -210,10 +210,10 @@ int mount_setup_early(void) { + } + + int mount_cgroup_controllers(char ***join_controllers) { +- int r; +- char buf[LINE_MAX]; + _cleanup_set_free_free_ Set *controllers = NULL; + _cleanup_fclose_ FILE *f; ++ char buf[LINE_MAX]; ++ int r; + + /* Mount all available cgroup controllers that are built into the kernel. */ + +@@ -256,6 +256,7 @@ int mount_cgroup_controllers(char ***join_controllers) { + } + + for (;;) { ++ _cleanup_free_ char *options = NULL, *controller = NULL, *where = NULL; + MountPoint p = { + .what = "cgroup", + .type = "cgroup", +@@ -263,7 +264,6 @@ int mount_cgroup_controllers(char ***join_controllers) { + .mode = MNT_IN_CONTAINER, + }; + char ***k = NULL; +- _cleanup_free_ char *options = NULL, *controller; + + controller = set_steal_first(controllers); + if (!controller) +@@ -280,7 +280,7 @@ int mount_cgroup_controllers(char ***join_controllers) { + for (i = *k, j = *k; *i; i++) { + + if (!streq(*i, controller)) { +- char _cleanup_free_ *t; ++ _cleanup_free_ char *t; + + t = set_remove(controllers, *i); + if (!t) { +@@ -302,7 +302,11 @@ int mount_cgroup_controllers(char ***join_controllers) { + controller = NULL; + } + +- p.where = strappenda("/sys/fs/cgroup/", options); ++ where = strappend("/sys/fs/cgroup/", options); ++ if (!where) ++ return log_oom(); ++ ++ p.where = where; + p.options = options; + + r = mount_one(&p, true); +@@ -313,7 +317,11 @@ int mount_cgroup_controllers(char ***join_controllers) { + char **i; + + for (i = *k; *i; i++) { +- char *t = strappenda("/sys/fs/cgroup/", *i); ++ _cleanup_free_ char *t = NULL; ++ ++ t = strappend("/sys/fs/cgroup/", *i); ++ if (!t) ++ return log_oom(); + + r = symlink(options, t); + if (r < 0 && errno != EEXIST) { diff --git a/SOURCES/0337-core-don-t-try-to-relabel-mounts-before-we-loaded-th.patch b/SOURCES/0337-core-don-t-try-to-relabel-mounts-before-we-loaded-th.patch new file mode 100644 index 0000000..bcb14c8 --- /dev/null +++ b/SOURCES/0337-core-don-t-try-to-relabel-mounts-before-we-loaded-th.patch @@ -0,0 +1,28 @@ +From 5e102f2c8212a94b3a5221b5cf79eaafef693cc7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 24 Mar 2014 21:04:02 +0100 +Subject: [PATCH] core: don't try to relabel mounts before we loaded the policy + +(cherry-picked from c4bfd1691f4d3e26d6d7f34dbca941e119956e8a) + +Resolves: #1147524 +--- + src/core/mount-setup.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c +index 679f289..cff83d3 100644 +--- a/src/core/mount-setup.c ++++ b/src/core/mount-setup.c +@@ -166,7 +166,10 @@ static int mount_one(const MountPoint *p, bool relabel) { + + /* The access mode here doesn't really matter too much, since + * the mounted file system will take precedence anyway. */ +- mkdir_p_label(p->where, 0755); ++ if (relabel) ++ mkdir_p_label(p->where, 0755); ++ else ++ mkdir_p(p->where, 0755); + + log_debug("Mounting %s to %s of type %s with options %s.", + p->what, diff --git a/SOURCES/0338-systemctl-kill-mode-is-long-long-gone-don-t-mention-.patch b/SOURCES/0338-systemctl-kill-mode-is-long-long-gone-don-t-mention-.patch new file mode 100644 index 0000000..aa89da3 --- /dev/null +++ b/SOURCES/0338-systemctl-kill-mode-is-long-long-gone-don-t-mention-.patch @@ -0,0 +1,53 @@ +From 597dd2168bb3e7f62842b07c9df1bb7c7c47b793 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 25 Mar 2014 00:31:48 +0100 +Subject: [PATCH] systemctl: --kill-mode is long long gone, don't mention it in + the man page + +(cherry-picked from 0088d63151e088d62104d88f866e9eb049091c22) + +Resolves: #1147524 +--- + man/systemctl.xml | 5 ++--- + shell-completion/bash/systemctl | 5 +---- + 2 files changed, 3 insertions(+), 7 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index cb63bb0..f68b606 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -672,9 +672,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service + + Send a signal to one or more processes of the + unit. Use to select which +- process to kill. Use to select +- the kill mode and to select the +- signal to send. ++ process to kill. Use to select ++ the signal to send. + + + +diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl +index efe8485..cbf0eb7 100644 +--- a/shell-completion/bash/systemctl ++++ b/shell-completion/bash/systemctl +@@ -74,7 +74,7 @@ _systemctl () { + [STANDALONE]='--all -a --reverse --after --before --defaults --fail --ignore-dependencies --failed --force -f --full -l --global + --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall + --quiet -q --privileged -P --system --user --version --runtime' +- [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --state --root' ++ [ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --root' + ) + + local -A PROPS='CPUAccounting= MemoryAccounting= BlockIOAccounting= MemoryLimit= CPUShares= BlockIOWeight= DevicePolicy= DeviceAllow= BlockIOReadBandwidth= BlockIOWriteBandwidth= BlockIODeviceWeight=' +@@ -101,9 +101,6 @@ _systemctl () { + --kill-who) + comps='all control main' + ;; +- --kill-mode) +- comps='control-group process' +- ;; + --root) + comps=$(compgen -A directory -- "$cur" ) + compopt -o filenames diff --git a/SOURCES/0339-ask-password-when-the-user-types-a-overly-long-passw.patch b/SOURCES/0339-ask-password-when-the-user-types-a-overly-long-passw.patch new file mode 100644 index 0000000..ba22ef7 --- /dev/null +++ b/SOURCES/0339-ask-password-when-the-user-types-a-overly-long-passw.patch @@ -0,0 +1,34 @@ +From e02c7fe6cff60803c19dcfe3c21c69bc9c8bdef8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 25 Mar 2014 01:27:05 +0100 +Subject: [PATCH] ask-password: when the user types a overly long password, + beep and refuse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Based on a similar patch from David Härdeman. + +(cherry-picked from 036eeac5a1799fa2c0ae11a14d8c667b5d303189) + +Resolves: #1147524 +--- + src/shared/ask-password-api.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c +index 4557155..25367d0 100644 +--- a/src/shared/ask-password-api.c ++++ b/src/shared/ask-password-api.c +@@ -207,6 +207,11 @@ int ask_password_tty( + if (ttyfd >= 0) + loop_write(ttyfd, "(no echo) ", 10, false); + } else { ++ if (p >= sizeof(passphrase)-1) { ++ loop_write(ttyfd, "\a", 1, false); ++ continue; ++ } ++ + passphrase[p++] = c; + + if (!silent_mode && ttyfd >= 0) diff --git a/SOURCES/0340-logind-don-t-print-error-if-devices-vanish-during-AC.patch b/SOURCES/0340-logind-don-t-print-error-if-devices-vanish-during-AC.patch new file mode 100644 index 0000000..3a196d3 --- /dev/null +++ b/SOURCES/0340-logind-don-t-print-error-if-devices-vanish-during-AC.patch @@ -0,0 +1,39 @@ +From 02d57e30f6e8f0a1f0828d4ee0e1d3b87b54d8f6 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Wed, 2 Apr 2014 16:20:13 +0200 +Subject: [PATCH] logind: don't print error if devices vanish during ACL-init + +If a device is unplugged while we initialize it, we will get ENOENT for +ACL-init (and related stuff). We currently print errors then, which is +misleading. Print a debug-message early and continue. + +Conflicts: + src/login/logind-acl.c + +(cherry-picked from 8016b904849a2d2bd8b0171ed8493db5524b5ff7) + +Resolves: #1147524 +--- + src/login/logind-acl.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c +index 25abcbc..6582b8c 100644 +--- a/src/login/logind-acl.c ++++ b/src/login/logind-acl.c +@@ -283,8 +283,14 @@ int devnode_acl_all(struct udev *udev, + } + + SET_FOREACH(n, nodes, i) { ++ int k; ++ + log_debug("Fixing up ACLs at %s for seat %s", n, seat); +- r = devnode_acl(n, flush, del, old_uid, add, new_uid); ++ k = devnode_acl(n, flush, del, old_uid, add, new_uid); ++ if (k == -ENOENT) ++ log_debug("Device %s disappeared while setting ACLs", n); ++ else if (k < 0) ++ r = k; + } + + finish: diff --git a/SOURCES/0341-tty-ask-password-agent-return-negative-errno.patch b/SOURCES/0341-tty-ask-password-agent-return-negative-errno.patch new file mode 100644 index 0000000..8c2555c --- /dev/null +++ b/SOURCES/0341-tty-ask-password-agent-return-negative-errno.patch @@ -0,0 +1,30 @@ +From 2ae90f52f6ce48f24dcb585b8c0b02dc461cfc4e Mon Sep 17 00:00:00 2001 +From: Florian Albrechtskirchinger +Date: Thu, 3 Apr 2014 21:17:20 +0200 +Subject: [PATCH] tty-ask-password-agent: return negative errno + +Return negative errno in wall_tty_block(). get_ctty_devnr() already +returns a negative errno in case of failure, no need to negate it again. + +Reported-by: Simon + +(cherry-picked from ee0e4cca5ac37a094dfe1074907dae70c7b7701c) + +Resolves: #1147524 +--- + src/tty-ask-password-agent/tty-ask-password-agent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c +index f463662..256c21d 100644 +--- a/src/tty-ask-password-agent/tty-ask-password-agent.c ++++ b/src/tty-ask-password-agent/tty-ask-password-agent.c +@@ -438,7 +438,7 @@ static int wall_tty_block(void) { + + r = get_ctty_devnr(0, &devnr); + if (r < 0) +- return -r; ++ return r; + + if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0) + return -ENOMEM; diff --git a/SOURCES/0342-journal-cleanup-up-error-handling-in-update_catalog.patch b/SOURCES/0342-journal-cleanup-up-error-handling-in-update_catalog.patch new file mode 100644 index 0000000..103582f --- /dev/null +++ b/SOURCES/0342-journal-cleanup-up-error-handling-in-update_catalog.patch @@ -0,0 +1,105 @@ +From 4896a8507ea140f8f38bc88dc044b2e516a54cbf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 11 Apr 2014 08:44:55 -0400 +Subject: [PATCH] journal: cleanup up error handling in update_catalog() + +- Negative/positive errno mixup caused duplicates not to be detected properly. + Now we get a warning about some duplicate entries in our own catalogs... +- Errors in update_catalog would be ignored, but they should not be. + +(cherry-picked from e3b9d9c8027a7c4c55cf1614e0fe9423fad69e8f) + +Resolves: #1147524 +--- + src/journal/catalog.c | 25 +++++++++++++------------ + src/journal/test-catalog.c | 3 ++- + 2 files changed, 15 insertions(+), 13 deletions(-) + +diff --git a/src/journal/catalog.c b/src/journal/catalog.c +index 90ca008..e5342be 100644 +--- a/src/journal/catalog.c ++++ b/src/journal/catalog.c +@@ -109,7 +109,7 @@ static int finish_item( + const char *payload) { + + ssize_t offset; +- CatalogItem *i; ++ _cleanup_free_ CatalogItem *i = NULL; + int r; + + assert(h); +@@ -129,13 +129,14 @@ static int finish_item( + i->offset = htole64((uint64_t) offset); + + r = hashmap_put(h, i, i); +- if (r == EEXIST) { ++ if (r == -EEXIST) { + log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.", + SD_ID128_FORMAT_VAL(id), language ? language : "C"); +- free(i); + return 0; +- } ++ } else if (r < 0) ++ return r; + ++ i = NULL; + return 0; + } + +@@ -348,8 +349,8 @@ error: + int catalog_update(const char* database, const char* root, const char* const* dirs) { + _cleanup_strv_free_ char **files = NULL; + char **f; +- Hashmap *h; + struct strbuf *sb = NULL; ++ _cleanup_hashmap_free_free_ Hashmap *h = NULL; + _cleanup_free_ CatalogItem *items = NULL; + CatalogItem *i; + Iterator j; +@@ -371,13 +372,17 @@ int catalog_update(const char* database, const char* root, const char* const* di + } + + STRV_FOREACH(f, files) { +- log_debug("reading file '%s'", *f); +- catalog_import_file(h, sb, *f); ++ log_debug("Reading file '%s'", *f); ++ r = catalog_import_file(h, sb, *f); ++ if (r < 0) { ++ log_error("Failed to import file '%s': %s.", ++ *f, strerror(-r)); ++ goto finish; ++ } + } + + if (hashmap_size(h) <= 0) { + log_info("No items in catalog."); +- r = 0; + goto finish; + } else + log_debug("Found %u items in catalog.", hashmap_size(h)); +@@ -408,11 +413,7 @@ int catalog_update(const char* database, const char* root, const char* const* di + log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.", + database, n, sb->len, r); + +- r = 0; +- + finish: +- if (h) +- hashmap_free_free(h); + if (sb) + strbuf_cleanup(sb); + +diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c +index 5db5bed..f021dbf 100644 +--- a/src/journal/test-catalog.c ++++ b/src/journal/test-catalog.c +@@ -126,7 +126,8 @@ int main(int argc, char *argv[]) { + + setlocale(LC_ALL, "de_DE.UTF-8"); + +- log_set_max_level(LOG_DEBUG); ++ log_parse_environment(); ++ log_open(); + + test_catalog_importing(); + diff --git a/SOURCES/0343-bash-completion-fix-__get_startable_units.patch b/SOURCES/0343-bash-completion-fix-__get_startable_units.patch new file mode 100644 index 0000000..ae4700d --- /dev/null +++ b/SOURCES/0343-bash-completion-fix-__get_startable_units.patch @@ -0,0 +1,25 @@ +From ab6c4755057a7d852f1eaed62920ef1b25a19507 Mon Sep 17 00:00:00 2001 +From: Dan Kilman +Date: Sun, 13 Apr 2014 18:06:13 +0300 +Subject: [PATCH] bash completion: fix __get_startable_units + +(cherry-picked from a163b64c4b08e8a4ad39a9a295acf3d1634024a3) + +Resolves: #1147524 +--- + shell-completion/bash/systemctl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl +index cbf0eb7..c1cd416 100644 +--- a/shell-completion/bash/systemctl ++++ b/shell-completion/bash/systemctl +@@ -56,7 +56,7 @@ __get_all_units () { __systemctl $1 list-units --all \ + __get_active_units () { __systemctl $1 list-units \ + | { while read -r a b; do echo " $a"; done; }; } + __get_startable_units () { __systemctl $1 list-units --all -t service,timer,socket,mount,automount,path,snapshot,swap \ +- | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed " ]] && echo " $a"; done; }; } ++ | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }; } + __get_failed_units () { __systemctl $1 list-units \ + | { while read -r a b c d; do [[ $c == "failed" ]] && echo " $a"; done; }; } + __get_enabled_units () { __systemctl $1 list-unit-files \ diff --git a/SOURCES/0344-core-check-the-right-variable-for-failed-open.patch b/SOURCES/0344-core-check-the-right-variable-for-failed-open.patch new file mode 100644 index 0000000..752e8fd --- /dev/null +++ b/SOURCES/0344-core-check-the-right-variable-for-failed-open.patch @@ -0,0 +1,25 @@ +From 31cd4f1513656008646ee542e451338112fc8158 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= +Date: Thu, 8 May 2014 12:57:26 +0200 +Subject: [PATCH] core: check the right variable for failed open() + +(cherry-picked from cd7affaeea16d3904354b810a292e594dfef25dd) + +Resolves: #1147524 +--- + src/core/cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 32e2599..c215a86 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -661,7 +661,7 @@ int manager_setup_cgroup(Manager *m) { + close_nointr_nofail(m->pin_cgroupfs_fd); + + m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK); +- if (r < 0) { ++ if (m->pin_cgroupfs_fd < 0) { + log_error("Failed to open pin file: %m"); + return -errno; + } diff --git a/SOURCES/0345-util-allow-trailing-semicolons-on-define_trivial_cle.patch b/SOURCES/0345-util-allow-trailing-semicolons-on-define_trivial_cle.patch new file mode 100644 index 0000000..3c95a1c --- /dev/null +++ b/SOURCES/0345-util-allow-trailing-semicolons-on-define_trivial_cle.patch @@ -0,0 +1,209 @@ +From 30725ba0d69c5ba935c64ce9c3892494687e4c9b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 14 Oct 2013 04:59:26 +0200 +Subject: [PATCH] util: allow trailing semicolons on + define_trivial_cleanup_func lines + +Emacs C indenting really gets confused by these lines if they carry no +trailing semicolon, hence let's make this nicer for good old emacs. The +other macros which define functions already do this too, so let's copy +the scheme here. + +Also, let's use an uppercase name for the macro. So far our rough rule +was that macros that are totally not function-like (like this ones, +which define a function) are uppercase. (Well, admittedly it is a rough +rule only, for example function and variable decorators are all +lower-case SINCE THE CONSTANT YELLING IN THE SOURCES WOULD SUCK, and +also they at least got underscore prefixes.) Also, the macros that +define functions that we already have are all uppercase, so let's do the +same here... + +(cherry-picked from cd7affaeea16d3904354b810a292e594dfef25dd) + +Related: #1147524 +--- + src/gpt-auto-generator/gpt-auto-generator.c | 2 +- + src/journal/journal-internal.h | 2 +- + src/shared/fdset.h | 2 +- + src/shared/hashmap.h | 8 ++++++++ + src/shared/label.c | 4 ++-- + src/shared/set.h | 4 ++-- + src/shared/strv.h | 2 +- + src/shared/udev-util.h | 10 +++++----- + src/shared/util.h | 19 ++++++++++--------- + src/tmpfiles/tmpfiles.c | 2 +- + 10 files changed, 32 insertions(+), 23 deletions(-) + +diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c +index 6a4c9d8..eb281b5 100644 +--- a/src/gpt-auto-generator/gpt-auto-generator.c ++++ b/src/gpt-auto-generator/gpt-auto-generator.c +@@ -51,7 +51,7 @@ + + static const char *arg_dest = "/tmp"; + +-define_trivial_cleanup_func(blkid_probe, blkid_free_probe) ++DEFINE_TRIVIAL_CLEANUP_FUNC(blkid_probe, blkid_free_probe); + #define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep) + + static int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr, char **fstype) { +diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h +index 1bc912c..3355fca 100644 +--- a/src/journal/journal-internal.h ++++ b/src/journal/journal-internal.h +@@ -135,7 +135,7 @@ struct sd_journal { + char *journal_make_match_string(sd_journal *j); + void journal_print_header(sd_journal *j); + +-define_trivial_cleanup_func(sd_journal*, sd_journal_close) ++DEFINE_TRIVIAL_CLEANUP_FUNC(sd_journal*, sd_journal_close); + #define _cleanup_journal_close_ _cleanup_(sd_journal_closep) + + #define JOURNAL_FOREACH_DATA_RETVAL(j, data, l, retval) \ +diff --git a/src/shared/fdset.h b/src/shared/fdset.h +index 6277e46..907acd7 100644 +--- a/src/shared/fdset.h ++++ b/src/shared/fdset.h +@@ -49,5 +49,5 @@ int fdset_iterate(FDSet *s, Iterator *i); + #define FDSET_FOREACH(fd, fds, i) \ + for ((i) = ITERATOR_FIRST, (fd) = fdset_iterate((fds), &(i)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i))) + +-define_trivial_cleanup_func(FDSet*, fdset_free) ++DEFINE_TRIVIAL_CLEANUP_FUNC(FDSet*, fdset_free); + #define _cleanup_fdset_free_ _cleanup_(fdset_freep) +diff --git a/src/shared/hashmap.h b/src/shared/hashmap.h +index 3d4f672..b912af8 100644 +--- a/src/shared/hashmap.h ++++ b/src/shared/hashmap.h +@@ -24,6 +24,7 @@ + #include + + #include "macro.h" ++#include "util.h" + + /* Pretty straightforward hash table implementation. As a minor + * optimization a NULL hashmap object will be treated as empty hashmap +@@ -104,3 +105,10 @@ char **hashmap_get_strv(Hashmap *h); + + #define HASHMAP_FOREACH_BACKWARDS(e, h, i) \ + for ((i) = ITERATOR_LAST, (e) = hashmap_iterate_backwards((h), &(i), NULL); (e); (e) = hashmap_iterate_backwards((h), &(i), NULL)) ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free); ++DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free); ++DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free); ++#define _cleanup_hashmap_free_ _cleanup_(hashmap_freep) ++#define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep) ++#define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep) +diff --git a/src/shared/label.c b/src/shared/label.c +index 4dab93e..8f7dfb4 100644 +--- a/src/shared/label.c ++++ b/src/shared/label.c +@@ -40,8 +40,8 @@ + #include + #include + +-define_trivial_cleanup_func(security_context_t, freecon); +-define_trivial_cleanup_func(context_t, context_free); ++DEFINE_TRIVIAL_CLEANUP_FUNC(security_context_t, freecon); ++DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free); + + #define _cleanup_security_context_free_ _cleanup_(freeconp) + #define _cleanup_context_free_ _cleanup_(context_freep) +diff --git a/src/shared/set.h b/src/shared/set.h +index a291470..5612478 100644 +--- a/src/shared/set.h ++++ b/src/shared/set.h +@@ -73,7 +73,7 @@ char **set_get_strv(Set *s); + #define SET_FOREACH_BACKWARDS(e, s, i) \ + for ((i) = ITERATOR_LAST, (e) = set_iterate_backwards((s), &(i)); (e); (e) = set_iterate_backwards((s), &(i))) + +-define_trivial_cleanup_func(Set*, set_free) +-define_trivial_cleanup_func(Set*, set_free_free) ++DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free); ++DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free); + #define _cleanup_set_free_ _cleanup_(set_freep) + #define _cleanup_set_free_free_ _cleanup_(set_free_freep) +diff --git a/src/shared/strv.h b/src/shared/strv.h +index 4d117f8..f6fb033 100644 +--- a/src/shared/strv.h ++++ b/src/shared/strv.h +@@ -30,7 +30,7 @@ char *strv_find(char **l, const char *name) _pure_; + char *strv_find_prefix(char **l, const char *name) _pure_; + + void strv_free(char **l); +-define_trivial_cleanup_func(char**, strv_free) ++DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free); + #define _cleanup_strv_free_ _cleanup_(strv_freep) + + char **strv_copy(char * const *l); +diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h +index bff8f5f..27677af 100644 +--- a/src/shared/udev-util.h ++++ b/src/shared/udev-util.h +@@ -24,11 +24,11 @@ + #include "udev.h" + #include "util.h" + +-define_trivial_cleanup_func(struct udev*, udev_unref) +-define_trivial_cleanup_func(struct udev_device*, udev_device_unref) +-define_trivial_cleanup_func(struct udev_enumerate*, udev_enumerate_unref) +-define_trivial_cleanup_func(struct udev_event*, udev_event_unref) +-define_trivial_cleanup_func(struct udev_rules*, udev_rules_unref) ++DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref); ++DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_device*, udev_device_unref); ++DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_enumerate*, udev_enumerate_unref); ++DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_event*, udev_event_unref); ++DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_rules*, udev_rules_unref); + + #define _cleanup_udev_unref_ _cleanup_(udev_unrefp) + #define _cleanup_udev_device_unref_ _cleanup_(udev_device_unrefp) +diff --git a/src/shared/util.h b/src/shared/util.h +index 5a9bc99..d68f385 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -558,11 +558,12 @@ static inline void freep(void *p) { + free(*(void**) p); + } + +-#define define_trivial_cleanup_func(type, func) \ +- static inline void func##p(type *p) { \ +- if (*p) \ +- func(*p); \ +- } \ ++#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ ++ static inline void func##p(type *p) { \ ++ if (*p) \ ++ func(*p); \ ++ } \ ++ struct __useless_struct_to_allow_trailing_semicolon__ + + static inline void closep(int *fd) { + if (*fd >= 0) +@@ -573,10 +574,10 @@ static inline void umaskp(mode_t *u) { + umask(*u); + } + +-define_trivial_cleanup_func(FILE*, fclose) +-define_trivial_cleanup_func(FILE*, pclose) +-define_trivial_cleanup_func(DIR*, closedir) +-define_trivial_cleanup_func(FILE*, endmntent) ++DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, fclose); ++DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, pclose); ++DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir); ++DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, endmntent); + + #define _cleanup_free_ _cleanup_(freep) + #define _cleanup_close_ _cleanup_(closep) +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index df6c99a..9917514 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -999,7 +999,7 @@ static void item_free(Item *i) { + free(i); + } + +-define_trivial_cleanup_func(Item*, item_free) ++DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free); + #define _cleanup_item_free_ _cleanup_(item_freep) + + static bool item_equal(Item *a, Item *b) { diff --git a/SOURCES/0346-man-sd_journal_send-does-nothing-when-journald-is-no.patch b/SOURCES/0346-man-sd_journal_send-does-nothing-when-journald-is-no.patch new file mode 100644 index 0000000..9e76321 --- /dev/null +++ b/SOURCES/0346-man-sd_journal_send-does-nothing-when-journald-is-no.patch @@ -0,0 +1,31 @@ +From 4dd641efa81998ed328fd2c74be8beee7aa32dad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 9 May 2014 08:39:25 -0400 +Subject: [PATCH] man: sd_journal_send does nothing when journald is not + available + +https://bugzilla.redhat.com/show_bug.cgi?id=1096067 + +(cherry-picked from bdf9fc1a940e342afb7a78075984419cb3bc3135) + +Resolves: #1147524 +--- + man/sd_journal_print.xml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml +index a716cc3..d934b0a 100644 +--- a/man/sd_journal_print.xml ++++ b/man/sd_journal_print.xml +@@ -218,6 +218,11 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( + errno-style error code. The + errno3 + variable itself is not altered. ++ ++ If ++ systemd-journald8 ++ is not running (the socket is not present), those ++ functions do nothing, and also return 0. + + + diff --git a/SOURCES/0347-man-clarify-that-the-ExecReload-command-should-be-sy.patch b/SOURCES/0347-man-clarify-that-the-ExecReload-command-should-be-sy.patch new file mode 100644 index 0000000..19bf9a7 --- /dev/null +++ b/SOURCES/0347-man-clarify-that-the-ExecReload-command-should-be-sy.patch @@ -0,0 +1,40 @@ +From 191c7ee3810782c8968def5b23e46b442a8f530d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 May 2014 01:33:22 +0200 +Subject: [PATCH] man: clarify that the ExecReload= command should be + synchronous + +http://lists.freedesktop.org/archives/systemd-devel/2014-May/019054.html + +(cherry-picked from 33169701b0640d3629d4c36cf8c71dc26d2cb7e1) + +Resolves: #1147524 +--- + man/systemd.service.xml | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index 80d6951..8df4b87 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -525,6 +525,20 @@ ExecStart=/bin/echo $ONE $TWO ${TWO} + following: + + /bin/kill -HUP $MAINPID ++ ++ Note however that reloading a ++ daemon by sending a signal (as with ++ the example line above) is usually not ++ a good choice, because this is an ++ asynchronous operation and hence not ++ suitable to order reloads of multiple ++ services against each other. It is ++ strongly recommended to set ++ ExecReload= to a ++ command that no only triggers a ++ configuration reload of the daemon, ++ but also synchronously waits for it ++ complete. + + + diff --git a/SOURCES/0348-conf-parser-never-consider-it-an-error-if-we-cannot-.patch b/SOURCES/0348-conf-parser-never-consider-it-an-error-if-we-cannot-.patch new file mode 100644 index 0000000..c64d9d5 --- /dev/null +++ b/SOURCES/0348-conf-parser-never-consider-it-an-error-if-we-cannot-.patch @@ -0,0 +1,30 @@ +From 762f7d479be5217a2109dbf0f97fe82e1155e6ee Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 22 May 2014 16:47:46 +0900 +Subject: [PATCH] conf-parser: never consider it an error if we cannot load a + drop-in file because it is missing + +After all, we want to be able to boot with /etc empty one day... + +(cherry-picked from 9f43a07f10639c5b41b45448e551e43914eefe32) + +Resolves: #1147524 +--- + src/shared/conf-parser.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c +index 6085d33..db71168 100644 +--- a/src/shared/conf-parser.c ++++ b/src/shared/conf-parser.c +@@ -320,8 +320,8 @@ int config_parse(const char *unit, + if (!f) { + f = ours = fopen(filename, "re"); + if (!f) { +- log_error("Failed to open configuration file '%s': %m", filename); +- return -errno; ++ log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR, "Failed to open configuration file '%s': %m", filename); ++ return errno == ENOENT ? 0 : -errno; + } + } + diff --git a/SOURCES/0349-socket-properly-handle-if-our-service-vanished-durin.patch b/SOURCES/0349-socket-properly-handle-if-our-service-vanished-durin.patch new file mode 100644 index 0000000..3b16964 --- /dev/null +++ b/SOURCES/0349-socket-properly-handle-if-our-service-vanished-durin.patch @@ -0,0 +1,30 @@ +From e1c7d367b8523ec8c9ef3deb81a1cfd879944171 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 22 May 2014 16:56:21 +0900 +Subject: [PATCH] socket: properly handle if our service vanished during + runtime + +(cherry-picked from 640ace4a8de907994a1b95f6d368c3e6a8fcf60f) + +Resolves: #1147524 +--- + src/core/socket.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/core/socket.c b/src/core/socket.c +index 35fc204..958d063 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1610,6 +1610,12 @@ static void socket_enter_running(Socket *s, int cfd) { + } + + if (!pending) { ++ if (!UNIT_ISSET(s->service)) { ++ log_error_unit(UNIT(s)->id, "%s: service to activate vanished, refusing activation.", UNIT(s)->id); ++ r = -ENOENT; ++ goto fail; ++ } ++ + r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL); + if (r < 0) + goto fail; diff --git a/SOURCES/0350-Do-not-unescape-unit-names-in-Install-section.patch b/SOURCES/0350-Do-not-unescape-unit-names-in-Install-section.patch new file mode 100644 index 0000000..14c7012 --- /dev/null +++ b/SOURCES/0350-Do-not-unescape-unit-names-in-Install-section.patch @@ -0,0 +1,27 @@ +From 5db48e390d876be7e00c3403953d7fe80ff6c87b Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 26 May 2014 20:09:45 +0200 +Subject: [PATCH] Do not unescape unit names in [Install] section + +https://bugs.freedesktop.org/show_bug.cgi?id=49316 + +(cherry-picked from 000f6e5667eb4f73e137cbd0d7395a9f9db7728a) + +Resolves: #1147524 +--- + src/shared/conf-parser.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c +index db71168..b356687 100644 +--- a/src/shared/conf-parser.c ++++ b/src/shared/conf-parser.c +@@ -670,7 +670,7 @@ int config_parse_strv(const char *unit, + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + _cleanup_free_ char *n; + +- n = cunescape_length(w, l); ++ n = strndup(w, l); + if (!n) + return log_oom(); + diff --git a/SOURCES/0351-util-ignore_file-should-not-allow-files-ending-with.patch b/SOURCES/0351-util-ignore_file-should-not-allow-files-ending-with.patch new file mode 100644 index 0000000..80fdab8 --- /dev/null +++ b/SOURCES/0351-util-ignore_file-should-not-allow-files-ending-with.patch @@ -0,0 +1,29 @@ +From 45914d5301d694730965872962fc71b9d11f9b3d Mon Sep 17 00:00:00 2001 +From: Thomas Hindoe Paaboel Andersen +Date: Sat, 31 May 2014 21:36:23 +0200 +Subject: [PATCH] util: ignore_file should not allow files ending with '~' + +ignore_file currently allows any file ending with '~' while it +seems that the opposite was intended: +a228a22fda4faa9ecb7c5a5e499980c8ae5d2a08 + +(cherry-picked from 93f1a06374e335e8508d89e1bdaadf45be6ab777) + +Resolves: #1147524 +--- + src/shared/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/util.c b/src/shared/util.c +index 9f25b15..1590c3a 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -1502,7 +1502,7 @@ bool ignore_file(const char *filename) { + assert(filename); + + if (endswith(filename, "~")) +- return false; ++ return true; + + return ignore_file_allow_backup(filename); + } diff --git a/SOURCES/0352-core-fix-invalid-free-in-killall.patch b/SOURCES/0352-core-fix-invalid-free-in-killall.patch new file mode 100644 index 0000000..93a0721 --- /dev/null +++ b/SOURCES/0352-core-fix-invalid-free-in-killall.patch @@ -0,0 +1,33 @@ +From 250a6ce38605fe172541fb75e8d64132f2ec38d4 Mon Sep 17 00:00:00 2001 +From: Andreas Henriksson +Date: Fri, 13 Jun 2014 18:48:19 +0200 +Subject: [PATCH] core: fix invalid free() in killall() + +static int killall(....) in ./src/core/killall.c tries to get "s" +initialized by calling get_process_comm(...) which calls +read_one_line_file(...) which if it fails will mean it is left +uninitialized. +It is then used in argument to strna(s) call where it is +dereferenced(!), in addition to nothing else initializing it before +the scope it is in finishes. + +(cherry-picked from 3e09eb5c83e56bc0184bd9d9c44f76047464f77c) + +Resolves: #1147524 +--- + src/core/killall.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/killall.c b/src/core/killall.c +index e395050..967dac0 100644 +--- a/src/core/killall.c ++++ b/src/core/killall.c +@@ -167,7 +167,7 @@ static int killall(int sig, Set *pids) { + continue; + + if (sig == SIGKILL) { +- _cleanup_free_ char *s; ++ _cleanup_free_ char *s = NULL; + + get_process_comm(pid, &s); + log_notice("Sending SIGKILL to PID %lu (%s).", (unsigned long) pid, strna(s)); diff --git a/SOURCES/0353-install-fix-invalid-free-in-unit_file_mask.patch b/SOURCES/0353-install-fix-invalid-free-in-unit_file_mask.patch new file mode 100644 index 0000000..c964279 --- /dev/null +++ b/SOURCES/0353-install-fix-invalid-free-in-unit_file_mask.patch @@ -0,0 +1,31 @@ +From b1de3eb93bfdc4cf3872d9e1005166bb9867b0b2 Mon Sep 17 00:00:00 2001 +From: Andreas Henriksson +Date: Fri, 13 Jun 2014 18:48:18 +0200 +Subject: [PATCH] install: fix invalid free() in unit_file_mask() + +int unit_file_mask(...) in ./src/shared/install.c calls +get_config_path(...) which can in 4 error cases return without setting +"ret", and thus "prefix" can be uninitialized when unit_file_mask(...) +finishes (which it does directly after the error is returned from +get_config_path(...)). + +(cherry-picked from 223217749e57996336d5730b0a28716cca56d45d) + +Resolves: #1147524 +--- + src/shared/install.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index dd5e22b..1662c5f 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -598,7 +598,7 @@ int unit_file_mask( + unsigned *n_changes) { + + char **i; +- _cleanup_free_ char *prefix; ++ _cleanup_free_ char *prefix = NULL; + int r; + + assert(scope >= 0); diff --git a/SOURCES/0354-unit-name-fix-detection-of-unit-templates-instances.patch b/SOURCES/0354-unit-name-fix-detection-of-unit-templates-instances.patch new file mode 100644 index 0000000..0305b54 --- /dev/null +++ b/SOURCES/0354-unit-name-fix-detection-of-unit-templates-instances.patch @@ -0,0 +1,59 @@ +From 14b393f9d9b7caffcd48557c6bd4eb63de4942ad Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 16 Jun 2014 17:01:26 +0200 +Subject: [PATCH] unit-name: fix detection of unit templates/instances + +We need to check for the last dot, not the first one in a unit name, for +the suffix. Correct that. + +(cherry-picked from 6ef9eeed61a291cc42b7d911f5cf5a4deca742a3) + +Resolves: #1147524 +--- + src/shared/unit-name.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c +index bc8094d..577f7e7 100644 +--- a/src/shared/unit-name.c ++++ b/src/shared/unit-name.c +@@ -334,7 +334,7 @@ char *unit_name_path_unescape(const char *f) { + } + + bool unit_name_is_template(const char *n) { +- const char *p; ++ const char *p, *e; + + assert(n); + +@@ -342,11 +342,15 @@ bool unit_name_is_template(const char *n) { + if (!p) + return false; + +- return p[1] == '.'; ++ e = strrchr(p+1, '.'); ++ if (!e) ++ return false; ++ ++ return e == p + 1; + } + + bool unit_name_is_instance(const char *n) { +- const char *p; ++ const char *p, *e; + + assert(n); + +@@ -354,7 +358,11 @@ bool unit_name_is_instance(const char *n) { + if (!p) + return false; + +- return p[1] != '.'; ++ e = strrchr(p+1, '.'); ++ if (!e) ++ return false; ++ ++ return e > p + 1; + } + + char *unit_name_replace_instance(const char *f, const char *i) { diff --git a/SOURCES/0355-journald-make-MaxFileSec-really-default-to-1month.patch b/SOURCES/0355-journald-make-MaxFileSec-really-default-to-1month.patch new file mode 100644 index 0000000..0206426 --- /dev/null +++ b/SOURCES/0355-journald-make-MaxFileSec-really-default-to-1month.patch @@ -0,0 +1,36 @@ +From 72c01067d266a49796b5c64018b2d8c92840255a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20Bartoszkiewicz?= +Date: Thu, 26 Jun 2014 22:11:35 +0200 +Subject: [PATCH] journald: make MaxFileSec really default to 1month + +journald.conf(5) states that the default for MaxFileSec is one month, +but the code didn't respect that. + +(cherry-picked from e150e82097211f09b911c7784a89ef9efed713ca) + +Resolves: #1147524 +--- + src/journal/journald-server.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 1fcb3d5..a289a50 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -67,6 +67,7 @@ + #define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE) + #define DEFAULT_RATE_LIMIT_INTERVAL (30*USEC_PER_SEC) + #define DEFAULT_RATE_LIMIT_BURST 1000 ++#define DEFAULT_MAX_FILE_USEC USEC_PER_MONTH + + #define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC) + +@@ -1476,6 +1477,8 @@ int server_init(Server *s) { + + s->forward_to_syslog = true; + ++ s->max_file_usec = DEFAULT_MAX_FILE_USEC; ++ + s->max_level_store = LOG_DEBUG; + s->max_level_syslog = LOG_DEBUG; + s->max_level_kmsg = LOG_NOTICE; diff --git a/SOURCES/0356-bootchart-it-s-not-OK-to-return-1-from-a-main-progra.patch b/SOURCES/0356-bootchart-it-s-not-OK-to-return-1-from-a-main-progra.patch new file mode 100644 index 0000000..d999614 --- /dev/null +++ b/SOURCES/0356-bootchart-it-s-not-OK-to-return-1-from-a-main-progra.patch @@ -0,0 +1,27 @@ +From 131d8e2cf65eb3c6dfc691676ca6f0a55ae44d71 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 11 Aug 2014 18:23:47 +0200 +Subject: [PATCH] bootchart: it's not OK to return -1 from a main program + +(cherry-picked from 4155f7d4be5053d5f34a26e5437fd85e1fe00fa3) + +Resolves: #1147524 +--- + src/bootchart/bootchart.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c +index 14ccd3e..4a8d6c2 100644 +--- a/src/bootchart/bootchart.c ++++ b/src/bootchart/bootchart.c +@@ -346,8 +346,8 @@ int main(int argc, char *argv[]) { + + sampledata = new0(struct list_sample_data, 1); + if (sampledata == NULL) { +- log_error("Failed to allocate memory for a node: %m"); +- return -1; ++ log_oom(); ++ return EXIT_FAILURE; + } + + sampledata->sampletime = gettime_ns(); diff --git a/SOURCES/0357-journald-Fix-off-by-one-error-in-Missed-X-kernel-mes.patch b/SOURCES/0357-journald-Fix-off-by-one-error-in-Missed-X-kernel-mes.patch new file mode 100644 index 0000000..de08892 --- /dev/null +++ b/SOURCES/0357-journald-Fix-off-by-one-error-in-Missed-X-kernel-mes.patch @@ -0,0 +1,30 @@ +From db22c5d0a16eb30b78cdeef927df8c2d0b895ef1 Mon Sep 17 00:00:00 2001 +From: Eelco Dolstra +Date: Wed, 6 Aug 2014 13:14:51 +0200 +Subject: [PATCH] journald: Fix off-by-one error in "Missed X kernel messages" + warning + +On receiving a message, "kernel_seqnum" is set to "serial + 1". So +subtracting 1 will cause messages like "Missed 0 kernel messages", +which should be "Missed 1 kernel messages". + +(cherry-picked from b9c488f60050248b35640f28e4d00958702ba1c3) + +Resolves: #1147524 +--- + src/journal/journald-kmsg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index e393cb7..0073a33 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -152,7 +152,7 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) { + /* Did we lose any? */ + if (serial > *s->kernel_seqnum) + server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %"PRIu64" kernel messages", +- serial - *s->kernel_seqnum - 1); ++ serial - *s->kernel_seqnum); + + /* Make sure we never read this one again. Note that + * we always store the next message serial we expect diff --git a/SOURCES/0358-man-drop-references-to-removed-and-obsolete-systemct.patch b/SOURCES/0358-man-drop-references-to-removed-and-obsolete-systemct.patch new file mode 100644 index 0000000..66f3547 --- /dev/null +++ b/SOURCES/0358-man-drop-references-to-removed-and-obsolete-systemct.patch @@ -0,0 +1,37 @@ +From 38786feb38a6d7b8a3fa3e5d9a184f06d8fd7802 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 15 Aug 2014 02:41:14 +0200 +Subject: [PATCH] man: drop references to removed and obsolete 'systemctl load' + command + +(cherry-picked from d0a3fb7556d77c44c2bc38a560e99d4ad0abcf33) + +Resolves: #1147524 +--- + man/systemctl.xml | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index f68b606..d2430ee 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -602,8 +602,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service + file. + + This command should not be confused with the +- daemon-reload or load +- commands. ++ daemon-reload command. + + + +@@ -1163,8 +1162,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service + tree. While the daemon is being reloaded, all sockets systemd + listens on on behalf of user configuration will stay + accessible. This command should not be confused +- with the load or +- reload commands. ++ with the reload command. + + + diff --git a/SOURCES/0359-units-fix-BindsTo-logic-when-applied-relative-to-ser.patch b/SOURCES/0359-units-fix-BindsTo-logic-when-applied-relative-to-ser.patch new file mode 100644 index 0000000..85804ad --- /dev/null +++ b/SOURCES/0359-units-fix-BindsTo-logic-when-applied-relative-to-ser.patch @@ -0,0 +1,94 @@ +From 469d48cf685bd0157fa44ff7ebd3bd0302746ab0 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 18 Aug 2014 22:21:42 +0200 +Subject: [PATCH] units: fix BindsTo= logic when applied relative to services + with Type=oneshot +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Start jobs for Type=oneshot units are successful when the unit state +transition activating → inactive took place. In such a case all units +that BindsTo= on it previously would continue to run, even though the unit +they dependet on was actually already gone. + +(cherry-picked from ff50244582bf69e8489bba6ce59a21663d7f8274) + +Resolves: #1147524 +--- + src/core/unit.c | 48 ++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 44 insertions(+), 4 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index b51e351..f221b9a 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1302,12 +1302,44 @@ static void unit_check_unneeded(Unit *u) { + if (unit_active_or_pending(other)) + return; + +- log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id); ++ log_info_unit(u->id, "Unit %s is not needed anymore. Stopping.", u->id); + + /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ + manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL); + } + ++static void unit_check_binds_to(Unit *u) { ++ bool stop = false; ++ Unit *other; ++ Iterator i; ++ ++ assert(u); ++ ++ if (u->job) ++ return; ++ ++ if (unit_active_state(u) != UNIT_ACTIVE) ++ return; ++ ++ SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i) { ++ if (other->job) ++ continue; ++ ++ if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) ++ continue; ++ ++ stop = true; ++ } ++ ++ if (!stop) ++ return; ++ ++ log_info_unit(u->id, "Unit %s is bound to inactive service. Stopping, too.", u->id); ++ ++ /* A unit we need to run is gone. Sniff. Let's stop this. */ ++ manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL); ++} ++ + static void retroactively_start_dependencies(Unit *u) { + Iterator i; + Unit *other; +@@ -1611,11 +1643,19 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su + manager_recheck_journal(m); + unit_trigger_notify(u); + +- /* Maybe we finished startup and are now ready for being +- * stopped because unneeded? */ +- if (u->manager->n_reloading <= 0) ++ if (u->manager->n_reloading <= 0) { ++ /* Maybe we finished startup and are now ready for ++ * being stopped because unneeded? */ + unit_check_unneeded(u); + ++ /* Maybe we finished startup, but something we needed ++ * has vanished? Let's die then. (This happens when ++ * something BindsTo= to a Type=oneshot unit, as these ++ * units go directly from starting to inactive, ++ * without ever entering started.) */ ++ unit_check_binds_to(u); ++ } ++ + unit_add_to_dbus_queue(u); + unit_add_to_gc_queue(u); + } diff --git a/SOURCES/0360-core-don-t-allow-enabling-if-unit-is-masked.patch b/SOURCES/0360-core-don-t-allow-enabling-if-unit-is-masked.patch new file mode 100644 index 0000000..37ebbf8 --- /dev/null +++ b/SOURCES/0360-core-don-t-allow-enabling-if-unit-is-masked.patch @@ -0,0 +1,36 @@ +From 0fb9d07643a9e9e84c61a6a62f4c2b7d52e4d96f Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Tue, 7 Oct 2014 13:27:38 +0200 +Subject: [PATCH] core: don't allow enabling if unit is masked + +(cherry-picked from f7101b7368dfe41dbc8b7203e06133cccb589c01) + +Resolves: #1149299 +--- + src/shared/install.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 1662c5f..7a29798 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1520,6 +1520,19 @@ int unit_file_enable( + return r; + + STRV_FOREACH(i, files) { ++ UnitFileState state; ++ ++ state = unit_file_get_state(scope, root_dir, *i); ++ if (state < 0) { ++ log_error("Failed to get unit file state for %s: %s", *i, strerror(-state)); ++ return state; ++ } ++ ++ if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) { ++ log_error("Failed to enable unit: Unit %s is masked", *i); ++ return -ENOTSUP; ++ } ++ + r = install_info_add_auto(&c, *i); + if (r < 0) + return r; diff --git a/SOURCES/0361-man-systemctl-document-enable-on-masked-units.patch b/SOURCES/0361-man-systemctl-document-enable-on-masked-units.patch new file mode 100644 index 0000000..adeb1d9 --- /dev/null +++ b/SOURCES/0361-man-systemctl-document-enable-on-masked-units.patch @@ -0,0 +1,35 @@ +From 091b32bd93acd3e7be844684771ab2248b97637b Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 8 Oct 2014 13:43:02 +0200 +Subject: [PATCH] man/systemctl: document enable on masked units + +Related: #1149299 +--- + man/systemctl.xml | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index d2430ee..b894511 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -862,6 +862,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service + the system, or for all future logins of all users, or only this + boot. Note that in the last case, no systemd daemon + configuration is reloaded. ++ ++ Using enable on masked units ++ results in an error. + + + +@@ -999,8 +1002,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service + /dev/null, making it impossible to + start them. This is a stronger version of + disable, since it prohibits all kinds of +- activation of the unit, including manual activation. Use +- this option with care. This honors the ++ activation of the unit, including enablement and manual ++ activation. Use this option with care. This honors the + option, to only mask temporarily + until the next reoobt of the system. + diff --git a/SOURCES/0362-core-do-not-segfault-if-proc-swaps-cannot-be-opened.patch b/SOURCES/0362-core-do-not-segfault-if-proc-swaps-cannot-be-opened.patch new file mode 100644 index 0000000..20d9792 --- /dev/null +++ b/SOURCES/0362-core-do-not-segfault-if-proc-swaps-cannot-be-opened.patch @@ -0,0 +1,54 @@ +From 4537b962be32aa0a2f49741454f168801ed7c683 Mon Sep 17 00:00:00 2001 +From: Matt Mullins +Date: Mon, 24 Feb 2014 15:03:52 -0800 +Subject: [PATCH] core: do not segfault if /proc/swaps cannot be opened + +The refactoring in f84b1b1ff9b1261 ('core: do not segfault if swap +activity happens when /proc/swaps is not open') caused +swap_dispatch_reload and swap_enumerate to continue even if fopen() +failed with ENOENT. + +This should instead be modified to return from swap_dispatch_reload and +swap_enumerate, rather than continuing to load the list of swaps when +m->proc_swaps is NULL. + +https://bugzilla.redhat.com/show_bug.cgi?id=1069393 + +RHEL (and fedora) only + +Resolves: #1151239 +--- + src/core/swap.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/core/swap.c b/src/core/swap.c +index b72034f..36ef88b 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -1075,7 +1075,7 @@ static int open_proc_swaps(Manager *m) { + + m->proc_swaps = fopen("/proc/swaps", "re"); + if (!m->proc_swaps) +- return (errno == ENOENT) ? 0 : -errno; ++ return -errno; + + m->swap_watch.type = WATCH_SWAP; + m->swap_watch.fd = fileno(m->proc_swaps); +@@ -1098,7 +1098,7 @@ int swap_dispatch_reload(Manager *m) { + + r = open_proc_swaps(m); + if (r < 0) +- return r; ++ return (r == -ENOENT) ? 0 : r; + + return swap_fd_event(m, EPOLLPRI); + } +@@ -1251,7 +1251,7 @@ static int swap_enumerate(Manager *m) { + + r = open_proc_swaps(m); + if (r < 0) +- return r; ++ return (r == -ENOENT) ? 0 : r; + + r = swap_load_proc_swaps(m, false); + if (r < 0) diff --git a/SOURCES/0363-man-we-don-t-have-Wanted-dependency.patch b/SOURCES/0363-man-we-don-t-have-Wanted-dependency.patch new file mode 100644 index 0000000..ca23995 --- /dev/null +++ b/SOURCES/0363-man-we-don-t-have-Wanted-dependency.patch @@ -0,0 +1,29 @@ +From 49beb7d21d269f0feeea6a80145e1cde0d499548 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Wed, 15 Oct 2014 09:28:31 +0200 +Subject: [PATCH] man: we don't have 'Wanted' dependency + +(Cherry-picked from 3e883473a0f36c220fc45ecf61d6878c9ac308b4) + +Resolves: #1152487 +--- + man/systemd.unit.xml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index c500953..62db219 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -175,10 +175,10 @@ + foo.service.wants/ may exist. All + unit files symlinked from such a directory are + implicitly added as dependencies of type +- Wanted= to the unit. This is useful ++ Wants= to the unit. This is useful + to hook units into the start-up of other units, + without having to modify their unit files. For details +- about the semantics of Wanted=, see ++ about the semantics of Wants=, see + below. The preferred way to create symlinks in the + .wants/ directory of a unit file + is with the enable command of the diff --git a/SOURCES/0364-environment-append-unit_id-to-error-messages-regardi.patch b/SOURCES/0364-environment-append-unit_id-to-error-messages-regardi.patch new file mode 100644 index 0000000..c06f01d --- /dev/null +++ b/SOURCES/0364-environment-append-unit_id-to-error-messages-regardi.patch @@ -0,0 +1,132 @@ +From 432496f644241d282d706285181a0b94c7c788f5 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Fri, 17 Oct 2014 11:46:01 +0200 +Subject: [PATCH] environment: append unit_id to error messages regarding + EnvironmentFile + +(cherry-picked from 7491ccf2cb237a2a88b831b2c7374ba2bb255cba) +Conflicts: + src/core/execute.c + +Resolves: #1147691 +--- + src/core/execute.c | 6 +++--- + src/core/execute.h | 2 +- + src/shared/env-util.c | 13 ++++++++++--- + src/shared/env-util.h | 2 +- + src/test/test-fileio.c | 2 +- + 5 files changed, 16 insertions(+), 9 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 0894156..be99149 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1071,7 +1071,7 @@ int exec_spawn(ExecCommand *command, + } else + socket_fd = -1; + +- r = exec_context_load_environment(context, &files_env); ++ r = exec_context_load_environment(context, unit_id, &files_env); + if (r < 0) { + log_struct_unit(LOG_ERR, + unit_id, +@@ -1776,7 +1776,7 @@ void exec_command_free_array(ExecCommand **c, unsigned n) { + } + } + +-int exec_context_load_environment(const ExecContext *c, char ***l) { ++int exec_context_load_environment(const ExecContext *c, const char *unit_id, char ***l) { + char **i, **r = NULL; + + assert(c); +@@ -1833,7 +1833,7 @@ int exec_context_load_environment(const ExecContext *c, char ***l) { + } + /* Log invalid environment variables with filename */ + if (p) +- p = strv_env_clean_log(p, pglob.gl_pathv[n]); ++ p = strv_env_clean_log(p, unit_id, pglob.gl_pathv[n]); + + if (r == NULL) + r = p; +diff --git a/src/core/execute.h b/src/core/execute.h +index 5055890..b66bd5f 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -200,7 +200,7 @@ void exec_context_tmp_dirs_done(ExecContext *c); + void exec_context_dump(ExecContext *c, FILE* f, const char *prefix); + void exec_context_tty_reset(const ExecContext *context); + +-int exec_context_load_environment(const ExecContext *c, char ***l); ++int exec_context_load_environment(const ExecContext *c, const char *unit_id, char ***l); + + bool exec_context_may_touch_console(ExecContext *c); + void exec_context_serialize(const ExecContext *c, Unit *u, FILE *f); +diff --git a/src/shared/env-util.c b/src/shared/env-util.c +index 7976881..5b5da48 100644 +--- a/src/shared/env-util.c ++++ b/src/shared/env-util.c +@@ -29,6 +29,13 @@ + #include "env-util.h" + #include "def.h" + ++#define log_full_unit(level, unit, ...) log_meta_object(level, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__) ++#define log_debug_unit(unit, ...) log_full_unit(LOG_DEBUG, unit, __VA_ARGS__) ++#define log_info_unit(unit, ...) log_full_unit(LOG_INFO, unit, __VA_ARGS__) ++#define log_notice_unit(unit, ...) log_full_unit(LOG_NOTICE, unit, __VA_ARGS__) ++#define log_warning_unit(unit, ...) log_full_unit(LOG_WARNING, unit, __VA_ARGS__) ++#define log_error_unit(unit, ...) log_full_unit(LOG_ERR, unit, __VA_ARGS__) ++ + #define VALID_CHARS_ENV_NAME \ + DIGITS LETTERS \ + "_" +@@ -375,7 +382,7 @@ char *strv_env_get(char **l, const char *name) { + return strv_env_get_n(l, name, strlen(name)); + } + +-char **strv_env_clean_log(char **e, const char *message) { ++char **strv_env_clean_log(char **e, const char *unit_id, const char *message) { + char **p, **q; + int k = 0; + +@@ -385,7 +392,7 @@ char **strv_env_clean_log(char **e, const char *message) { + + if (!env_assignment_is_valid(*p)) { + if (message) +- log_error("Ignoring invalid environment '%s': %s", *p, message); ++ log_error_unit(unit_id, "Ignoring invalid environment '%s': %s", *p, message); + free(*p); + continue; + } +@@ -412,5 +419,5 @@ char **strv_env_clean_log(char **e, const char *message) { + } + + char **strv_env_clean(char **e) { +- return strv_env_clean_log(e, NULL); ++ return strv_env_clean_log(e, NULL, NULL); + } +diff --git a/src/shared/env-util.h b/src/shared/env-util.h +index 8d2114b..5ea82ad 100644 +--- a/src/shared/env-util.h ++++ b/src/shared/env-util.h +@@ -30,7 +30,7 @@ bool env_assignment_is_valid(const char *e); + + bool strv_env_is_valid(char **e); + char **strv_env_clean(char **l); +-char **strv_env_clean_log(char **e, const char *message); ++char **strv_env_clean_log(char **e, const char *unit_id, const char *message); + + bool strv_env_name_or_assignment_is_valid(char **l); + +diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c +index 06f3e28..c92bb6e 100644 +--- a/src/test/test-fileio.c ++++ b/src/test/test-fileio.c +@@ -88,7 +88,7 @@ static void test_parse_env_file(void) { + assert_se(streq(a[9], "ten=")); + assert_se(a[10] == NULL); + +- strv_env_clean_log(a, "test"); ++ strv_env_clean_log(a, NULL, "test"); + + k = 0; + STRV_FOREACH(i, b) { diff --git a/SOURCES/0365-udevd-add-event-timeout-commandline-option.patch b/SOURCES/0365-udevd-add-event-timeout-commandline-option.patch new file mode 100644 index 0000000..67e1048 --- /dev/null +++ b/SOURCES/0365-udevd-add-event-timeout-commandline-option.patch @@ -0,0 +1,125 @@ +From 3f13db324c715ab9dd0a514490160448ed3ae7ee Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Tue, 29 Jul 2014 09:06:14 +0200 +Subject: [PATCH] udevd: add --event-timeout commandline option + +Some events take longer than the default 30 seconds. Killing those +events will leave the machine halfway configured. + +Add a commandline option '--event-timeout' to handle these cases. + +(cherry-picked from 9719859c07aa13539ed2cd4b31972cd30f678543) + +Conflicts: + src/udev/udevd.c + +Resolves: #1154778 +--- + man/systemd-udevd.service.xml | 19 +++++++++++++++++++ + src/udev/udevd.c | 14 ++++++++++++-- + 2 files changed, 31 insertions(+), 2 deletions(-) + +diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml +index 7fce300..c3a2cb9 100644 +--- a/man/systemd-udevd.service.xml ++++ b/man/systemd-udevd.service.xml +@@ -42,6 +42,7 @@ + + + ++ + + + +@@ -90,6 +91,15 @@ + + + ++ ++ ++ Wait for the event to finish up to the given ++ number of seconds. After this time the event will ++ be terminated. Default is 30. ++ ++ ++ ++ + + + Specify when systemd-udevd should resolve names of users and groups. +@@ -155,6 +165,15 @@ + + + ++ udev.event-timeout= ++ rd.udev.event-timeout= ++ ++ Wait for events to finish up to the given number ++ of seconds. This option might be useful if events are ++ terminated due to a timeout in large configurations. ++ ++ ++ + net.ifnames= + + Network interfaces are renamed to give them predictable names +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 3d5feb4..6241549 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -72,6 +72,7 @@ static bool reload; + static int children; + static int children_max; + static int exec_delay; ++static int event_timeout = 30; + static sigset_t sigmask_orig; + static UDEV_LIST(event_list); + static UDEV_LIST(worker_list); +@@ -287,6 +288,9 @@ static void worker_new(struct event *event) + if (exec_delay > 0) + udev_event->exec_delay = exec_delay; + ++ if (event_timeout != 30) ++ udev_event->timeout_usec = event_timeout * USEC_PER_SEC; ++ + /* apply rules, create node, symlinks */ + udev_event_execute_rules(udev_event, rules, &sigmask_orig); + +@@ -884,6 +888,8 @@ static void kernel_cmdline_options(struct udev *udev) + children_max = strtoul(opt + 18, NULL, 0); + } else if (startswith(opt, "udev.exec-delay=")) { + exec_delay = strtoul(opt + 16, NULL, 0); ++ } else if (startswith(opt, "udev.event-timeout=")) { ++ event_timeout = strtoul(opt + 16, NULL, 0); + } + + free(s); +@@ -903,6 +909,7 @@ int main(int argc, char *argv[]) + { "debug", no_argument, NULL, 'D' }, + { "children-max", required_argument, NULL, 'c' }, + { "exec-delay", required_argument, NULL, 'e' }, ++ { "event-timeout", required_argument, NULL, 't' }, + { "resolve-names", required_argument, NULL, 'N' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, +@@ -946,6 +953,9 @@ int main(int argc, char *argv[]) + case 'e': + exec_delay = strtoul(optarg, NULL, 0); + break; ++ case 't': ++ event_timeout = strtoul(optarg, NULL, 0); ++ break; + case 'D': + debug = true; + log_set_max_level(LOG_DEBUG); +@@ -1278,8 +1288,8 @@ int main(int argc, char *argv[]) + if (worker->state != WORKER_RUNNING) + continue; + +- if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) { +- log_error("worker [%u] %s timeout; kill it\n", worker->pid, ++ if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout * USEC_PER_SEC) { ++ log_error("worker [%u] %s timeout; kill it", worker->pid, + worker->event ? worker->event->devpath : ""); + kill(worker->pid, SIGKILL); + worker->state = WORKER_KILLED; diff --git a/SOURCES/0366-selinux-fix-potential-double-free-crash-in-child-pro.patch b/SOURCES/0366-selinux-fix-potential-double-free-crash-in-child-pro.patch new file mode 100644 index 0000000..389e24f --- /dev/null +++ b/SOURCES/0366-selinux-fix-potential-double-free-crash-in-child-pro.patch @@ -0,0 +1,40 @@ +From 161ad7deb00e31cb47fdc29f2e795690ffa66be4 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 13 Oct 2014 13:41:06 +0200 +Subject: [PATCH] selinux: fix potential double free crash in child process + +Before returning from function we should reset ret to NULL, thus cleanup +function is nop. + +Also context_str() returns pointer to a string containing context but not a +copy, hence we must make copy it explicitly. + +Related: #1113790 +--- + src/shared/label.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/shared/label.c b/src/shared/label.c +index 8f7dfb4..52aea4f 100644 +--- a/src/shared/label.c ++++ b/src/shared/label.c +@@ -270,7 +270,8 @@ int label_get_child_mls_label(int socket_fd, const char *exe, char **label) { + } + + freecon(mycon); +- mycon = context_str(bcon); ++ mycon = NULL; ++ mycon = strdup(context_str(bcon)); + if (!mycon) { + r = -errno; + goto out; +@@ -284,8 +285,8 @@ int label_get_child_mls_label(int socket_fd, const char *exe, char **label) { + } + + *label = ret; ++ ret = NULL; + r = 0; +- + out: + if (r < 0 && security_getenforce() == 1) + return r; diff --git a/SOURCES/0367-selinux-pass-flag-to-correct-exec_spawn.patch b/SOURCES/0367-selinux-pass-flag-to-correct-exec_spawn.patch new file mode 100644 index 0000000..ccdb2c0 --- /dev/null +++ b/SOURCES/0367-selinux-pass-flag-to-correct-exec_spawn.patch @@ -0,0 +1,42 @@ +From c230e5e8efe72cf4137bf29a197059e5a23bb532 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 13 Oct 2014 13:57:08 +0200 +Subject: [PATCH] selinux: pass flag to correct exec_spawn + +We want to spawn service with label passed by remote peer and not processes +spawned by socket unit itself. + +RHEL-only patch + +Related: #1113790 +--- + src/core/service.c | 2 +- + src/core/socket.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 7ef2b3a..635a953 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1867,7 +1867,7 @@ static int service_spawn( + apply_chroot, + apply_tty_stdin, + UNIT(s)->manager->confirm_spawn, +- false, ++ s->socket_fd_selinux_context_net, + UNIT(s)->manager->cgroup_supported, + path, + UNIT(s)->id, +diff --git a/src/core/socket.c b/src/core/socket.c +index 958d063..1a91700 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1234,7 +1234,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + true, + true, + UNIT(s)->manager->confirm_spawn, +- s->selinux_context_from_net, ++ false, + UNIT(s)->manager->cgroup_supported, + UNIT(s)->cgroup_path, + UNIT(s)->id, diff --git a/SOURCES/0368-selinux-set-selinux-context-applied-on-exec-before-c.patch b/SOURCES/0368-selinux-set-selinux-context-applied-on-exec-before-c.patch new file mode 100644 index 0000000..2cffafb --- /dev/null +++ b/SOURCES/0368-selinux-set-selinux-context-applied-on-exec-before-c.patch @@ -0,0 +1,89 @@ +From e7c4dc07d35a10dc90f013572da6d25d17311d0a Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 13 Oct 2014 16:12:30 +0200 +Subject: [PATCH] selinux: set selinux context applied on exec() before closing + all fds + +We need original socket_fd around otherwise label_get_child_mls_label fails with +-EINVAL return code. + +Related: #1113790 +--- + src/core/execute.c | 56 +++++++++++++++++++++++++++++------------------------- + 1 file changed, 30 insertions(+), 26 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index be99149..06713cc 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1401,6 +1401,36 @@ int exec_spawn(ExecCommand *command, + } + } + ++#ifdef HAVE_SELINUX ++ if (apply_permissions) { ++ if (use_selinux()) { ++ if (context->selinux_context) { ++ err = setexeccon(context->selinux_context); ++ if (err < 0 && !context->selinux_context_ignore) { ++ r = EXIT_SELINUX_CONTEXT; ++ goto fail_child; ++ } ++ } ++ ++ if (selinux_context_net && socket_fd >= 0) { ++ _cleanup_free_ char *label = NULL; ++ ++ err = label_get_child_mls_label(socket_fd, command->path, &label); ++ if (err < 0) { ++ r = EXIT_SELINUX_CONTEXT; ++ goto fail_child; ++ } ++ ++ err = setexeccon(label); ++ if (err < 0) { ++ r = EXIT_SELINUX_CONTEXT; ++ goto fail_child; ++ } ++ } ++ } ++ } ++#endif ++ + /* We repeat the fd closing here, to make sure that + * nothing is leaked from the PAM modules */ + err = close_all_fds(fds, n_fds); +@@ -1474,33 +1504,7 @@ int exec_spawn(ExecCommand *command, + goto fail_child; + } + } +-#ifdef HAVE_SELINUX +- if (use_selinux()) { +- if (context->selinux_context) { +- err = setexeccon(context->selinux_context); +- if (err < 0 && !context->selinux_context_ignore) { +- r = EXIT_SELINUX_CONTEXT; +- goto fail_child; +- } +- } +- +- if (selinux_context_net && socket_fd >= 0) { +- _cleanup_free_ char *label = NULL; + +- err = label_get_child_mls_label(socket_fd, command->path, &label); +- if (err < 0) { +- r = EXIT_SELINUX_CONTEXT; +- goto fail_child; +- } +- +- err = setexeccon(label); +- if (err < 0) { +- r = EXIT_SELINUX_CONTEXT; +- goto fail_child; +- } +- } +- } +-#endif + } + + our_env = new0(char*, 7); diff --git a/SOURCES/0369-logind-use-correct-who-enum-values-with-KillUnit.patch b/SOURCES/0369-logind-use-correct-who-enum-values-with-KillUnit.patch new file mode 100644 index 0000000..ca40c6e --- /dev/null +++ b/SOURCES/0369-logind-use-correct-who-enum-values-with-KillUnit.patch @@ -0,0 +1,43 @@ +From 53e9be6b9c38a7a7d943b01da6898355c535991e Mon Sep 17 00:00:00 2001 +From: Marius Vollmer +Date: Thu, 31 Oct 2013 15:55:07 +0200 +Subject: [PATCH] logind: use correct "who" enum values with KillUnit. + +rhel-only (in upstream fixed during dbus rewrite) + +Resolves: #1155502 +--- + src/login/logind-dbus.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 6cabb7b..4137522 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -116,7 +116,7 @@ + " \n" \ + " \n" \ + " \n" \ +- " \n" \ ++ " \n" \ + " \n" \ + " \n" \ + " \n" \ +@@ -2814,7 +2814,7 @@ int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo + assert(manager); + assert(unit); + +- w = who == KILL_LEADER ? "process" : "cgroup"; ++ w = who == KILL_LEADER ? "main" : "all"; + assert_cc(sizeof(signo) == sizeof(int32_t)); + + r = bus_method_call_with_reply( +@@ -2830,7 +2830,7 @@ int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID); + if (r < 0) { +- log_error("Failed to stop unit %s: %s", unit, bus_error(error, r)); ++ log_error("Failed to kill unit %s: %s", unit, bus_error(error, r)); + return r; + } + diff --git a/SOURCES/0370-logind-always-kill-session-when-termination-is-reque.patch b/SOURCES/0370-logind-always-kill-session-when-termination-is-reque.patch new file mode 100644 index 0000000..f4b8ed3 --- /dev/null +++ b/SOURCES/0370-logind-always-kill-session-when-termination-is-reque.patch @@ -0,0 +1,291 @@ +From c4e4ad079d6c3c18b6f08722ce30796e8c53346b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 8 Feb 2014 20:29:56 -0500 +Subject: [PATCH] logind: always kill session when termination is requested + +KillUserProcesses=yes/no should be ignored when termination is +explicitly requested. + +Conflicts: + src/login/logind-dbus.c + src/login/logind-seat-dbus.c + src/login/logind-session-dbus.c + src/login/logind-session.c + src/login/logind-user-dbus.c + src/login/logind.c + +(cherry-picked (or better say rewritten) from 9bb69af4f2823fdd30902f5ffd959e9b041feb53) + +Resolves: #1155502 +--- + src/login/logind-dbus.c | 6 +++--- + src/login/logind-seat-dbus.c | 2 +- + src/login/logind-seat.c | 8 ++++---- + src/login/logind-seat.h | 4 ++-- + src/login/logind-session-dbus.c | 2 +- + src/login/logind-session.c | 8 ++++---- + src/login/logind-session.h | 2 +- + src/login/logind-user-dbus.c | 2 +- + src/login/logind-user.c | 4 ++-- + src/login/logind-user.h | 2 +- + src/login/logind.c | 10 +++++----- + 11 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 4137522..8a463f9 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -1927,7 +1927,7 @@ static DBusHandlerResult manager_message_handler( + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + +- r = session_stop(session); ++ r = session_stop(session, true); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + +@@ -1950,7 +1950,7 @@ static DBusHandlerResult manager_message_handler( + if (!user) + return bus_send_error_reply(connection, message, &error, -ENOENT); + +- r = user_stop(user); ++ r = user_stop(user, true); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + +@@ -1973,7 +1973,7 @@ static DBusHandlerResult manager_message_handler( + if (!seat) + return bus_send_error_reply(connection, message, &error, -ENOENT); + +- r = seat_stop_sessions(seat); ++ r = seat_stop_sessions(seat, true); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + +diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c +index 230f7f0..c87c1de 100644 +--- a/src/login/logind-seat-dbus.c ++++ b/src/login/logind-seat-dbus.c +@@ -261,7 +261,7 @@ static DBusHandlerResult seat_message_dispatch( + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "Terminate")) { + +- r = seat_stop_sessions(s); ++ r = seat_stop_sessions(s, true); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + +diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c +index feebcf4..d3b999d 100644 +--- a/src/login/logind-seat.c ++++ b/src/login/logind-seat.c +@@ -369,7 +369,7 @@ int seat_start(Seat *s) { + return 0; + } + +-int seat_stop(Seat *s) { ++int seat_stop(Seat *s, bool force) { + int r = 0; + + assert(s); +@@ -381,7 +381,7 @@ int seat_stop(Seat *s) { + "MESSAGE=Removed seat %s.", s->id, + NULL); + +- seat_stop_sessions(s); ++ seat_stop_sessions(s, force); + + unlink(s->state_file); + seat_add_to_gc_queue(s); +@@ -394,14 +394,14 @@ int seat_stop(Seat *s) { + return r; + } + +-int seat_stop_sessions(Seat *s) { ++int seat_stop_sessions(Seat *s, bool force) { + Session *session; + int r = 0, k; + + assert(s); + + LIST_FOREACH(sessions_by_seat, session, s->sessions) { +- k = session_stop(session); ++ k = session_stop(session, force); + if (k < 0) + r = k; + } +diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h +index be6db6e..bf496b3 100644 +--- a/src/login/logind-seat.h ++++ b/src/login/logind-seat.h +@@ -72,8 +72,8 @@ bool seat_can_graphical(Seat *s); + int seat_get_idle_hint(Seat *s, dual_timestamp *t); + + int seat_start(Seat *s); +-int seat_stop(Seat *s); +-int seat_stop_sessions(Seat *s); ++int seat_stop(Seat *s, bool force); ++int seat_stop_sessions(Seat *s, bool force); + + int seat_check_gc(Seat *s, bool drop_not_started); + void seat_add_to_gc_queue(Seat *s); +diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c +index 86b0746..76e16e7 100644 +--- a/src/login/logind-session-dbus.c ++++ b/src/login/logind-session-dbus.c +@@ -311,7 +311,7 @@ static DBusHandlerResult session_message_dispatch( + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Terminate")) { + +- r = session_stop(s); ++ r = session_stop(s, true); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 0fa290b..669a027 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -609,7 +609,7 @@ int session_start(Session *s) { + return 0; + } + +-static int session_stop_scope(Session *s) { ++static int session_stop_scope(Session *s, bool force) { + DBusError error; + char *job; + int r; +@@ -621,7 +621,7 @@ static int session_stop_scope(Session *s) { + if (!s->scope) + return 0; + +- if (manager_shall_kill(s->manager, s->user->name)) { ++ if (force || manager_shall_kill(s->manager, s->user->name)) { + r = manager_stop_unit(s->manager, s->scope, &error, &job); + if (r < 0) { + log_error("Failed to stop session scope: %s", bus_error(&error, r)); +@@ -676,7 +676,7 @@ static void session_close_timer_fd(Session *s) { + s->timer_fd = -1; + } + +-int session_stop(Session *s) { ++int session_stop(Session *s, bool force) { + int r; + + assert(s); +@@ -690,7 +690,7 @@ int session_stop(Session *s) { + session_remove_fifo(s); + + /* Kill cgroup */ +- r = session_stop_scope(s); ++ r = session_stop_scope(s, force); + + s->stopping = true; + +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 9b76582..3659872 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -131,7 +131,7 @@ void session_set_idle_hint(Session *s, bool b); + int session_create_fifo(Session *s); + void session_remove_fifo(Session *s); + int session_start(Session *s); +-int session_stop(Session *s); ++int session_stop(Session *s, bool force); + int session_finalize(Session *s); + void session_release(Session *s); + int session_save(Session *s); +diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c +index fa2ecba..72dd5d0 100644 +--- a/src/login/logind-user-dbus.c ++++ b/src/login/logind-user-dbus.c +@@ -242,7 +242,7 @@ static DBusHandlerResult user_message_dispatch( + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.User", "Terminate")) { + +- r = user_stop(u); ++ r = user_stop(u, true); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 653574e..6ddda54 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -466,13 +466,13 @@ static int user_remove_runtime_path(User *u) { + return r; + } + +-int user_stop(User *u) { ++int user_stop(User *u, bool force) { + Session *s; + int r = 0, k; + assert(u); + + LIST_FOREACH(sessions_by_user, s, u->sessions) { +- k = session_stop(s); ++ k = session_stop(s, force); + if (k < 0) + r = k; + } +diff --git a/src/login/logind-user.h b/src/login/logind-user.h +index a12532e..13513fa 100644 +--- a/src/login/logind-user.h ++++ b/src/login/logind-user.h +@@ -72,7 +72,7 @@ void user_free(User *u); + int user_check_gc(User *u, bool drop_not_started); + void user_add_to_gc_queue(User *u); + int user_start(User *u); +-int user_stop(User *u); ++int user_stop(User *u, bool force); + int user_finalize(User *u); + UserState user_get_state(User *u); + int user_get_idle_hint(User *u, dual_timestamp *t); +diff --git a/src/login/logind.c b/src/login/logind.c +index 5180be7..da3c099 100644 +--- a/src/login/logind.c ++++ b/src/login/logind.c +@@ -618,14 +618,14 @@ static void manager_dispatch_other(Manager *m, int fd) { + if (s) { + assert(s->fifo_fd == fd); + session_remove_fifo(s); +- session_stop(s); ++ session_stop(s, false); + return; + } + + s = hashmap_get(m->timer_fds, INT_TO_PTR(fd + 1)); + if (s) { + assert(s->timer_fd == fd); +- session_stop(s); ++ session_stop(s, false); + return; + } + +@@ -942,7 +942,7 @@ void manager_gc(Manager *m, bool drop_not_started) { + seat->in_gc_queue = false; + + if (seat_check_gc(seat, drop_not_started) == 0) { +- seat_stop(seat); ++ seat_stop(seat, false); + seat_free(seat); + } + } +@@ -954,7 +954,7 @@ void manager_gc(Manager *m, bool drop_not_started) { + /* First, if we are not closing yet, initiate stopping */ + if (!session_check_gc(session, drop_not_started) && + session_get_state(session) != SESSION_CLOSING) +- session_stop(session); ++ session_stop(session, false); + + if (!session_check_gc(session, drop_not_started)) { + session_finalize(session); +@@ -968,7 +968,7 @@ void manager_gc(Manager *m, bool drop_not_started) { + + if (!user_check_gc(user, drop_not_started) && + user_get_state(user) != USER_CLOSING) +- user_stop(user); ++ user_stop(user, false); + + if (!user_check_gc(user, drop_not_started)) { + user_finalize(user); diff --git a/SOURCES/0371-udev-net_id-correctly-name-netdevs-based-on-dev_port.patch b/SOURCES/0371-udev-net_id-correctly-name-netdevs-based-on-dev_port.patch new file mode 100644 index 0000000..a094bee --- /dev/null +++ b/SOURCES/0371-udev-net_id-correctly-name-netdevs-based-on-dev_port.patch @@ -0,0 +1,49 @@ +From 74888db37748c20b144a7cb117fb35f5c9804bcb Mon Sep 17 00:00:00 2001 +From: Tom Gundersen +Date: Sat, 25 Oct 2014 17:10:11 +0200 +Subject: [PATCH] udev: net_id - correctly name netdevs based on dev_port when + set + +Upstream, dev_id was replaced by dev_port, and the same happened for some kernel +drivers. This logic is not in the RHEL7 kernel, except for one new driver which +uses dev_port, but never used dev_id in the past. + +To give proper names to these devices, fall back to using dev_port when dev_id +is not set. This does not affect any existing drivers. + +(rhel only) + +Resolves: #1155996 +--- + src/udev/udev-builtin-net_id.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index b3cb04b..b5b5909 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -36,7 +36,7 @@ + * o -- on-board device index number + * s[f][d] -- hotplug slot index number + * x -- MAC address +- * [P]ps[f][d] ++ * [P]ps[f][d/] + * -- PCI geographical location + * [P]ps[f][u][..][c][i] + * -- USB port number chain +@@ -185,8 +185,14 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + + /* kernel provided multi-device index */ + attr = udev_device_get_sysattr_value(dev, "dev_id"); +- if (attr) ++ if (attr) { + dev_id = strtol(attr, NULL, 16); ++ if (dev_id == 0) { ++ attr = udev_device_get_sysattr_value(dev, "dev_port"); ++ if (attr) ++ dev_id = strtol(attr, NULL, 16); ++ } ++ } + + /* compose a name based on the raw kernel's PCI bus, slot numbers */ + s = names->pci_path; diff --git a/SOURCES/0372-udev-net_id-dev_port-is-base-10.patch b/SOURCES/0372-udev-net_id-dev_port-is-base-10.patch new file mode 100644 index 0000000..d3dce5e --- /dev/null +++ b/SOURCES/0372-udev-net_id-dev_port-is-base-10.patch @@ -0,0 +1,23 @@ +From 6aba16d2932457f516a3153d85b147f3d962f4a2 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 4 Nov 2014 17:59:28 +0100 +Subject: [PATCH] udev: net_id dev_port is base 10 + +Related: #1155996 +--- + src/udev/udev-builtin-net_id.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index b5b5909..4e6ca96 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -190,7 +190,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + if (dev_id == 0) { + attr = udev_device_get_sysattr_value(dev, "dev_port"); + if (attr) +- dev_id = strtol(attr, NULL, 16); ++ dev_id = strtol(attr, NULL, 10); + } + } + diff --git a/SOURCES/0373-udev-Fix-parsing-of-udev.event-timeout-kernel-parame.patch b/SOURCES/0373-udev-Fix-parsing-of-udev.event-timeout-kernel-parame.patch new file mode 100644 index 0000000..2a30e1a --- /dev/null +++ b/SOURCES/0373-udev-Fix-parsing-of-udev.event-timeout-kernel-parame.patch @@ -0,0 +1,25 @@ +From 1949cb6f5ff8cccecfab4eca5a4e697d5c55dbdf Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 5 Nov 2014 10:50:01 +0100 +Subject: [PATCH] udev: Fix parsing of udev.event-timeout kernel parameter + +(rhel-only, will be fixed in upstream differently) + +Related: #1154778 +--- + src/udev/udevd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 6241549..8d3f64f 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -889,7 +889,7 @@ static void kernel_cmdline_options(struct udev *udev) + } else if (startswith(opt, "udev.exec-delay=")) { + exec_delay = strtoul(opt + 16, NULL, 0); + } else if (startswith(opt, "udev.event-timeout=")) { +- event_timeout = strtoul(opt + 16, NULL, 0); ++ event_timeout = strtoul(opt + 19, NULL, 0); + } + + free(s); diff --git a/SOURCES/0374-login-rerun-vconsole-setup-when-switching-from-vgaco.patch b/SOURCES/0374-login-rerun-vconsole-setup-when-switching-from-vgaco.patch new file mode 100644 index 0000000..b97447c --- /dev/null +++ b/SOURCES/0374-login-rerun-vconsole-setup-when-switching-from-vgaco.patch @@ -0,0 +1,61 @@ +From 8659757c045dcdb6fcf628fa76025f1a2f533e8a Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 5 Nov 2014 08:30:52 -0500 +Subject: [PATCH] login: rerun vconsole-setup when switching from vgacon to + fbcon + +The initialization performed by systemd-vconsole-setup is reset +when changing console drivers (say from vgacon to fbcon), so we +need to run it in that case. + +See +http://lists.freedesktop.org/archives/systemd-devel/2014-October/023919.html +http://lists.freedesktop.org/archives/systemd-devel/2014-October/024423.html +http://lists.freedesktop.org/archives/systemd-devel/2014-November/024881.html + +This commit adds a udev rule to make systemd-vconsole-setup get run when +the fbcon device becomes available. + +(david: moved into new file 90-vconsole.rules instead of 71-seats.rules; + build-failures are on me, not on Ray) + +(cherry-picked from f6ba8671d83f9fce9a00045d8fa399a1c07ba7fc) + +Related: #1002450 +--- + Makefile.am | 3 +++ + src/vconsole/90-vconsole.rules | 11 +++++++++++ + 2 files changed, 14 insertions(+) + create mode 100644 src/vconsole/90-vconsole.rules + +diff --git a/Makefile.am b/Makefile.am +index dab55ba..faf2a32 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -3258,6 +3258,9 @@ rootlibexec_PROGRAMS += \ + nodist_systemunit_DATA += \ + units/systemd-vconsole-setup.service + ++dist_udevrules_DATA += \ ++ src/vconsole/90-vconsole.rules ++ + SYSINIT_TARGET_WANTS += \ + systemd-vconsole-setup.service + endif +diff --git a/src/vconsole/90-vconsole.rules b/src/vconsole/90-vconsole.rules +new file mode 100644 +index 0000000..bf6a9ef +--- /dev/null ++++ b/src/vconsole/90-vconsole.rules +@@ -0,0 +1,11 @@ ++# This file is part of systemd. ++# ++# systemd is free software; you can redistribute it and/or modify it ++# under the terms of the GNU Lesser General Public License as published by ++# the Free Software Foundation; either version 2.1 of the License, or ++# (at your option) any later version. ++ ++# Kernel resets vconsole state when changing console drivers so run ++# systemd-vconsole-setup when fbcon loads ++ ++ACTION=="add", SUBSYSTEM=="graphics", KERNEL=="fbcon", RUN+="/usr/lib/systemd/systemd-vconsole-setup" diff --git a/SOURCES/0375-cgroups-agent-really-down-grade-log-level.patch b/SOURCES/0375-cgroups-agent-really-down-grade-log-level.patch new file mode 100644 index 0000000..f3e9852 --- /dev/null +++ b/SOURCES/0375-cgroups-agent-really-down-grade-log-level.patch @@ -0,0 +1,29 @@ +From 6b8650a2e10a00088b977467bf0c79dd7044fcd9 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Mon, 10 Nov 2014 17:00:20 +0100 +Subject: [PATCH] cgroups-agent: really down-grade log level + +(rhel-only, fix for broken backport b0010d76a8c56900d15fab8ac1ed94d364d1e566) + +Related: #1044386 +--- + src/cgroups-agent/cgroups-agent.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c +index 43b9b3a..57db147 100644 +--- a/src/cgroups-agent/cgroups-agent.c ++++ b/src/cgroups-agent/cgroups-agent.c +@@ -50,11 +50,10 @@ int main(int argc, char *argv[]) { + + bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error); + if (!bus) { +- log_warning("Failed to get D-Bus connection: %s", strerror(-r)); + /* If we couldn't connect we assume this was triggered + * while systemd got restarted/transitioned from + * initrd to the system, so let's ignore this */ +- log_debug("Failed to get D-Bus connection: %s", strerror(-r)); ++ log_debug("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto finish; + } + diff --git a/SOURCES/0376-core-introduce-new-Delegate-yes-no-property-controll.patch b/SOURCES/0376-core-introduce-new-Delegate-yes-no-property-controll.patch new file mode 100644 index 0000000..ab61ded --- /dev/null +++ b/SOURCES/0376-core-introduce-new-Delegate-yes-no-property-controll.patch @@ -0,0 +1,385 @@ +From 310c5654023cd224f4c016872e39335b1b3ac603 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 13 Nov 2014 14:34:42 +0100 +Subject: [PATCH] core: introduce new Delegate=yes/no property controlling + creation of cgroup subhierarchies + +For priviliged units this resource control property ensures that the +processes have all controllers systemd manages enabled. + +For unpriviliged services (those with User= set) this ensures that +access rights to the service cgroup is granted to the user in question, +to create further subgroups. Note that this only applies to the +name=systemd hierarchy though, as access to other controllers is not +safe for unpriviliged processes. + +Delegate=yes should be set for container scopes where a systemd instance +inside the container shall manage the hierarchies below its own cgroup +and have access to all controllers. + +Delegate=yes should also be set for user@.service, so that systemd +--user can run, controlling its own cgroup tree. + +This commit changes machined, systemd-nspawn@.service and user@.service +to set this boolean, in order to ensure that container management will +just work, and the user systemd instance can run fine. + +(cherry picked from a931ad47a8623163a29d898224d8a8c1177ffdaf) + +Resolves: #1139223 +--- + man/systemd.resource-control.xml | 14 ++++++++++++ + src/core/cgroup.c | 19 +++++++++++++++-- + src/core/cgroup.h | 2 ++ + src/core/dbus-cgroup.c | 40 +++++++++++++++++++++++++++++++++++ + src/core/execute.c | 23 +++++++++++++++++--- + src/core/execute.h | 2 ++ + src/core/load-fragment-gperf.gperf.m4 | 3 ++- + src/core/mount.c | 1 + + src/core/service.c | 1 + + src/core/socket.c | 1 + + src/core/swap.c | 1 + + src/machine/machined-dbus.c | 10 +++++++++ + src/shared/cgroup-util.h | 3 ++- + units/systemd-nspawn@.service.in | 1 + + 14 files changed, 114 insertions(+), 7 deletions(-) + +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index 8688905..3748c0c 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -327,6 +327,20 @@ along with systemd; If not, see . + + + ++ ++ Delegate= ++ ++ ++ Turns on delegation of further resource control ++ partitioning to processes of the unit. For unpriviliged ++ services (i.e. those using the User= ++ setting) this allows processes to create a subhierarchy ++ beneath its control group path. For priviliged services and ++ scopes this ensures the processes will have all control ++ group controllers enabled. ++ ++ ++ + + + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index c215a86..443937b 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -94,14 +94,16 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + "%sCPUShares=%lu\n" + "%sBlockIOWeight=%lu\n" + "%sMemoryLimit=%" PRIu64 "\n" +- "%sDevicePolicy=%s\n", ++ "%sDevicePolicy=%s\n" ++ "%sDelegate=%s\n", + prefix, yes_no(c->cpu_accounting), + prefix, yes_no(c->blockio_accounting), + prefix, yes_no(c->memory_accounting), + prefix, c->cpu_shares, + prefix, c->blockio_weight, + prefix, c->memory_limit, +- prefix, cgroup_device_policy_to_string(c->device_policy)); ++ prefix, cgroup_device_policy_to_string(c->device_policy), ++ prefix, yes_no(c->delegate)); + + LIST_FOREACH(device_allow, a, c->device_allow) + fprintf(f, +@@ -342,6 +344,19 @@ static CGroupControllerMask unit_get_cgroup_mask(Unit *u) { + if (!c) + return 0; + ++ /* If delegation is turned on, then turn on all cgroups, ++ * unless the process we fork into it is known to drop ++ * privileges anyway, and shouldn't get access to the ++ * controllers anyway. */ ++ ++ if (c->delegate) { ++ ExecContext *e; ++ ++ e = unit_get_exec_context(u); ++ if (!e || exec_context_maintains_privileges(e)) ++ return _CGROUP_CONTROLLER_MASK_ALL; ++ } ++ + return cgroup_context_get_mask(c); + } + +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index 0a079e9..d00bcac 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -80,6 +80,8 @@ struct CGroupContext { + + CGroupDevicePolicy device_policy; + LIST_HEAD(CGroupDeviceAllow, device_allow); ++ ++ bool delegate; + }; + + #include "unit.h" +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index 9ebcad9..a13c869 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -124,6 +124,7 @@ static int bus_cgroup_append_device_allow(DBusMessageIter *i, const char *proper + } + + const BusProperty bus_cgroup_context_properties[] = { ++ { "Delegate", bus_property_append_bool, "b", offsetof(CGroupContext, delegate) }, + { "CPUAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, cpu_accounting) }, + { "CPUShares", bus_property_append_ul, "t", offsetof(CGroupContext, cpu_shares) }, + { "BlockIOAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, blockio_accounting) }, +@@ -138,6 +139,38 @@ const BusProperty bus_cgroup_context_properties[] = { + {} + }; + ++static int bus_cgroup_set_transient_property( ++ Unit *u, ++ CGroupContext *c, ++ const char *name, ++ DBusMessageIter *i, ++ UnitSetPropertiesMode mode, ++ DBusError *error) { ++ ++ assert(u); ++ assert(c); ++ assert(name); ++ assert(i); ++ ++ if (streq(name, "Delegate")) { ++ ++ if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) ++ return -EINVAL; ++ ++ if (mode != UNIT_CHECK) { ++ dbus_bool_t b; ++ ++ dbus_message_iter_get_basic(i, &b); ++ c->delegate = b; ++ unit_write_drop_in_private(u, mode, name, b ? "Delegate=yes" : "Delegate=no"); ++ } ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ + int bus_cgroup_set_property( + Unit *u, + CGroupContext *c, +@@ -550,5 +583,12 @@ int bus_cgroup_set_property( + return 1; + } + ++ if (u->transient && u->load_state == UNIT_STUB) { ++ int r; ++ r = bus_cgroup_set_transient_property(u, c, name, i, mode, error); ++ if (r != 0) ++ return r; ++ } ++ + return 0; + } +diff --git a/src/core/execute.c b/src/core/execute.c +index 06713cc..d814c39 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1042,6 +1042,7 @@ int exec_spawn(ExecCommand *command, + bool selinux_context_net, + CGroupControllerMask cgroup_supported, + const char *cgroup_path, ++ bool cgroup_delegate, + const char *unit_id, + int idle_pipe[4], + pid_t *ret) { +@@ -1306,8 +1307,10 @@ int exec_spawn(ExecCommand *command, + } + } + +-#ifdef HAVE_PAM +- if (cgroup_path && context->user && context->pam_name) { ++ /* If delegation is enabled we'll pass ownership of the cgroup ++ * (but only in systemd's own controller hierarchy!) to the ++ * user of the new process. */ ++ if (cgroup_path && context->user && cgroup_delegate) { + err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0644, uid, gid); + if (err < 0) { + r = EXIT_CGROUP; +@@ -1321,7 +1324,6 @@ int exec_spawn(ExecCommand *command, + goto fail_child; + } + } +-#endif + + if (apply_permissions) { + err = enforce_groups(context, username, gid); +@@ -2116,6 +2118,21 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { + + } + ++bool exec_context_maintains_privileges(ExecContext *c) { ++ assert(c); ++ ++ /* Returns true if the process forked off would run under ++ * an unchanged UID or as root. */ ++ ++ if (!c->user) ++ return true; ++ ++ if (streq(c->user, "root") || streq(c->user, "0")) ++ return true; ++ ++ return false; ++} ++ + void exec_status_start(ExecStatus *s, pid_t pid) { + assert(s); + +diff --git a/src/core/execute.h b/src/core/execute.h +index b66bd5f..03afdf3 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -177,6 +177,7 @@ int exec_spawn(ExecCommand *command, + bool selinux_context_net, + CGroupControllerMask cgroup_mask, + const char *cgroup_path, ++ bool cgroup_delegate, + const char *unit_id, + int pipe_fd[2], + pid_t *ret); +@@ -203,6 +204,7 @@ void exec_context_tty_reset(const ExecContext *context); + int exec_context_load_environment(const ExecContext *c, const char *unit_id, char ***l); + + bool exec_context_may_touch_console(ExecContext *c); ++bool exec_context_maintains_privileges(ExecContext *c); + void exec_context_serialize(const ExecContext *c, Unit *u, FILE *f); + + void exec_status_start(ExecStatus *s, pid_t pid); +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index ee7cd5d..c6eb757 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -96,7 +96,8 @@ $1.BlockIOAccounting, config_parse_bool, 0, + $1.BlockIOWeight, config_parse_blockio_weight, 0, offsetof($1, cgroup_context) + $1.BlockIODeviceWeight, config_parse_blockio_device_weight, 0, offsetof($1, cgroup_context) + $1.BlockIOReadBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context) +-$1.BlockIOWriteBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context)' ++$1.BlockIOWriteBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context) ++$1.Delegate, config_parse_bool, 0, offsetof($1, cgroup_context.delegate)' + )m4_dnl + Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description) + Unit.Documentation, config_parse_documentation, 0, offsetof(Unit, documentation) +diff --git a/src/core/mount.c b/src/core/mount.c +index bbceb92..a9cd28b 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -794,6 +794,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { + false, + UNIT(m)->manager->cgroup_supported, + UNIT(m)->cgroup_path, ++ m->cgroup_context.delegate, + UNIT(m)->id, + NULL, + &pid); +diff --git a/src/core/service.c b/src/core/service.c +index 635a953..5fd69cf 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1870,6 +1870,7 @@ static int service_spawn( + s->socket_fd_selinux_context_net, + UNIT(s)->manager->cgroup_supported, + path, ++ s->cgroup_context.delegate, + UNIT(s)->id, + s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL, + &pid); +diff --git a/src/core/socket.c b/src/core/socket.c +index 1a91700..f7fffbe 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1237,6 +1237,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + false, + UNIT(s)->manager->cgroup_supported, + UNIT(s)->cgroup_path, ++ s->cgroup_context.delegate, + UNIT(s)->id, + NULL, + &pid); +diff --git a/src/core/swap.c b/src/core/swap.c +index 36ef88b..152a080 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -592,6 +592,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { + false, + UNIT(s)->manager->cgroup_supported, + UNIT(s)->cgroup_path, ++ s->cgroup_context.delegate, + UNIT(s)->id, + NULL, + &pid); +diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c +index 22caadf..0cebdc5 100644 +--- a/src/machine/machined-dbus.c ++++ b/src/machine/machined-dbus.c +@@ -739,9 +739,11 @@ int manager_start_scope( + DBusMessageIter iter, sub, sub2, sub3, sub4; + const char *timeout_stop_property = "TimeoutStopUSec"; + const char *pids_property = "PIDs"; ++ const char *delegate_property = "Delegate"; + uint64_t timeout = 500 * USEC_PER_MSEC; + const char *fail = "fail"; + uint32_t u; ++ dbus_bool_t b = 1; + int r; + + assert(manager); +@@ -814,6 +816,14 @@ int manager_start_scope( + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + ++ if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || ++ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &delegate_property) || ++ !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "b", &sub3) || ++ !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_BOOLEAN, &b) || ++ !dbus_message_iter_close_container(&sub2, &sub3) || ++ !dbus_message_iter_close_container(&sub, &sub2)) ++ return log_oom(); ++ + if (more_properties) { + r = copy_many_fields(&sub, more_properties); + if (r < 0) +diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h +index 0963450..0608b9a 100644 +--- a/src/shared/cgroup-util.h ++++ b/src/shared/cgroup-util.h +@@ -34,7 +34,8 @@ typedef enum CGroupControllerMask { + CGROUP_CPUACCT = 2, + CGROUP_BLKIO = 4, + CGROUP_MEMORY = 8, +- CGROUP_DEVICE = 16 ++ CGROUP_DEVICE = 16, ++ _CGROUP_CONTROLLER_MASK_ALL = 31 + } CGroupControllerMask; + + /* +diff --git a/units/systemd-nspawn@.service.in b/units/systemd-nspawn@.service.in +index 8e00736..bdfa89f 100644 +--- a/units/systemd-nspawn@.service.in ++++ b/units/systemd-nspawn@.service.in +@@ -12,6 +12,7 @@ Documentation=man:systemd-nspawn(1) + [Service] + ExecStart=@bindir@/systemd-nspawn -bjD /var/lib/container/%i + Type=notify ++Delegate=yes + + [Install] + WantedBy=multi-user.target diff --git a/SOURCES/0377-core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch b/SOURCES/0377-core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch new file mode 100644 index 0000000..c2bbe4b --- /dev/null +++ b/SOURCES/0377-core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch @@ -0,0 +1,50 @@ +From 4d554c7c1b5373f854cdfd3b8c7d6804225c752e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 10 Dec 2014 20:38:24 +0100 +Subject: [PATCH] core: don't migrate PIDs for units that may contain + subcgroups, do this only for leaf units + +Otherwise a slice or delegation unit might move PIDs around ignoring the +fact that it is attached to a subcgroup. + +(cherry picked from commit 0cd385d31814c8c1bc0c81d11ef321036b8b0921) + +Resolves: #1139223 +--- + src/core/cgroup.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 443937b..5163ee4 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -392,11 +392,16 @@ static CGroupControllerMask unit_get_siblings_mask(Unit *u) { + + static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { + _cleanup_free_ char *path; ++ CGroupContext *c; + int r; + bool was_in_hash = false; + + assert(u); + ++ c = unit_get_cgroup_context(u); ++ if (!c) ++ return 0; ++ + path = unit_default_cgroup_path(u); + if (!path) + return log_oom(); +@@ -416,8 +421,10 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { + if (r < 0) + log_error("Failed to create cgroup %s: %s", path, strerror(-r)); + +- /* Then, possibly move things over */ +- if (u->cgroup_path) { ++ /* Then, possibly move things over, but not if ++ * subgroups may contain processes, which is the case ++ * for slice and delegation units. */ ++ if (u->cgroup_path && u->type != UNIT_SLICE && !c->delegate) { + r = cg_migrate_everywhere(u->manager->cgroup_supported, u->cgroup_path, path); + if (r < 0) + log_error("Failed to migrate cgroup from %s to %s: %s", diff --git a/SOURCES/0378-mount-use-libmount-to-enumerate-proc-self-mountinfo.patch b/SOURCES/0378-mount-use-libmount-to-enumerate-proc-self-mountinfo.patch new file mode 100644 index 0000000..9c76eac --- /dev/null +++ b/SOURCES/0378-mount-use-libmount-to-enumerate-proc-self-mountinfo.patch @@ -0,0 +1,204 @@ +From 53b2695b96c6e8717a375cc2a17fcc4384d04790 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Sun, 23 Nov 2014 20:33:37 -0800 +Subject: [PATCH] mount: use libmount to enumerate /proc/self/mountinfo + +This lets libmount add in user options from /run/mount/utab, like +_netdev which is needed to get proper ordering against remote-fs.target + +Conflicts: + Makefile.am + README + configure.ac + src/core/mount.c + +(cherry-picked from 8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30) + +Related: #1161417 +--- + .travis.yml | 2 +- + Makefile.am | 4 +++- + README | 1 + + configure.ac | 10 +++++++++ + src/core/mount.c | 65 ++++++++++++++++++++++++++------------------------------ + 5 files changed, 45 insertions(+), 37 deletions(-) + +diff --git a/.travis.yml b/.travis.yml +index 7e5251c..4ea2bc2 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -3,7 +3,7 @@ compiler: + - gcc + before_install: + - sudo apt-get update -qq +- - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev ++ - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libmount-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev + script: ./autogen.sh && ./configure --enable-gtk-doc --enable-gtk-doc-pdf && make V=1 && sudo ./systemd-machine-id-setup && make check && make distcheck + after_failure: cat test-suite.log + notifications: +diff --git a/Makefile.am b/Makefile.am +index faf2a32..0891bca 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -997,6 +997,7 @@ libsystemd_core_la_CFLAGS = \ + $(PAM_CFLAGS) \ + $(AUDIT_CFLAGS) \ + $(KMOD_CFLAGS) \ ++ $(MOUNT_CFLAGS) \ + -pthread + + libsystemd_core_la_LIBADD = \ +@@ -1013,7 +1014,8 @@ libsystemd_core_la_LIBADD = \ + $(PAM_LIBS) \ + $(AUDIT_LIBS) \ + $(CAP_LIBS) \ +- $(KMOD_LIBS) ++ $(KMOD_LIBS) \ ++ $(MOUNT_LIBS) + + src/core/load-fragment-gperf-nulstr.c: src/core/load-fragment-gperf.gperf + $(AM_V_at)$(MKDIR_P) $(dir $@) +diff --git a/README b/README +index b39cd37..42487dd 100644 +--- a/README ++++ b/README +@@ -94,6 +94,7 @@ REQUIREMENTS: + + dbus >= 1.4.0 + libcap ++ libmount >= 2.20 (from util-linux) + libblkid >= 2.20 (from util-linux) (optional) + libkmod >= 14 (optional) + PAM >= 1.1.2 (optional) +diff --git a/configure.ac b/configure.ac +index 4f26092..b7dfc5f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -292,6 +292,15 @@ fi + AM_CONDITIONAL(HAVE_BLKID, [test "$have_blkid" = "yes"]) + + # ------------------------------------------------------------------------------ ++have_libmount=no ++PKG_CHECK_MODULES(MOUNT, [ mount >= 2.20 ], ++ [AC_DEFINE(HAVE_LIBMOUNT, 1, [Define if libmount is available]) have_libmount=yes], have_libmount=no) ++if test "x$have_libmount" = xno; then ++ AC_MSG_ERROR([*** libmount support required but libraries not found]) ++fi ++AM_CONDITIONAL(HAVE_LIBMOUNT, [test "$have_libmount" = "yes"]) ++ ++# ------------------------------------------------------------------------------ + have_ima=yes + AC_ARG_ENABLE([ima], AS_HELP_STRING([--disable-ima],[Disable optional IMA support]), + [case "${enableval}" in +@@ -1046,6 +1055,7 @@ AC_MSG_RESULT([ + efi: ${have_efi} + kmod: ${have_kmod} + blkid: ${have_blkid} ++ libmount: ${have_libmount} + nss-myhostname: ${have_myhostname} + gudev: ${enable_gudev} + gintrospection: ${enable_introspection} +diff --git a/src/core/mount.c b/src/core/mount.c +index bbceb92..d78269c 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "manager.h" + #include "unit.h" +@@ -1563,55 +1564,47 @@ fail: + return r; + } + ++static inline void mnt_free_table_p(struct libmnt_table **tb) { ++ mnt_free_table(*tb); ++} ++ ++static inline void mnt_free_iter_p(struct libmnt_iter **itr) { ++ mnt_free_iter(*itr); ++} ++ + static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { ++ _cleanup_(mnt_free_table_p) struct libmnt_table *tb = NULL; ++ _cleanup_(mnt_free_iter_p) struct libmnt_iter *itr = NULL; ++ struct libmnt_fs *fs; + int r = 0; +- unsigned i; + + assert(m); + +- rewind(m->proc_self_mountinfo); ++ tb = mnt_new_table(); ++ itr = mnt_new_iter(MNT_ITER_FORWARD); ++ if (!tb || !itr) ++ return log_oom(); + +- for (i = 1;; i++) { +- _cleanup_free_ char *device = NULL, *path = NULL, *options = NULL, *options2 = NULL, *fstype = NULL, *d = NULL, *p = NULL, *o = NULL; +- int k; ++ mnt_table_parse_mtab(tb, NULL); ++ if (r) ++ return r; + +- k = fscanf(m->proc_self_mountinfo, +- "%*s " /* (1) mount id */ +- "%*s " /* (2) parent id */ +- "%*s " /* (3) major:minor */ +- "%*s " /* (4) root */ +- "%ms " /* (5) mount point */ +- "%ms" /* (6) mount options */ +- "%*[^-]" /* (7) optional fields */ +- "- " /* (8) separator */ +- "%ms " /* (9) file system type */ +- "%ms" /* (10) mount source */ +- "%ms" /* (11) mount options 2 */ +- "%*[^\n]", /* some rubbish at the end */ +- &path, +- &options, +- &fstype, +- &device, +- &options2); +- +- if (k == EOF) +- break; +- +- if (k != 5) { +- log_warning("Failed to parse /proc/self/mountinfo:%u.", i); +- continue; +- } ++ while (mnt_table_next_fs(tb, itr, &fs) == 0) { ++ const char *device, *path, *options, *fstype; ++ _cleanup_free_ const char *d = NULL, *p = NULL; ++ int k; + +- o = strjoin(options, ",", options2, NULL); +- if (!o) +- return log_oom(); ++ device = mnt_fs_get_source(fs); ++ path = mnt_fs_get_target(fs); ++ options = mnt_fs_get_options(fs); ++ fstype = mnt_fs_get_fstype(fs); + + d = cunescape(device); + p = cunescape(path); + if (!d || !p) + return log_oom(); + +- k = mount_add_one(m, d, p, o, fstype, 0, set_flags); ++ k = mount_add_one(m, d, p, options, fstype, 0, set_flags); + if (k < 0) + r = k; + } +@@ -1632,6 +1625,8 @@ static int mount_enumerate(Manager *m) { + int r; + assert(m); + ++ mnt_init_debug(0); ++ + if (!m->proc_self_mountinfo) { + struct epoll_event ev = { + .events = EPOLLPRI, diff --git a/SOURCES/0379-mount-monitor-for-utab-changes-with-inotify.patch b/SOURCES/0379-mount-monitor-for-utab-changes-with-inotify.patch new file mode 100644 index 0000000..54f4c80 --- /dev/null +++ b/SOURCES/0379-mount-monitor-for-utab-changes-with-inotify.patch @@ -0,0 +1,209 @@ +From 3c567125dd6e3f0f3a460d79701554ea4198c07b Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 18 Dec 2014 14:13:26 +0100 +Subject: [PATCH] mount: monitor for utab changes with inotify + +Parsing the mount table with libmount races against the mount command, +which will handle the actual mounting before updating utab. This means +the poll event on /proc/self/mountinfo can kick of a reparse in systemd +before the utab information is available. + +This change adds in an additional event source using inotify to watch +for changes to utab. It only watches for IN_MOVED_TO events, matching +libmount behavior of always overwriting this file using rename(2). + +This does add a second pass through the mount table parsing when utab is +updated. + +(based-on befb6d54948480f836d53d633bef27e3505818c1) + +Related: #1161417 +--- + src/core/manager.c | 3 ++- + src/core/manager.h | 2 ++ + src/core/mount.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++--- + src/core/mount.h | 2 +- + src/shared/util.h | 7 +++++ + 5 files changed, 88 insertions(+), 5 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index e48ea36..b0772ba 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1732,8 +1732,9 @@ static int process_event(Manager *m, struct epoll_event *ev) { + } + + case WATCH_MOUNT: ++ case WATCH_MOUNT_UTAB: + /* Some mount table change, intended for the mount subsystem */ +- mount_fd_event(m, ev->events); ++ mount_fd_event(m, w, ev->events); + break; + + case WATCH_SWAP: +diff --git a/src/core/manager.h b/src/core/manager.h +index 0133ea5..af66598 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -58,6 +58,7 @@ enum WatchType { + WATCH_UNIT_TIMER, + WATCH_JOB_TIMER, + WATCH_MOUNT, ++ WATCH_MOUNT_UTAB, + WATCH_SWAP, + WATCH_UDEV, + WATCH_DBUS_WATCH, +@@ -178,6 +179,7 @@ struct Manager { + /* Data specific to the mount subsystem */ + FILE *proc_self_mountinfo; + Watch mount_watch; ++ Watch mount_watch_utab; + + /* Data specific to the swap filesystem */ + FILE *proc_swaps; +diff --git a/src/core/mount.c b/src/core/mount.c +index d78269c..efa46da 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include "manager.h" + #include "unit.h" +@@ -1619,6 +1620,11 @@ static void mount_shutdown(Manager *m) { + fclose(m->proc_self_mountinfo); + m->proc_self_mountinfo = NULL; + } ++ ++ if (m->mount_watch_utab.fd) { ++ close_nointr(m->mount_watch_utab.fd); ++ m->mount_watch_utab.fd=0; ++ } + } + + static int mount_enumerate(Manager *m) { +@@ -1644,6 +1650,35 @@ static int mount_enumerate(Manager *m) { + return -errno; + } + ++ if (!m->mount_watch_utab.fd) { ++ ++ struct epoll_event ev = { ++ .events = EPOLLIN, ++ .data.ptr = &m->mount_watch_utab, ++ }; ++ ++ m->mount_watch_utab.fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); ++ if (m->mount_watch_utab.fd < 0) { ++ r = -errno; ++ goto fail; ++ } ++ ++ (void) mkdir_p_label("/run/mount", 0755); ++ ++ r = inotify_add_watch(m->mount_watch_utab.fd, "/run/mount", IN_MOVED_TO); ++ if (r < 0) { ++ r = -errno; ++ goto fail; ++ } ++ ++ m->mount_watch_utab.type = WATCH_MOUNT_UTAB; ++ ++ if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch_utab.fd, &ev) < 0) { ++ r = -errno; ++ goto fail; ++ } ++ } ++ + r = mount_load_proc_self_mountinfo(m, false); + if (r < 0) + goto fail; +@@ -1655,16 +1690,54 @@ fail: + return r; + } + +-void mount_fd_event(Manager *m, int events) { ++void mount_fd_event(Manager *m, Watch *w, int events) { + Unit *u; + int r; + + assert(m); +- assert(events & EPOLLPRI); ++ assert(w); ++ assert(events & (EPOLLPRI|EPOLLIN)); + + /* The manager calls this for every fd event happening on the + * /proc/self/mountinfo file, which informs us about mounting +- * table changes */ ++ * table changes ++ * This may also be called for /run/mount events */ ++ ++ if (w->type == WATCH_MOUNT_UTAB) { ++ bool rescan = false; ++ ++ /* FIXME: We *really* need to replace this with ++ * libmount's own API for this, we should not hardcode ++ * internal behaviour of libmount here. */ ++ ++ for (;;) { ++ uint8_t buffer[INOTIFY_EVENT_MAX] _alignas_(struct inotify_event); ++ struct inotify_event *e; ++ ssize_t l; ++ ++ l = read(w->fd, buffer, sizeof(buffer)); ++ if (l < 0) { ++ if (errno == EAGAIN || errno == EINTR) ++ break; ++ ++ log_error("Failed to read utab inotify: %s", strerror(errno)); ++ break; ++ } ++ ++ FOREACH_INOTIFY_EVENT(e, buffer, l) { ++ /* Only care about changes to utab, ++ * but we have to monitor the ++ * directory to reliably get ++ * notifications about when utab is ++ * replaced using rename(2) */ ++ if ((e->mask & IN_Q_OVERFLOW) || streq(e->name, "utab")) ++ rescan = true; ++ } ++ } ++ ++ if (!rescan) ++ return; ++ } + + r = mount_load_proc_self_mountinfo(m, true); + if (r < 0) { +diff --git a/src/core/mount.h b/src/core/mount.h +index 7cd4320..df0e541 100644 +--- a/src/core/mount.h ++++ b/src/core/mount.h +@@ -113,7 +113,7 @@ struct Mount { + + extern const UnitVTable mount_vtable; + +-void mount_fd_event(Manager *m, int events); ++void mount_fd_event(Manager *m, Watch *w, int events); + + const char* mount_state_to_string(MountState i) _const_; + MountState mount_state_from_string(const char *s) _pure_; +diff --git a/src/shared/util.h b/src/shared/util.h +index d68f385..c5ef8b6 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -791,3 +791,10 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, + qsort(base, nmemb, size, compar); + } + } ++ ++#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1) ++ ++#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \ ++ for ((e) = (struct inotify_event*) (buffer); \ ++ (uint8_t*) (e) < (uint8_t*) (buffer) + (sz); \ ++ (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len)) diff --git a/SOURCES/0380-mount-add-remote-fs-dependencies-if-needed-after-cha.patch b/SOURCES/0380-mount-add-remote-fs-dependencies-if-needed-after-cha.patch new file mode 100644 index 0000000..227a08d --- /dev/null +++ b/SOURCES/0380-mount-add-remote-fs-dependencies-if-needed-after-cha.patch @@ -0,0 +1,44 @@ +From ebbcce68c7383217ad93537ef023e85b913d0478 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Sun, 23 Nov 2014 20:33:40 -0800 +Subject: [PATCH] mount: add remote-fs dependencies if needed after change + +This is an attempt to add it the remote-fs dependencies to a mount unit +if the options change, like when the utab options are picked up after +mountinfo has already been processed. It just adds the remote-fs +dependencies, leaving the local-fs ones in place. + +With this change I always get mount units with proper remote-fs +dependencies when mounted with the _netdev option. + +(cherry-picked from a6d305f91d722e136c29222070efed5c5d8b120b) + +Resolves: #1161417 +--- + src/core/mount.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/core/mount.c b/src/core/mount.c +index efa46da..a7987bf 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1499,6 +1499,19 @@ static int mount_add_one( + } + } + ++ if (m->running_as == SYSTEMD_SYSTEM) { ++ const char* target; ++ ++ target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : NULL; ++ /* _netdev option may have shown up late, or on a ++ * remount. Add remote-fs dependencies, even though ++ * local-fs ones may already be there */ ++ if (target) { ++ unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true); ++ load_extras = true; ++ } ++ } ++ + if (u->load_state == UNIT_NOT_FOUND) { + u->load_state = UNIT_LOADED; + u->load_error = 0; diff --git a/SOURCES/0381-mount-check-options-as-well-as-fstype-for-network-mo.patch b/SOURCES/0381-mount-check-options-as-well-as-fstype-for-network-mo.patch new file mode 100644 index 0000000..bba353f --- /dev/null +++ b/SOURCES/0381-mount-check-options-as-well-as-fstype-for-network-mo.patch @@ -0,0 +1,87 @@ +From 4971e2c8438da1a95cdc306e01e9a3c2349342ad Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Sun, 23 Nov 2014 20:33:38 -0800 +Subject: [PATCH] mount: check options as well as fstype for network mounts + +When creating a new mount unit after an event on /proc/self/mountinfo, +check the mount options as well as the fstype to determine if this is a +remote mount that requires network access. + +Conflicts: + src/core/mount.c + +(cherry-picked from affc3d834347076e8616948978e70ed1fca84db4) + +Resolves: #1161417 +--- + src/core/mount.c | 33 ++++++++++++++++++++------------- + 1 file changed, 20 insertions(+), 13 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index a7987bf..6c3c7be 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -75,18 +75,22 @@ 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")) ++static bool mount_needs_network(const char *options, const char *fstype) { ++ if (mount_test_option(options, "_netdev")) + return true; + +- if (p->fstype && fstype_is_network(p->fstype)) ++ if (fstype && fstype_is_network(fstype)) + return true; + + return false; + } + ++static bool mount_is_network(MountParameters *p) { ++ assert(p); ++ ++ return mount_needs_network(p->options, p->fstype); ++} ++ + static bool mount_is_bind(MountParameters *p) { + assert(p); + +@@ -1446,9 +1450,6 @@ static int mount_add_one( + + u = manager_get_unit(m, e); + if (!u) { +- const char* const target = +- fstype_is_network(fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; +- + delete = true; + + u = unit_new(m, sizeof(Mount)); +@@ -1475,14 +1476,20 @@ static int mount_add_one( + goto fail; + } + +- r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true); +- if (r < 0) +- goto fail; + +- if (should_umount(MOUNT(u))) { +- r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); ++ if (m->running_as == SYSTEMD_SYSTEM) { ++ const char* target; ++ ++ target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; ++ r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true); + if (r < 0) + goto fail; ++ ++ if (should_umount(MOUNT(u))) { ++ r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); ++ if (r < 0) ++ goto fail; ++ } + } + + unit_add_to_load_queue(u); diff --git a/SOURCES/0382-rules-don-t-enable-usb-pm-for-Avocent-devices.patch b/SOURCES/0382-rules-don-t-enable-usb-pm-for-Avocent-devices.patch new file mode 100644 index 0000000..b2c5291 --- /dev/null +++ b/SOURCES/0382-rules-don-t-enable-usb-pm-for-Avocent-devices.patch @@ -0,0 +1,30 @@ +From 35b8533914a82d2ee8a667ec2afac0499dcbfb28 Mon Sep 17 00:00:00 2001 +From: Tom Hirst +Date: Wed, 25 Jun 2014 11:57:11 +0000 +Subject: [PATCH] rules: don't enable usb pm for Avocent devices + +The Avocent KVM over IP devices doesn't work correctly with USB power +management enabled. + +(cherry-picked from 52fb538361053f8c4abce0e40cd0bae3d28ceb16) + +Resolves: #1155370 +--- + rules/42-usb-hid-pm.rules | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/rules/42-usb-hid-pm.rules b/rules/42-usb-hid-pm.rules +index 3fd6e8a..483a781 100644 +--- a/rules/42-usb-hid-pm.rules ++++ b/rules/42-usb-hid-pm.rules +@@ -11,10 +11,6 @@ ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Mouse", ATTR{serial}== + ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Tablet", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto" + ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Keyboard", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto" + +-# Catch-all for Avocent HID devices. Keyed off interface in order to only +-# trigger on HID class devices. +-ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0624", ATTR{bInterfaceClass}=="03", TEST=="../power/control", ATTR{../power/control}="auto" +- + # Dell DRAC 4 + ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="2500", TEST=="power/control", ATTR{power/control}="auto" + diff --git a/SOURCES/rc.local b/SOURCES/rc.local index 8e633ff..a7e0ad2 100644 --- a/SOURCES/rc.local +++ b/SOURCES/rc.local @@ -4,9 +4,9 @@ # It is highly advisable to create own systemd services or udev rules # to run scripts during boot instead of using this file. # -# In constrast to previous versions due to parallel execution during boot +# In contrast to previous versions due to parallel execution during boot # this script will NOT be run after all other services. -# +# # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure # that this script will be executed during boot. diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index b896a0c..3df7d93 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -11,7 +11,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 208 -Release: 11%{?dist}.6 +Release: 20%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: A System and Service Manager @@ -265,12 +265,154 @@ Patch0231: 0231-unit-add-waiting-jobs-to-run-queue-in-unit_coldplug.patch Patch0232: 0232-logind-session-save-stopping-flag.patch Patch0233: 0233-units-serial-getty-.service-add-Install-section.patch Patch0234: 0234-units-order-network-online.target-after-network.targ.patch -Patch0235: 0235-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch -Patch0236: 0236-util-reset-signals-when-we-fork-off-agents.patch -Patch0237: 0237-socket-add-SocketUser-and-SocketGroup-for-chown-ing-.patch -Patch0238: 0238-rules-don-t-enable-usb-pm-for-Avocent-devices.patch -Patch0239: 0239-core-introduce-new-Delegate-yes-no-property-controll.patch -Patch0240: 0240-core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch +Patch0235: 0235-util-consider-both-fuse.glusterfs-and-glusterfs-netw.patch +Patch0236: 0236-core-make-StopWhenUnneeded-work-in-conjunction-with-.patch +Patch0237: 0237-cgroups-agent-down-grade-log-level.patch +Patch0238: 0238-random-seed-raise-POOL_SIZE_MIN-constant-to-1024.patch +Patch0239: 0239-delta-do-not-use-unicode-chars-in-C-locale.patch +Patch0240: 0240-core-print-debug-instead-of-error-message.patch +Patch0241: 0241-journald-always-add-syslog-facility-for-messages-com.patch +Patch0242: 0242-Introduce-_cleanup_endmntent_.patch +Patch0243: 0243-Introduce-_cleanup_fdset_free_.patch +Patch0244: 0244-Introduce-udev-object-cleanup-functions.patch +Patch0245: 0245-fsck-modernization.patch +Patch0246: 0246-fsck-fstab-generator-be-lenient-about-missing-fsck.-.patch +Patch0247: 0247-rules-60-persistent-storage-add-nvme-pcie-ssd-scsi_i.patch +Patch0248: 0248-cgls-fix-running-with-M-option.patch +Patch0249: 0249-units-when-spawning-a-getty-configure-TERM-explicitl.patch +Patch0250: 0250-getty-Start-getty-on-3270-terminals-available-on-Lin.patch +Patch0251: 0251-core-Added-support-for-ERRNO-NOTIFY_SOCKET-message-p.patch +Patch0252: 0252-service-don-t-accept-negative-ERRNO-notification-mes.patch +Patch0253: 0253-socket-add-SocketUser-and-SocketGroup-for-chown-ing-.patch +Patch0254: 0254-selinux-Check-access-vector-for-enable-and-disable-p.patch +Patch0255: 0255-systemctl-show-StatusErrno-value-in-systemctl-status.patch +Patch0256: 0256-service-flush-status-text-and-errno-values-each-time.patch +Patch0257: 0257-service-don-t-free-status_text-twice.patch +Patch0258: 0258-util-add-files_same-helper-function.patch +Patch0259: 0259-systemctl-for-switch-root-check-if-we-switch-to-a-sy.patch +Patch0260: 0260-shared-include-root-when-canonicalizing-conf-paths.patch +Patch0261: 0261-shared-add-root-argument-to-search_and_fopen.patch +Patch0262: 0262-machine-id-add-root-option-to-operate-on-an-alternat.patch +Patch0263: 0263-conf-files-fix-when-for-root-logic.patch +Patch0264: 0264-Make-systemctl-root-look-for-files-in-the-proper-pla.patch +Patch0265: 0265-tmpfiles-fix-memory-leak-of-exclude_prefixes.patch +Patch0266: 0266-tmpfiles-add-root-option-to-operate-on-an-alternate-.patch +Patch0267: 0267-conf-files-include-root-in-returned-file-paths.patch +Patch0268: 0268-install-make-sure-that-root-mode-doesn-t-make-us-con.patch +Patch0269: 0269-shared-install-do-not-prefix-created-symlink-with-ro.patch +Patch0270: 0270-systemctl-fail-in-the-case-that-no-unit-files-were-f.patch +Patch0271: 0271-units-make-ExecStopPost-action-part-of-ExecStart.patch +Patch0272: 0272-systemctl-fix-broken-list-unit-files-with-root.patch +Patch0273: 0273-machine-id-only-look-into-KVM-uuid-when-we-are-not-r.patch +Patch0274: 0274-util-reset-signals-when-we-fork-off-agents.patch +Patch0275: 0275-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch +Patch0276: 0276-udev-do-not-skip-the-execution-of-RUN-when-renaming-.patch +Patch0277: 0277-man-mention-System-Administrator-s-Guide-in-systemct.patch +Patch0278: 0278-vconsole-also-copy-character-maps-not-just-fonts-fro.patch +Patch0279: 0279-vconsole-setup-run-setfont-before-loadkeys.patch +Patch0280: 0280-vconsole-setup-fix-inverted-error-messages.patch +Patch0281: 0281-localed-consider-an-unset-model-as-a-wildcard.patch +Patch0282: 0282-systemd-detect-virt-detect-s390-virtualization.patch +Patch0283: 0283-systemctl-unbreak-switchroot.patch +Patch0284: 0284-systemd-detect-virt-fix-detect-s390-virtualization.patch +Patch0285: 0285-exec-Add-SELinuxContext-configuration-item.patch +Patch0286: 0286-exec-Ignore-the-setting-SELinuxContext-if-selinux-is.patch +Patch0287: 0287-exec-Add-support-for-ignoring-errors-on-SELinuxConte.patch +Patch0288: 0288-core-store-and-expose-SELinuxContext-field-normalize.patch +Patch0289: 0289-socket-introduce-SELinuxContextFromNet-option.patch +Patch0290: 0290-sysctl-make-prefix-allow-all-kinds-of-sysctl-paths.patch +Patch0291: 0291-core-make-sure-to-serialize-jobs-for-all-units.patch +Patch0292: 0292-man-mention-localectl-in-locale.conf.patch +Patch0293: 0293-rules-automatically-online-hot-added-CPUs.patch +Patch0294: 0294-rules-add-rule-for-naming-Dell-iDRAC-USB-Virtual-NIC.patch +Patch0295: 0295-bash-completion-add-verb-set-property.patch +Patch0296: 0296-man-update-journald-rate-limit-defaults.patch +Patch0297: 0297-core-don-t-try-to-connect-to-d-bus-after-switchroot.patch +Patch0298: 0298-localed-log-locale-keymap-changes-in-detail.patch +Patch0299: 0299-localed-introduce-helper-function-to-simplify-matchi.patch +Patch0300: 0300-localed-check-for-partially-matching-converted-keyma.patch +Patch0301: 0301-fileio-make-parse_env_file-return-number-of-parsed-i.patch +Patch0302: 0302-localectl-print-warning-when-there-are-options-given.patch +Patch0303: 0303-dbus-fix-crash-when-appending-selinux-context.patch +Patch0304: 0304-tmpfiles-minor-modernizations.patch +Patch0305: 0305-install-when-looking-for-a-unit-file-for-enabling-se.patch +Patch0306: 0306-install-remove-unused-variable.patch +Patch0307: 0307-bootctl-typo-fix-in-help-message.patch +Patch0308: 0308-logind-ignore-failing-close-on-session-devices.patch +Patch0309: 0309-sysfs-show.c-return-negative-error.patch +Patch0310: 0310-core-only-send-SIGHUP-when-doing-first-kill-not-when.patch +Patch0311: 0311-cgroup-make-sure-to-properly-send-SIGCONT-to-all-pro.patch +Patch0312: 0312-core-don-t-send-duplicate-SIGCONT-when-killing-units.patch +Patch0313: 0313-efi-fix-Undefined-reference-efi_loader_get_boot_usec.patch +Patch0314: 0314-macro-better-make-IN_SET-macro-use-const-arrays.patch +Patch0315: 0315-macro-make-sure-we-can-use-IN_SET-also-with-complex-.patch +Patch0316: 0316-core-fix-property-changes-in-transient-units.patch +Patch0317: 0317-load-modules-properly-return-a-failing-error-code-if.patch +Patch0318: 0318-core-unit-fix-unit_add_target_dependencies-for-units.patch +Patch0319: 0319-man-there-is-no-ExecStopPre-for-service-units.patch +Patch0320: 0320-man-document-that-per-interface-sysctl-variables-are.patch +Patch0321: 0321-journal-downgrade-vaccuum-message-to-debug-level.patch +Patch0322: 0322-logs-show-fix-corrupt-output-with-empty-messages.patch +Patch0323: 0323-journalctl-refuse-extra-arguments-with-verify-and-si.patch +Patch0324: 0324-journal-assume-that-next-entry-is-after-previous-ent.patch +Patch0325: 0325-journal-forget-file-after-encountering-an-error.patch +Patch0326: 0326-man-update-link-to-LSB.patch +Patch0327: 0327-man-systemd-bootchart-fix-spacing-in-command.patch +Patch0328: 0328-man-add-missing-comma.patch +Patch0329: 0329-units-Do-not-unescape-instance-name-in-systemd-backl.patch +Patch0330: 0330-manager-flush-memory-stream-before-using-the-buffer.patch +Patch0331: 0331-man-multiple-sleep-modes-are-to-be-separated-by-whit.patch +Patch0332: 0332-man-fix-description-of-systemctl-after-before.patch +Patch0333: 0333-udev-properly-detect-reference-to-unexisting-part-of.patch +Patch0334: 0334-gpt-auto-generator-don-t-return-OOM-on-parentless-de.patch +Patch0335: 0335-man-improve-wording-of-systemctl-s-after-before.patch +Patch0336: 0336-cgroup-it-s-not-OK-to-invoke-alloca-in-loops.patch +Patch0337: 0337-core-don-t-try-to-relabel-mounts-before-we-loaded-th.patch +Patch0338: 0338-systemctl-kill-mode-is-long-long-gone-don-t-mention-.patch +Patch0339: 0339-ask-password-when-the-user-types-a-overly-long-passw.patch +Patch0340: 0340-logind-don-t-print-error-if-devices-vanish-during-AC.patch +Patch0341: 0341-tty-ask-password-agent-return-negative-errno.patch +Patch0342: 0342-journal-cleanup-up-error-handling-in-update_catalog.patch +Patch0343: 0343-bash-completion-fix-__get_startable_units.patch +Patch0344: 0344-core-check-the-right-variable-for-failed-open.patch +Patch0345: 0345-util-allow-trailing-semicolons-on-define_trivial_cle.patch +Patch0346: 0346-man-sd_journal_send-does-nothing-when-journald-is-no.patch +Patch0347: 0347-man-clarify-that-the-ExecReload-command-should-be-sy.patch +Patch0348: 0348-conf-parser-never-consider-it-an-error-if-we-cannot-.patch +Patch0349: 0349-socket-properly-handle-if-our-service-vanished-durin.patch +Patch0350: 0350-Do-not-unescape-unit-names-in-Install-section.patch +Patch0351: 0351-util-ignore_file-should-not-allow-files-ending-with.patch +Patch0352: 0352-core-fix-invalid-free-in-killall.patch +Patch0353: 0353-install-fix-invalid-free-in-unit_file_mask.patch +Patch0354: 0354-unit-name-fix-detection-of-unit-templates-instances.patch +Patch0355: 0355-journald-make-MaxFileSec-really-default-to-1month.patch +Patch0356: 0356-bootchart-it-s-not-OK-to-return-1-from-a-main-progra.patch +Patch0357: 0357-journald-Fix-off-by-one-error-in-Missed-X-kernel-mes.patch +Patch0358: 0358-man-drop-references-to-removed-and-obsolete-systemct.patch +Patch0359: 0359-units-fix-BindsTo-logic-when-applied-relative-to-ser.patch +Patch0360: 0360-core-don-t-allow-enabling-if-unit-is-masked.patch +Patch0361: 0361-man-systemctl-document-enable-on-masked-units.patch +Patch0362: 0362-core-do-not-segfault-if-proc-swaps-cannot-be-opened.patch +Patch0363: 0363-man-we-don-t-have-Wanted-dependency.patch +Patch0364: 0364-environment-append-unit_id-to-error-messages-regardi.patch +Patch0365: 0365-udevd-add-event-timeout-commandline-option.patch +Patch0366: 0366-selinux-fix-potential-double-free-crash-in-child-pro.patch +Patch0367: 0367-selinux-pass-flag-to-correct-exec_spawn.patch +Patch0368: 0368-selinux-set-selinux-context-applied-on-exec-before-c.patch +Patch0369: 0369-logind-use-correct-who-enum-values-with-KillUnit.patch +Patch0370: 0370-logind-always-kill-session-when-termination-is-reque.patch +Patch0371: 0371-udev-net_id-correctly-name-netdevs-based-on-dev_port.patch +Patch0372: 0372-udev-net_id-dev_port-is-base-10.patch +Patch0373: 0373-udev-Fix-parsing-of-udev.event-timeout-kernel-parame.patch +Patch0374: 0374-login-rerun-vconsole-setup-when-switching-from-vgaco.patch +Patch0375: 0375-cgroups-agent-really-down-grade-log-level.patch +Patch0376: 0376-core-introduce-new-Delegate-yes-no-property-controll.patch +Patch0377: 0377-core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch +Patch0378: 0378-mount-use-libmount-to-enumerate-proc-self-mountinfo.patch +Patch0379: 0379-mount-monitor-for-utab-changes-with-inotify.patch +Patch0380: 0380-mount-add-remote-fs-dependencies-if-needed-after-cha.patch +Patch0381: 0381-mount-check-options-as-well-as-fstype-for-network-mo.patch +Patch0382: 0382-rules-don-t-enable-usb-pm-for-Avocent-devices.patch %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} @@ -302,6 +444,7 @@ BuildRequires: automake BuildRequires: autoconf BuildRequires: libtool BuildRequires: git +BuildRequires: libmount-devel Requires(post): coreutils Requires(post): gawk @@ -466,6 +609,7 @@ git am \ --exclude test/.gitignore \ --exclude units/.gitignore \ --exclude units/user/.gitignore \ + --exclude .travis.yml \ %{patches} @@ -1069,23 +1213,131 @@ getent passwd systemd-journal-gateway >/dev/null 2>&1 || useradd -r -l -u 191 -g %{_datadir}/systemd/gatewayd %changelog -* Wed Jan 07 2015 Lukas Nykryn - 208-11.6 -- rules: don't enable usb pm for Avocent devices (#1176736) -- core: introduce new Delegate=yes/no property controlling creation of cgroup subhierarchies (#1179715) -- core: don't migrate PIDs for units that may contain subcgroups, do this only for leaf units (#1179715) - -* Fri Dec 05 2014 Michal Sekletar - 208-11.5 -- socket: add SocketUser= and SocketGroup= for chown()ing (#1171054) - -* Mon Oct 06 2014 Lukáš Nykrýn - 208-11.4 -- util: reset signals when we fork off agents -- util: fix minimal race where we might miss SIGTERMs when forking off an agent - -* Mon Jul 21 2014 Lukáš Nykrýn - 208-11.2 -- units: order network-online.target after network.target - -* Fri Jul 11 2014 Lukáš Nykrýn - 208-11.1 -- units/serial-getty@.service: add [Install] section +* Mon Dec 22 2014 Lukas Nykryn - 208-20 +- core: introduce new Delegate=yes/no property controlling creation of cgroup subhierarchies (#1139223) +- core: don't migrate PIDs for units that may contain subcgroups, do this only for leaf units (#1139223) +- mount: use libmount to enumerate /proc/self/mountinfo (#1161417) +- mount: monitor for utab changes with inotify (#1161417) +- mount: add remote-fs dependencies if needed after change (#1161417) +- mount: check options as well as fstype for network mounts (#1161417) +- rules: don't enable usb pm for Avocent devices (#1155370) + +* Mon Nov 10 2014 Lukas Nykryn - 208-19 +- cgroups-agent: really down-grade log level (#1044386) + +* Mon Nov 10 2014 Lukas Nykryn - 208-18 +- login: rerun vconsole-setup when switching from vgacon to fbcon (#1002450) + +* Fri Nov 07 2014 Lukas Nykryn - 208-17 +- udev: net_id dev_port is base 10 (#1155996) +- udev: Fix parsing of udev.event-timeout kernel parameter (#1154778) + +* Thu Oct 30 2014 Lukas Nykryn - 208-16 +- logind: use correct "who" enum values with KillUnit. (#1155502) +- logind: always kill session when termination is requested (#1155502) +- udev: net_id - correctly name netdevs based on dev_port when set (#1155996) + +* Tue Oct 21 2014 Lukas Nykryn - 208-15 +- core: do not segfault if /proc/swaps cannot be opened (#1151239) +- man: we don't have 'Wanted' dependency (#1152487) +- environment: append unit_id to error messages regarding EnvironmentFile (#1147691) +- udevd: add --event-timeout commandline option (#1154778) + +* Wed Oct 08 2014 Lukas Nykryn - 208-14 +- core: don't allow enabling if unit is masked (#1149299) + +* Tue Oct 07 2014 Lukas Nykryn - 208-13 +- tmpfiles: minor modernizations (#1147524) +- install: when looking for a unit file for enabling, search for templates only after traversing all search directories (#1147524) +- install: remove unused variable (#1147524) +- bootctl: typo fix in help message (#1147524) +- logind: ignore failing close() on session-devices (#1147524) +- sysfs-show.c: return negative error (#1147524) +- core: only send SIGHUP when doing first kill, not when doing final sigkill (#1147524) +- cgroup: make sure to properly send SIGCONT to all processes of a cgroup if that's requested (#1147524) +- core: don't send duplicate SIGCONT when killing units (#1147524) +- efi: fix Undefined reference efi_loader_get_boot_usec when EFI support is disabled (#1147524) +- macro: better make IN_SET() macro use const arrays (#1147524) +- macro: make sure we can use IN_SET() also with complex function calls as first argument (#1147524) +- core: fix property changes in transient units (#1147524) +- load-modules: properly return a failing error code if some module fails to load (#1147524) +- core/unit: fix unit_add_target_dependencies() for units with no dependencies (#1147524) +- man: there is no ExecStopPre= for service units (#1147524) +- man: document that per-interface sysctl variables are applied as network interfaces show up (#1147524) +- journal: downgrade vaccuum message to debug level (#1147524) +- logs-show: fix corrupt output with empty messages (#1147524) +- journalctl: refuse extra arguments with --verify and similar (#1147524) +- journal: assume that next entry is after previous entry (#1147524) +- journal: forget file after encountering an error (#1147524) +- man: update link to LSB (#1147524) +- man: systemd-bootchart - fix spacing in command (#1147524) +- man: add missing comma (#1147524) +- units: Do not unescape instance name in systemd-backlight@.service (#1147524) +- manager: flush memory stream before using the buffer (#1147524) +- man: multiple sleep modes are to be separated by whitespace, not commas (#1147524) +- man: fix description of systemctl --after/--before (#1147524) +- udev: properly detect reference to unexisting part of PROGRAM's result (#1147524) +- gpt-auto-generator: don't return OOM on parentless devices (#1147524) +- man: improve wording of systemctl's --after/--before (#1147524) +- cgroup: it's not OK to invoke alloca() in loops (#1147524) +- core: don't try to relabel mounts before we loaded the policy (#1147524) +- systemctl: --kill-mode is long long gone, don't mention it in the man page (#1147524) +- ask-password: when the user types a overly long password, beep and refuse (#1147524) +- logind: don't print error if devices vanish during ACL-init (#1147524) +- tty-ask-password-agent: return negative errno (#1147524) +- journal: cleanup up error handling in update_catalog() (#1147524) +- bash completion: fix __get_startable_units (#1147524) +- core: check the right variable for failed open() (#1147524) +- man: sd_journal_send does nothing when journald is not available (#1147524) +- man: clarify that the ExecReload= command should be synchronous (#1147524) +- conf-parser: never consider it an error if we cannot load a drop-in file because it is missing (#1147524) +- socket: properly handle if our service vanished during runtime (#1147524) +- Do not unescape unit names in [Install] section (#1147524) +- util: ignore_file should not allow files ending with '~' (#1147524) +- core: fix invalid free() in killall() (#1147524) +- install: fix invalid free() in unit_file_mask() (#1147524) +- unit-name: fix detection of unit templates/instances (#1147524) +- journald: make MaxFileSec really default to 1month (#1147524) +- bootchart: it's not OK to return -1 from a main program (#1147524) +- journald: Fix off-by-one error in "Missed X kernel messages" warning (#1147524) +- man: drop references to removed and obsolete 'systemctl load' command (#1147524) +- units: fix BindsTo= logic when applied relative to services with Type=oneshot (#1147524) + +* Mon Sep 29 2014 Lukas Nykryn - 208-12 +- units/serial-getty@.service: add [Install] section (#1083936) +- units: order network-online.target after network.target (#1072431) +- util: consider both fuse.glusterfs and glusterfs network file systems (#1080229) +- core: make StopWhenUnneeded work in conjunction with units that fail during their start job (#986949) +- cgroups-agent: down-grade log level (#1044386) +- random-seed: raise POOL_SIZE_MIN constant to 1024 (#1066517) +- delta: do not use unicode chars in C locale (#1088419) +- core: print debug instead of error message (#1105608) +- journald: always add syslog facility for messages coming from kmsg (#1113215) +- fsck,fstab-generator: be lenient about missing fsck. (#1098310) +- rules/60-persistent-storage: add nvme pcie ssd scsi_id ENV (#1042990) +- cgls: fix running with -M option (#1085455) +- getty: Start getty on 3270 terminals available on Linux on System z (#1075729) +- core: Added support for ERRNO NOTIFY_SOCKET message parsing (#1106457) +- socket: add SocketUser= and SocketGroup= for chown()ing sockets in the file system (#1111761) +- tmpfiles: add --root option to operate on an alternate fs tree (#1111199) +- units: make ExecStopPost action part of ExecStart (#1036276) +- machine-id: only look into KVM uuid when we are not running in a container (#1123452) +- util: reset signals when we fork off agents (#1134818) +- udev: do not skip the execution of RUN when renaming a network device fails (#1102135) +- man: mention System Administrator's Guide in systemctl manpage (#978948) +- vconsole: also copy character maps (not just fonts) from vt1 to vt2, vt3, ... (#1002450) +- localed: consider an unset model as a wildcard (#903776) +- systemd-detect-virt: detect s390 virtualization (#1139149) +- socket: introduce SELinuxContextFromNet option (#1113790) +- sysctl: make --prefix allow all kinds of sysctl paths (#1138591) +- man: mention localectl in locale.conf (#1049286) +- rules: automatically online hot-added CPUs (#968811) +- rules: add rule for naming Dell iDRAC USB Virtual NIC as 'idrac' (#1054477) +- bash-completion: add verb set-property (#1064487) +- man: update journald rate limit defaults (#1145352) +- core: don't try to connect to d-bus after switchroot (#1083300) +- localed: check for partially matching converted keymaps (#1109145) +- fileio: make parse_env_file() return number of parsed items (#1069420) * Wed Apr 02 2014 Lukáš Nykrýn - 208-11 - logind-session: save stopping flag (#1082692)