summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--NEWS19
-rw-r--r--po/it.po138
-rw-r--r--src/basic/log.c6
-rw-r--r--src/basic/socket-util.h11
-rw-r--r--src/cgroups-agent/cgroups-agent.c48
-rw-r--r--src/core/cgroup.c19
-rw-r--r--src/core/dbus-socket.c2
-rw-r--r--src/core/dbus.c75
-rw-r--r--src/core/dbus.h2
-rw-r--r--src/core/execute.c2
-rw-r--r--src/core/manager.c164
-rw-r--r--src/core/manager.h3
-rw-r--r--src/core/socket.c6
-rw-r--r--src/core/unit.c2
-rw-r--r--src/core/unit.h1
-rw-r--r--src/coredump/coredump.c2
-rw-r--r--src/fsck/fsck.c2
-rw-r--r--src/import/importd.c2
-rw-r--r--src/journal/journal-send.c14
-rw-r--r--src/journal/journald-native.c14
-rw-r--r--src/journal/journald-server.c2
-rw-r--r--src/journal/journald-stream.c13
-rw-r--r--src/journal/journald-syslog.c36
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c2
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c4
-rw-r--r--src/login/pam_systemd.c2
-rw-r--r--src/reply-password/reply-password.c8
-rw-r--r--src/shared/ask-password-api.c2
-rw-r--r--src/shared/bus-unit-util.c4
-rw-r--r--src/socket-proxy/socket-proxyd.c17
-rw-r--r--src/systemctl/systemctl.c9
-rw-r--r--src/test/test-socket-util.c17
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c7
-rw-r--r--src/udev/udev-ctrl.c2
l---------test/TEST-12-ISSUE-3171/Makefile1
-rwxr-xr-xtest/TEST-12-ISSUE-3171/test.sh106
37 files changed, 521 insertions, 245 deletions
diff --git a/Makefile.am b/Makefile.am
index cf4e75996d..ee9e91a339 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5844,6 +5844,8 @@ EXTRA_DIST += \
test/TEST-10-ISSUE-2467/test.sh \
test/TEST-11-ISSUE-3166/Makefile \
test/TEST-11-ISSUE-3166/test.sh \
+ test/TEST-12-ISSUE-3171/Makefile \
+ test/TEST-12-ISSUE-3171/test.sh \
test/test-functions
EXTRA_DIST += \
diff --git a/NEWS b/NEWS
index 7abe338e8b..8f1cde01e8 100644
--- a/NEWS
+++ b/NEWS
@@ -38,7 +38,7 @@ CHANGES WITH 230 in spe:
and any service that should survive the end of any individual login
session can be started at a user service or scope using systemd-run.
systemd-run(1) man page has been extended with an example which shows
- how to run screen in a scope unit underneath user@.service. The same
+ how to run screen in a scope unit underneath user@.service. The same
command works for tmux.
After the user logs out of all sessions, user@.service will be
@@ -62,8 +62,8 @@ CHANGES WITH 230 in spe:
* LLDP support has been extended, and both passive (receive-only) and
active (sender) modes are supported. Passive mode ("routers-only") is
- enabled by default in systemd-networkd. Active LLDP mode is enabled
- by default for containers on the internal network. The "networkctl
+ enabled by default in systemd-networkd. Active LLDP mode is enabled
+ by default for containers on the internal network. The "networkctl
lldp" command may be used to list information gathered. "networkctl
status" will also show basic LLDP information on connected peers now.
@@ -101,7 +101,8 @@ CHANGES WITH 230 in spe:
* "systemctl show" gained a new --value switch, which allows print a
only the contents of a specific unit property, without also printing
- the property's name.
+ the property's name. Similar support was added to "show*" verbs
+ of loginctl and machinectl that output "key=value" lists.
* A new command "systemctl revert" has been added that may be used to
revert to the vendor version of a unit file, in case local changes
@@ -111,7 +112,7 @@ CHANGES WITH 230 in spe:
just hidden container images.
* systemd-bus-proxyd has been removed, as kdbus is unlikely to still be
- merged into the kernerl in its current form.
+ merged into the kernel in its current form.
* systemd-networkd gained support for configuring proxy ARP support for
each interface, via the ProxyArp= setting in .network files. It also
@@ -142,11 +143,11 @@ CHANGES WITH 230 in spe:
changed to use this functionality by default.
* The default start timeout may now be configured on the kernel command
- line via systemd.default_timeout_start_sec=. It was configurable
- previously via the DefaultTimeoutStartSec= option in
- /etc/systemd/system.conf already.
+ line via systemd.default_timeout_start_sec=. It was already
+ configurable via the DefaultTimeoutStartSec= option in
+ /etc/systemd/system.conf.
- * Socket units gaineda new TriggerLimitIntervalSec= and
+ * Socket units gained a new TriggerLimitIntervalSec= and
TriggerLimitBurst= setting to configure a limit on the activation
rate of the socket unit.
diff --git a/po/it.po b/po/it.po
index a8547b9395..24504da42b 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: systemd\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-11-22 16:37+0100\n"
-"PO-Revision-Date: 2015-11-22 16:54+0100\n"
+"POT-Creation-Date: 2016-05-07 04:45+0200\n"
+"PO-Revision-Date: 2016-05-07 04:55+0200\n"
"Last-Translator: Daniele Medri <dmedri@gmail.com>\n"
"Language-Team: Italian\n"
"Language: it\n"
@@ -16,11 +16,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.8.5\n"
+"X-Generator: Poedit 1.8.7.1\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
msgid "Send passphrase back to system"
-msgstr "Inviare la frase segreta (passphrase) al sistema"
+msgstr "Invia la frase segreta (passphrase) al sistema"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
msgid ""
@@ -63,7 +63,7 @@ msgstr ""
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
msgid "Reload the systemd state"
-msgstr "Riavviare lo stato di systemd"
+msgstr "Riavvia lo stato di systemd"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
msgid "Authentication is required to reload the systemd state."
@@ -251,48 +251,58 @@ msgstr ""
"gestione di sistema alla apertura/chiusura del portatile."
#: ../src/login/org.freedesktop.login1.policy.in.h:19
-msgid "Allow non-logged-in users to run programs"
+msgid "Allow non-logged-in user to run programs"
msgstr "Consenti agli utenti non connessi di eseguire programmi"
#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"E' necessaria un'esplicita richiesta per eseguire programmi come utenti non "
+"connessi."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow non-logged-in users to run programs"
+msgstr "Consenti agli utenti non connessi di eseguire programmi"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
msgid "Authentication is required to run programs as a non-logged-in user."
msgstr ""
"Autenticazione richiesta per consentire agli utenti non connessi di eseguire "
"programmi."
-#: ../src/login/org.freedesktop.login1.policy.in.h:21
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
msgid "Allow attaching devices to seats"
msgstr "Consenti di collegare dispositivi alle postazioni"
-#: ../src/login/org.freedesktop.login1.policy.in.h:22
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
msgid "Authentication is required for attaching a device to a seat."
msgstr ""
"Autenticazione richiesta per collegare un dispositivo ad una postazione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:23
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
msgid "Flush device to seat attachments"
msgstr "Scollega i dispositivi dalla postazione"
-#: ../src/login/org.freedesktop.login1.policy.in.h:24
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
msgid ""
"Authentication is required for resetting how devices are attached to seats."
msgstr ""
"Autenticazione richiesta per ripristinare come i dispositivi sono collegati "
"alle postazioni."
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
-msgstr "Spegnere il sistema"
+msgstr "Spegni il sistema (power off)"
-#: ../src/login/org.freedesktop.login1.policy.in.h:26
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
msgid "Authentication is required for powering off the system."
msgstr "Autenticazione richiesta per spegnere il sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:27
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
msgid "Power off the system while other users are logged in"
-msgstr "Spegnere il sistema mentre altri utenti sono connessi"
+msgstr "Spegni il sistema (power off) mentre altri utenti sono connessi"
-#: ../src/login/org.freedesktop.login1.policy.in.h:28
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
msgid ""
"Authentication is required for powering off the system while other users are "
"logged in."
@@ -300,11 +310,13 @@ msgstr ""
"Autenticazione richiesta per spegnere il sistema mentre altri utenti sono "
"connessi."
-#: ../src/login/org.freedesktop.login1.policy.in.h:29
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
msgid "Power off the system while an application asked to inhibit it"
-msgstr "Spegnere il sistema mentre un'applicazione chiede di inibirne l'azione"
+msgstr ""
+"Spegni il sistema (power off) mentre un'applicazione chiede di inibirne "
+"l'azione"
-#: ../src/login/org.freedesktop.login1.policy.in.h:30
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
msgid ""
"Authentication is required for powering off the system while an application "
"asked to inhibit it."
@@ -312,19 +324,19 @@ msgstr ""
"Autenticazione richiesta per spegnere il sistema mentre un'applicazione "
"chiede di inibirne l'azione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
-msgstr "Riavviare il sistema"
+msgstr "Riavvia il sistema (reboot)"
-#: ../src/login/org.freedesktop.login1.policy.in.h:32
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
msgid "Authentication is required for rebooting the system."
msgstr "Autenticazione richiesta per riavviare il sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:33
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
msgid "Reboot the system while other users are logged in"
-msgstr "Riavviare il sistema mentre altri utenti sono connessi"
+msgstr "Riavvia il sistema (reboot) mentre altri utenti sono connessi"
-#: ../src/login/org.freedesktop.login1.policy.in.h:34
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
msgid ""
"Authentication is required for rebooting the system while other users are "
"logged in."
@@ -332,12 +344,13 @@ msgstr ""
"Autenticazione richiesta per riavviare il sistema mentre altri utenti sono "
"connessi."
-#: ../src/login/org.freedesktop.login1.policy.in.h:35
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
msgid "Reboot the system while an application asked to inhibit it"
msgstr ""
-"Riavviare il sistema mentre un'applicazione chiede di inibirne l'azione"
+"Riavvia il sistema (reboot) mentre un'applicazione chiede di inibirne "
+"l'azione"
-#: ../src/login/org.freedesktop.login1.policy.in.h:36
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
msgid ""
"Authentication is required for rebooting the system while an application "
"asked to inhibit it."
@@ -345,19 +358,19 @@ msgstr ""
"Autenticazione richiesta per riavviare il sistema mentre un'applicazione "
"chiede di inibirne l'azione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
-msgstr "Sospendere il sistema"
+msgstr "Sospendi il sistema (suspend)"
-#: ../src/login/org.freedesktop.login1.policy.in.h:38
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
msgid "Authentication is required for suspending the system."
msgstr "Autenticazione richiesta per sospendere il sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:39
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
msgid "Suspend the system while other users are logged in"
-msgstr "Sospendere il sistema mentre altri utenti sono connessi"
+msgstr "Sospendi il sistema (suspend) mentre altri utenti sono connessi"
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
msgid ""
"Authentication is required for suspending the system while other users are "
"logged in."
@@ -365,12 +378,13 @@ msgstr ""
"Autenticazione richiesta per sospendere il sistema mentre altri utenti sono "
"connessi."
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Suspend the system while an application asked to inhibit it"
msgstr ""
-"Sospendere il sistema mentre un'applicazione chiede di inibirne l'azione"
+"Sospendi il sistema (suspend) mentre un'applicazione chiede di inibirne "
+"l'azione"
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
msgid ""
"Authentication is required for suspending the system while an application "
"asked to inhibit it."
@@ -378,19 +392,19 @@ msgstr ""
"Autenticazione richiesta per sospendere il sistema mentre un'applicazione "
"chiede di inibirne l'azione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
-msgstr "Ibernare il sistema"
+msgstr "Iberna il sistema (hibernate)"
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
msgid "Authentication is required for hibernating the system."
msgstr "Autenticazione richiesta per ibernare il sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
msgid "Hibernate the system while other users are logged in"
-msgstr "Ibernare il sistema mentre altri utenti sono connessi"
+msgstr "Iberna il sistema (hibernate) mentre altri utenti sono connessi"
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
msgid ""
"Authentication is required for hibernating the system while other users are "
"logged in."
@@ -398,11 +412,13 @@ msgstr ""
"Autenticazione richiesta per ibernare il sistema mentre altri utenti sono "
"connessi."
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Hibernate the system while an application asked to inhibit it"
-msgstr "Ibernare il sistema mentre un'applicazione chiede di inibirne l'azione"
+msgstr ""
+"Iberna il sistema (hibernate) mentre un'applicazione chiede di inibirne "
+"l'azione"
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
"Authentication is required for hibernating the system while an application "
"asked to inhibit it."
@@ -410,32 +426,32 @@ msgstr ""
"Autenticazione richiesta per ibernare il sistema mentre un'applicazione "
"chiede di inibirne l'azione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Manage active sessions, users and seats"
msgstr "Gestione delle sessioni attive, utenti e postazioni"
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid ""
"Authentication is required for managing active sessions, users and seats."
msgstr ""
"Autenticazione richiesta per gestire le sessioni attive, gli utenti e le "
"postazioni."
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
msgid "Lock or unlock active sessions"
msgstr "Blocca/sblocca sessioni attive"
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
msgid "Authentication is required to lock or unlock active sessions."
msgstr "Autenticazione richiesta per bloccare o sbloccare le sessioni attive."
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
msgid "Allow indication to the firmware to boot to setup interface"
msgstr ""
"Permette indicazioni per il firmware per avviare l'interfaccia di "
"configurazione"
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
msgid ""
"Authentication is required to indicate to the firmware to boot to setup "
"interface."
@@ -443,11 +459,11 @@ msgstr ""
"Autenticazione richiesta per indicare al firmware di avviare l'interfaccia "
"di configurazione."
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
msgstr "Configura un messaggio per gli utenti"
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
msgid "Authentication is required to set a wall message"
msgstr "Autenticazione richiesta per configurare un messaggio per gli utenti"
@@ -565,31 +581,31 @@ msgstr ""
"Autenticazione richiesta per verificare se la sincronizzazione dell'orario "
"in rete possa essere attivata."
-#: ../src/core/dbus-unit.c:428
+#: ../src/core/dbus-unit.c:450
msgid "Authentication is required to start '$(unit)'."
msgstr "Autenticazione richiesta per avviare '$(unit)'."
-#: ../src/core/dbus-unit.c:429
+#: ../src/core/dbus-unit.c:451
msgid "Authentication is required to stop '$(unit)'."
msgstr "Autenticazione richiesta per fermare '$(unit)'."
-#: ../src/core/dbus-unit.c:430
+#: ../src/core/dbus-unit.c:452
msgid "Authentication is required to reload '$(unit)'."
msgstr "Autenticazione richiesta per ricaricare '$(unit)'."
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+#: ../src/core/dbus-unit.c:453 ../src/core/dbus-unit.c:454
msgid "Authentication is required to restart '$(unit)'."
msgstr "Autenticazione richiesta per riavviare '$(unit)'."
-#: ../src/core/dbus-unit.c:535
+#: ../src/core/dbus-unit.c:560
msgid "Authentication is required to kill '$(unit)'."
msgstr "Autenticazione richiesta per terminare '$(unit)'."
-#: ../src/core/dbus-unit.c:565
+#: ../src/core/dbus-unit.c:590
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr ""
"Autenticazione richiesta per riconfigurare lo stato \"fallito\" di '$(unit)'."
-#: ../src/core/dbus-unit.c:597
+#: ../src/core/dbus-unit.c:622
msgid "Authentication is required to set properties on '$(unit)'."
msgstr "Autenticazione richiesta per configurare le proprietà di '$(unit)'."
diff --git a/src/basic/log.c b/src/basic/log.c
index d89e6f7274..3ea643b6e6 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -165,7 +165,7 @@ static int log_open_syslog(void) {
goto fail;
}
- if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+ if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
safe_close(syslog_fd);
/* Some legacy syslog systems still use stream
@@ -177,7 +177,7 @@ static int log_open_syslog(void) {
goto fail;
}
- if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+ if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
r = -errno;
goto fail;
}
@@ -215,7 +215,7 @@ static int log_open_journal(void) {
goto fail;
}
- if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+ if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
r = -errno;
goto fail;
}
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index d17a2f35f8..daa4b24a37 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -137,3 +137,14 @@ ssize_t next_datagram_size_fd(int fd);
#define CMSG_FOREACH(cmsg, mh) \
for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
+
+/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
+#define SOCKADDR_UN_LEN(sa) \
+ ({ \
+ const struct sockaddr_un *_sa = &(sa); \
+ assert(_sa->sun_family == AF_UNIX); \
+ offsetof(struct sockaddr_un, sun_path) + \
+ (_sa->sun_path[0] == 0 ? \
+ 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
+ strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
+ })
diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c
index aadfba0707..d7c722ac3d 100644
--- a/src/cgroups-agent/cgroups-agent.c
+++ b/src/cgroups-agent/cgroups-agent.c
@@ -18,15 +18,22 @@
***/
#include <stdlib.h>
+#include <sys/socket.h>
-#include "sd-bus.h"
-
-#include "bus-util.h"
+#include "fd-util.h"
#include "log.h"
+#include "socket-util.h"
int main(int argc, char *argv[]) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
- int r;
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/cgroups-agent",
+ };
+
+ _cleanup_close_ int fd = -1;
+ ssize_t n;
+ size_t l;
if (argc != 2) {
log_error("Incorrect number of arguments.");
@@ -37,27 +44,22 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
- /* We send this event to the private D-Bus socket and then the
- * system instance will forward this to the system bus. We do
- * this to avoid an activation loop when we start dbus when we
- * are called when the dbus service is shut down. */
-
- r = bus_connect_system_systemd(&bus);
- if (r < 0) {
- /* 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_errno(r, "Failed to get D-Bus connection: %m");
+ fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+ if (fd < 0) {
+ log_debug_errno(errno, "Failed to allocate socket: %m");
+ return EXIT_FAILURE;
+ }
+
+ l = strlen(argv[1]);
+
+ n = sendto(fd, argv[1], l, 0, &sa.sa, SOCKADDR_UN_LEN(sa.un));
+ if (n < 0) {
+ log_debug_errno(errno, "Failed to send cgroups agent message: %m");
return EXIT_FAILURE;
}
- r = sd_bus_emit_signal(bus,
- "/org/freedesktop/systemd1/agent",
- "org.freedesktop.systemd1.Agent",
- "Released",
- "s", argv[1]);
- if (r < 0) {
- log_debug_errno(r, "Failed to send signal message on private connection: %m");
+ if ((size_t) n != l) {
+ log_debug("Datagram size mismatch");
return EXIT_FAILURE;
}
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 25cc6962f9..996efde22b 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -857,6 +857,7 @@ static int unit_create_cgroup(
/* Keep track that this is now realized */
u->cgroup_realized = true;
u->cgroup_realized_mask = target_mask;
+ u->cgroup_enabled_mask = enable_mask;
if (u->type != UNIT_SLICE && !c->delegate) {
@@ -886,10 +887,10 @@ int unit_attach_pids_to_cgroup(Unit *u) {
return 0;
}
-static bool unit_has_mask_realized(Unit *u, CGroupMask target_mask) {
+static bool unit_has_mask_realized(Unit *u, CGroupMask target_mask, CGroupMask enable_mask) {
assert(u);
- return u->cgroup_realized && u->cgroup_realized_mask == target_mask;
+ return u->cgroup_realized && u->cgroup_realized_mask == target_mask && u->cgroup_enabled_mask == enable_mask;
}
/* Check if necessary controllers and attributes for a unit are in place.
@@ -910,7 +911,9 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
}
target_mask = unit_get_target_mask(u);
- if (unit_has_mask_realized(u, target_mask))
+ enable_mask = unit_get_enable_mask(u);
+
+ if (unit_has_mask_realized(u, target_mask, enable_mask))
return 0;
/* First, realize parents */
@@ -921,7 +924,6 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
}
/* And then do the real work */
- enable_mask = unit_get_enable_mask(u);
r = unit_create_cgroup(u, target_mask, enable_mask);
if (r < 0)
return r;
@@ -990,7 +992,7 @@ static void unit_queue_siblings(Unit *u) {
/* If the unit doesn't need any new controllers
* and has current ones realized, it doesn't need
* any changes. */
- if (unit_has_mask_realized(m, unit_get_target_mask(m)))
+ if (unit_has_mask_realized(m, unit_get_target_mask(m), unit_get_enable_mask(m)))
continue;
unit_add_to_cgroup_queue(m);
@@ -1069,6 +1071,7 @@ void unit_prune_cgroup(Unit *u) {
u->cgroup_realized = false;
u->cgroup_realized_mask = 0;
+ u->cgroup_enabled_mask = 0;
}
int unit_search_main_pid(Unit *u, pid_t *ret) {
@@ -1312,7 +1315,9 @@ int manager_setup_cgroup(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to watch control group inotify object: %m");
- r = sd_event_source_set_priority(m->cgroup_inotify_event_source, SD_EVENT_PRIORITY_IDLE - 5);
+ /* Process cgroup empty notifications early, but after service notifications and SIGCHLD. Also
+ * see handling of cgroup agent notifications, for the classic cgroup hierarchy support. */
+ r = sd_event_source_set_priority(m->cgroup_inotify_event_source, SD_EVENT_PRIORITY_NORMAL-5);
if (r < 0)
return log_error_errno(r, "Failed to set priority of inotify event source: %m");
@@ -1458,6 +1463,8 @@ int manager_notify_cgroup_empty(Manager *m, const char *cgroup) {
assert(m);
assert(cgroup);
+ log_debug("Got cgroup empty notification for: %s", cgroup);
+
u = manager_get_unit_by_cgroup(m, cgroup);
if (!u)
return 0;
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index bb09a515f8..961340608d 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -149,7 +149,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
SD_BUS_PROPERTY("NAccepted", "u", bus_property_get_unsigned, offsetof(Socket, n_accepted), 0),
SD_BUS_PROPERTY("FileDescriptorName", "s", property_get_fdname, 0, 0),
SD_BUS_PROPERTY("SocketProtocol", "i", bus_property_get_int, offsetof(Socket, socket_protocol), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TriggerLimitIntervalSec", "t", bus_property_get_usec, offsetof(Socket, trigger_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("TriggerLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, trigger_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TriggerLimitBurst", "u", bus_property_get_unsigned, offsetof(Socket, trigger_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 263955d874..3422a02d68 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -71,28 +71,42 @@ int bus_send_queued_message(Manager *m) {
return 0;
}
+int bus_forward_agent_released(Manager *m, const char *path) {
+ int r;
+
+ assert(m);
+ assert(path);
+
+ if (!MANAGER_IS_SYSTEM(m))
+ return 0;
+
+ if (!m->system_bus)
+ return 0;
+
+ /* If we are running a system instance we forward the agent message on the system bus, so that the user
+ * instances get notified about this, too */
+
+ r = sd_bus_emit_signal(m->system_bus,
+ "/org/freedesktop/systemd1/agent",
+ "org.freedesktop.systemd1.Agent",
+ "Released",
+ "s", path);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to propagate agent release message: %m");
+
+ return 1;
+}
+
static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- const char *cgroup, *me;
Manager *m = userdata;
+ const char *cgroup;
uid_t sender_uid;
- sd_bus *bus;
int r;
assert(message);
assert(m);
- /* ignore recursive events sent by us on the system/user bus */
- bus = sd_bus_message_get_bus(message);
- if (!sd_bus_is_server(bus)) {
- r = sd_bus_get_unique_name(bus, &me);
- if (r < 0)
- return r;
-
- if (streq_ptr(sd_bus_message_get_sender(message), me))
- return 0;
- }
-
/* only accept org.freedesktop.systemd1.Agent from UID=0 */
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
if (r < 0)
@@ -110,16 +124,6 @@ static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus
}
manager_notify_cgroup_empty(m, cgroup);
-
- /* if running as system-instance, forward under our name */
- if (MANAGER_IS_SYSTEM(m) && m->system_bus) {
- r = sd_bus_message_rewind(message, 1);
- if (r >= 0)
- r = sd_bus_send(m->system_bus, message, NULL);
- if (r < 0)
- log_warning_errno(r, "Failed to forward Released message: %m");
- }
-
return 0;
}
@@ -690,25 +694,6 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void
return 0;
}
- if (MANAGER_IS_SYSTEM(m)) {
- /* When we run as system instance we get the Released
- * signal via a direct connection */
-
- r = sd_bus_add_match(
- bus,
- NULL,
- "type='signal',"
- "interface='org.freedesktop.systemd1.Agent',"
- "member='Released',"
- "path='/org/freedesktop/systemd1/agent'",
- signal_agent_released, m);
-
- if (r < 0) {
- log_warning_errno(r, "Failed to register Released match on new connection bus: %m");
- return 0;
- }
- }
-
r = bus_setup_disconnected_match(m, bus);
if (r < 0)
return 0;
@@ -906,8 +891,8 @@ static int bus_setup_system(Manager *m, sd_bus *bus) {
assert(m);
assert(bus);
- /* On kdbus or if we are a user instance we get the Released message via the system bus */
- if (MANAGER_IS_USER(m) || m->kdbus_fd >= 0) {
+ /* if we are a user instance we get the Released message via the system bus */
+ if (MANAGER_IS_USER(m)) {
r = sd_bus_add_match(
bus,
NULL,
@@ -990,7 +975,7 @@ static int bus_init_private(Manager *m) {
return 0;
strcpy(sa.un.sun_path, "/run/systemd/private");
- salen = offsetof(union sockaddr_union, un.sun_path) + strlen("/run/systemd/private");
+ salen = SOCKADDR_UN_LEN(sa.un);
} else {
size_t left = sizeof(sa.un.sun_path);
char *p = sa.un.sun_path;
diff --git a/src/core/dbus.h b/src/core/dbus.h
index e16a84fbb8..6baaffbd75 100644
--- a/src/core/dbus.h
+++ b/src/core/dbus.h
@@ -40,3 +40,5 @@ int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error
int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
+
+int bus_forward_agent_released(Manager *m, const char *path);
diff --git a/src/core/execute.c b/src/core/execute.c
index ac2ac39892..5eb3f13695 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -271,7 +271,7 @@ static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
}
}
- r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
+ r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
r = -errno;
diff --git a/src/core/manager.c b/src/core/manager.c
index bd00c224f4..e192cd475d 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -87,6 +87,7 @@
#include "watchdog.h"
#define NOTIFY_RCVBUF_SIZE (8*1024*1024)
+#define CGROUPS_AGENT_RCVBUF_SIZE (8*1024*1024)
/* Initial delay and the interval for printing status messages about running jobs */
#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
@@ -94,6 +95,7 @@
#define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
+static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
@@ -484,11 +486,11 @@ static int manager_setup_signals(Manager *m) {
(void) sd_event_source_set_description(m->signal_event_source, "manager-signal");
- /* Process signals a bit earlier than the rest of things, but
- * later than notify_fd processing, so that the notify
- * processing can still figure out to which process/service a
- * message belongs, before we reap the process. */
- r = sd_event_source_set_priority(m->signal_event_source, SD_EVENT_PRIORITY_NORMAL-5);
+ /* Process signals a bit earlier than the rest of things, but later than notify_fd processing, so that the
+ * notify processing can still figure out to which process/service a message belongs, before we reap the
+ * process. Also, process this before handling cgroup notifications, so that we always collect child exit
+ * status information before detecting that there's no process in a cgroup. */
+ r = sd_event_source_set_priority(m->signal_event_source, SD_EVENT_PRIORITY_NORMAL-6);
if (r < 0)
return r;
@@ -581,12 +583,12 @@ int manager_new(UnitFileScope scope, bool test_run, Manager **_m) {
m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
- m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd =
- m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = m->cgroup_inotify_fd = -1;
+ m->pin_cgroupfs_fd = m->notify_fd = m->cgroups_agent_fd = m->signal_fd = m->time_change_fd =
+ m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = m->cgroup_inotify_fd =
+ m->ask_password_inotify_fd = -1;
m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
- m->ask_password_inotify_fd = -1;
m->have_ask_password = -EINVAL; /* we don't know */
m->first_boot = -1;
@@ -703,7 +705,7 @@ static int manager_setup_notify(Manager *m) {
(void) unlink(m->notify_socket);
strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
- r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
+ r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
@@ -722,8 +724,8 @@ static int manager_setup_notify(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to allocate notify event source: %m");
- /* Process signals a bit earlier than SIGCHLD, so that we can
- * still identify to which service an exit message belongs */
+ /* Process notification messages a bit earlier than SIGCHLD, so that we can still identify to which
+ * service an exit message belongs. */
r = sd_event_source_set_priority(m->notify_event_source, SD_EVENT_PRIORITY_NORMAL-7);
if (r < 0)
return log_error_errno(r, "Failed to set priority of notify event source: %m");
@@ -734,6 +736,79 @@ static int manager_setup_notify(Manager *m) {
return 0;
}
+static int manager_setup_cgroups_agent(Manager *m) {
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/cgroups-agent",
+ };
+ int r;
+
+ /* This creates a listening socket we receive cgroups agent messages on. We do not use D-Bus for delivering
+ * these messages from the cgroups agent binary to PID 1, as the cgroups agent binary is very short-living, and
+ * each instance of it needs a new D-Bus connection. Since D-Bus connections are SOCK_STREAM/AF_UNIX, on
+ * overloaded systems the backlog of the D-Bus socket becomes relevant, as not more than the configured number
+ * of D-Bus connections may be queued until the kernel will start dropping further incoming connections,
+ * possibly resulting in lost cgroups agent messages. To avoid this, we'll use a private SOCK_DGRAM/AF_UNIX
+ * socket, where no backlog is relevant as communication may take place without an actual connect() cycle, and
+ * we thus won't lose messages.
+ *
+ * Note that PID 1 will forward the agent message to system bus, so that the user systemd instance may listen
+ * to it. The system instance hence listens on this special socket, but the user instances listen on the system
+ * bus for these messages. */
+
+ if (m->test_run)
+ return 0;
+
+ if (!MANAGER_IS_SYSTEM(m))
+ return 0;
+
+ if (cg_unified() > 0) /* We don't need this anymore on the unified hierarchy */
+ return 0;
+
+ if (m->cgroups_agent_fd < 0) {
+ _cleanup_close_ int fd = -1;
+
+ /* First free all secondary fields */
+ m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
+
+ fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+ if (fd < 0)
+ return log_error_errno(errno, "Failed to allocate cgroups agent socket: %m");
+
+ fd_inc_rcvbuf(fd, CGROUPS_AGENT_RCVBUF_SIZE);
+
+ (void) unlink(sa.un.sun_path);
+
+ /* Only allow root to connect to this socket */
+ RUN_WITH_UMASK(0077)
+ r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
+ if (r < 0)
+ return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
+
+ m->cgroups_agent_fd = fd;
+ fd = -1;
+ }
+
+ if (!m->cgroups_agent_event_source) {
+ r = sd_event_add_io(m->event, &m->cgroups_agent_event_source, m->cgroups_agent_fd, EPOLLIN, manager_dispatch_cgroups_agent_fd, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate cgroups agent event source: %m");
+
+ /* Process cgroups notifications early, but after having processed service notification messages or
+ * SIGCHLD signals, so that a cgroup running empty is always just the last safety net of notification,
+ * and we collected the metadata the notification and SIGCHLD stuff offers first. Also see handling of
+ * cgroup inotify for the unified cgroup stuff. */
+ r = sd_event_source_set_priority(m->cgroups_agent_event_source, SD_EVENT_PRIORITY_NORMAL-5);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set priority of cgroups agent event source: %m");
+
+ (void) sd_event_source_set_description(m->cgroups_agent_event_source, "manager-cgroups-agent");
+ }
+
+ return 0;
+}
+
static int manager_setup_kdbus(Manager *m) {
_cleanup_free_ char *p = NULL;
@@ -944,12 +1019,14 @@ Manager* manager_free(Manager *m) {
sd_event_source_unref(m->signal_event_source);
sd_event_source_unref(m->notify_event_source);
+ sd_event_source_unref(m->cgroups_agent_event_source);
sd_event_source_unref(m->time_change_event_source);
sd_event_source_unref(m->jobs_in_progress_event_source);
sd_event_source_unref(m->run_queue_event_source);
safe_close(m->signal_fd);
safe_close(m->notify_fd);
+ safe_close(m->cgroups_agent_fd);
safe_close(m->time_change_fd);
safe_close(m->kdbus_fd);
@@ -1142,6 +1219,10 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
if (q < 0 && r == 0)
r = q;
+ q = manager_setup_cgroups_agent(m);
+ if (q < 0 && r == 0)
+ r = q;
+
/* We might have deserialized the kdbus control fd, but if we
* didn't, then let's create the bus now. */
manager_setup_kdbus(m);
@@ -1479,6 +1560,35 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
return n;
}
+static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
+ Manager *m = userdata;
+ char buf[PATH_MAX+1];
+ ssize_t n;
+
+ n = recv(fd, buf, sizeof(buf), 0);
+ if (n < 0)
+ return log_error_errno(errno, "Failed to read cgroups agent message: %m");
+ if (n == 0) {
+ log_error("Got zero-length cgroups agent message, ignoring.");
+ return 0;
+ }
+ if ((size_t) n >= sizeof(buf)) {
+ log_error("Got overly long cgroups agent message, ignoring.");
+ return 0;
+ }
+
+ if (memchr(buf, 0, n)) {
+ log_error("Got cgroups agent message with embedded NUL byte, ignoring.");
+ return 0;
+ }
+ buf[n] = 0;
+
+ manager_notify_cgroup_empty(m, buf);
+ bus_forward_agent_released(m, buf);
+
+ return 0;
+}
+
static void manager_invoke_notify_message(Manager *m, Unit *u, pid_t pid, const char *buf, size_t n, FDSet *fds) {
_cleanup_strv_free_ char **tags = NULL;
@@ -2135,11 +2245,10 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
}
void manager_send_unit_plymouth(Manager *m, Unit *u) {
- union sockaddr_union sa = PLYMOUTH_SOCKET;
-
- int n = 0;
+ static const union sockaddr_union sa = PLYMOUTH_SOCKET;
_cleanup_free_ char *message = NULL;
_cleanup_close_ int fd = -1;
+ int n = 0;
/* Don't generate plymouth events if the service was already
* started and we're just deserializing */
@@ -2165,7 +2274,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
return;
}
- if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
log_error_errno(errno, "connect() failed: %m");
@@ -2265,6 +2374,16 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
fprintf(f, "notify-socket=%s\n", m->notify_socket);
}
+ if (m->cgroups_agent_fd >= 0) {
+ int copy;
+
+ copy = fdset_put_dup(fds, m->cgroups_agent_fd);
+ if (copy < 0)
+ return copy;
+
+ fprintf(f, "cgroups-agent-fd=%i\n", copy);
+ }
+
if (m->kdbus_fd >= 0) {
int copy;
@@ -2432,6 +2551,17 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
free(m->notify_socket);
m->notify_socket = n;
+ } else if (startswith(l, "cgroups-agent-fd=")) {
+ int fd;
+
+ if (safe_atoi(l + 17, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+ log_debug("Failed to parse cgroups agent fd: %s", l + 10);
+ else {
+ m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
+ safe_close(m->cgroups_agent_fd);
+ m->cgroups_agent_fd = fdset_remove(fds, fd);
+ }
+
} else if (startswith(l, "kdbus-fd=")) {
int fd;
@@ -2552,6 +2682,10 @@ int manager_reload(Manager *m) {
if (q < 0 && r >= 0)
r = q;
+ q = manager_setup_cgroups_agent(m);
+ if (q < 0 && r >= 0)
+ r = q;
+
/* Third, fire things up! */
manager_coldplug(m);
diff --git a/src/core/manager.h b/src/core/manager.h
index 17f84e6963..4bccca75cb 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -132,6 +132,9 @@ struct Manager {
int notify_fd;
sd_event_source *notify_event_source;
+ int cgroups_agent_fd;
+ sd_event_source *cgroups_agent_event_source;
+
int signal_fd;
sd_event_source *signal_event_source;
diff --git a/src/core/socket.c b/src/core/socket.c
index 016df40b8c..d4b409ef53 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -690,6 +690,12 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
}
+ fprintf(f,
+ "%sTriggerLimitIntervalSec: %s\n"
+ "%sTriggerLimitBurst: %u\n",
+ prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->trigger_limit.interval, USEC_PER_SEC),
+ prefix, s->trigger_limit.burst);
+
exec_context_dump(&s->exec_context, f, prefix);
kill_context_dump(&s->kill_context, f, prefix);
diff --git a/src/core/unit.c b/src/core/unit.c
index 8153515e89..d8ab5781b0 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1247,7 +1247,7 @@ int unit_load(Unit *u) {
fclose(u->transient_file);
u->transient_file = NULL;
- u->dropin_mtime = now(CLOCK_REALTIME);
+ u->fragment_mtime = now(CLOCK_REALTIME);
}
if (UNIT_VTABLE(u)->load) {
diff --git a/src/core/unit.h b/src/core/unit.h
index f14972728e..08a927962d 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -186,6 +186,7 @@ struct Unit {
/* Counterparts in the cgroup filesystem */
char *cgroup_path;
CGroupMask cgroup_realized_mask;
+ CGroupMask cgroup_enabled_mask;
CGroupMask cgroup_subtree_mask;
CGroupMask cgroup_members_mask;
int cgroup_inotify_wd;
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 41fc1993d5..01fdcfa909 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -847,7 +847,7 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd)
if (fd < 0)
return log_error_errno(errno, "Failed to create coredump socket: %m");
- if (connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return log_error_errno(errno, "Failed to connect to coredump service: %m");
for (i = 0; i < n_iovec; i++) {
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index 6f56066da8..d32e1d923e 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -262,7 +262,7 @@ static int fsck_progress_socket(void) {
if (fd < 0)
return log_warning_errno(errno, "socket(): %m");
- if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
r = log_full_errno(errno == ECONNREFUSED || errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path);
safe_close(fd);
diff --git a/src/import/importd.c b/src/import/importd.c
index d2a5867a6e..956a82945c 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -677,7 +677,7 @@ static int manager_new(Manager **ret) {
(void) mkdir_parents_label(sa.un.sun_path, 0755);
(void) unlink(sa.un.sun_path);
- if (bind(m->notify_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
+ if (bind(m->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return -errno;
if (setsockopt(m->notify_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index f0959b6237..5e8a3e3200 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -208,13 +208,13 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
struct iovec *w;
uint64_t *l;
int i, j = 0;
- struct sockaddr_un sa = {
- .sun_family = AF_UNIX,
- .sun_path = "/run/systemd/journal/socket",
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/socket",
};
struct msghdr mh = {
- .msg_name = &sa,
- .msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path),
+ .msg_name = (struct sockaddr*) &sa.sa,
+ .msg_namelen = SOCKADDR_UN_LEN(sa.un),
};
ssize_t k;
bool have_syslog_identifier = false;
@@ -392,7 +392,7 @@ _public_ int sd_journal_perror(const char *message) {
}
_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
- union sockaddr_union sa = {
+ static const union sockaddr_union sa = {
.un.sun_family = AF_UNIX,
.un.sun_path = "/run/systemd/journal/stdout",
};
@@ -408,7 +408,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
if (fd < 0)
return -errno;
- r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+ r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return -errno;
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index a445291a5e..0a1ce205c2 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -448,24 +448,24 @@ void server_process_native_file(
}
int server_open_native_socket(Server*s) {
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/socket",
+ };
static const int one = 1;
int r;
assert(s);
if (s->native_fd < 0) {
- union sockaddr_union sa = {
- .un.sun_family = AF_UNIX,
- .un.sun_path = "/run/systemd/journal/socket",
- };
-
s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (s->native_fd < 0)
return log_error_errno(errno, "socket() failed: %m");
- unlink(sa.un.sun_path);
+ (void) unlink(sa.un.sun_path);
- r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+ r = bind(s->native_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index e14d0ad980..8f82d2a838 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1696,7 +1696,7 @@ static int server_connect_notify(Server *s) {
if (sa.un.sun_path[0] == '@')
sa.un.sun_path[0] = 0;
- r = connect(s->notify_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(e));
+ r = connect(s->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "Failed to connect to notify socket: %m");
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
index 59352bcb3f..4ad16ee41c 100644
--- a/src/journal/journald-stream.c
+++ b/src/journal/journald-stream.c
@@ -700,23 +700,22 @@ fail:
}
int server_open_stdout_socket(Server *s) {
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/stdout",
+ };
int r;
assert(s);
if (s->stdout_fd < 0) {
- union sockaddr_union sa = {
- .un.sun_family = AF_UNIX,
- .un.sun_path = "/run/systemd/journal/stdout",
- };
-
s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (s->stdout_fd < 0)
return log_error_errno(errno, "socket() failed: %m");
- unlink(sa.un.sun_path);
+ (void) unlink(sa.un.sun_path);
- r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+ r = bind(s->stdout_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 5153fd0cce..0609b4b694 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -52,8 +52,7 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
.msg_iov = (struct iovec *) iovec,
.msg_iovlen = n_iovec,
.msg_name = (struct sockaddr*) &sa.sa,
- .msg_namelen = offsetof(union sockaddr_union, un.sun_path)
- + strlen("/run/systemd/journal/syslog"),
+ .msg_namelen = SOCKADDR_UN_LEN(sa.un),
};
struct cmsghdr *cmsg;
union {
@@ -316,12 +315,12 @@ static void syslog_skip_date(char **buf) {
}
void server_process_syslog_message(
- Server *s,
- const char *buf,
- const struct ucred *ucred,
- const struct timeval *tv,
- const char *label,
- size_t label_len) {
+ Server *s,
+ const char *buf,
+ const struct ucred *ucred,
+ const struct timeval *tv,
+ const char *label,
+ size_t label_len) {
char syslog_priority[sizeof("PRIORITY=") + DECIMAL_STR_MAX(int)],
syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
@@ -365,14 +364,12 @@ void server_process_syslog_message(
if (identifier) {
syslog_identifier = strjoina("SYSLOG_IDENTIFIER=", identifier);
- if (syslog_identifier)
- IOVEC_SET_STRING(iovec[n++], syslog_identifier);
+ IOVEC_SET_STRING(iovec[n++], syslog_identifier);
}
if (pid) {
syslog_pid = strjoina("SYSLOG_PID=", pid);
- if (syslog_pid)
- IOVEC_SET_STRING(iovec[n++], syslog_pid);
+ IOVEC_SET_STRING(iovec[n++], syslog_pid);
}
message = strjoina("MESSAGE=", buf);
@@ -383,24 +380,24 @@ void server_process_syslog_message(
}
int server_open_syslog_socket(Server *s) {
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/dev-log",
+ };
static const int one = 1;
int r;
assert(s);
if (s->syslog_fd < 0) {
- static const union sockaddr_union sa = {
- .un.sun_family = AF_UNIX,
- .un.sun_path = "/run/systemd/journal/dev-log",
- };
-
s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (s->syslog_fd < 0)
return log_error_errno(errno, "socket() failed: %m");
- unlink(sa.un.sun_path);
+ (void) unlink(sa.un.sun_path);
- r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+ r = bind(s->syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
@@ -437,6 +434,7 @@ int server_open_syslog_socket(Server *s) {
void server_maybe_warn_forward_syslog_missed(Server *s) {
usec_t n;
+
assert(s);
if (s->n_forward_syslog_missed <= 0)
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 04da94e7e3..ed5f94e136 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -836,7 +836,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid)
b->sockaddr.un.sun_family = AF_UNIX;
strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
- b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + strlen("/var/run/dbus/system_bus_socket");
+ b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
return 0;
}
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index bd1c7f15ff..4da9dbfd63 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -458,9 +458,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
if (sockaddr.un.sun_path[0] == '@')
sockaddr.un.sun_path[0] = 0;
- msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
- if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
- msghdr.msg_namelen = sizeof(struct sockaddr_un);
+ msghdr.msg_namelen = SOCKADDR_UN_LEN(sockaddr.un);
have_pid = pid != 0 && pid != getpid();
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index 40e246bb06..98dc201340 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -150,7 +150,7 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_
if (fd < 0)
return -errno;
- if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0)
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return -errno;
r = getpeercred(fd, &ucred);
diff --git a/src/reply-password/reply-password.c b/src/reply-password/reply-password.c
index e291758969..17eab9772e 100644
--- a/src/reply-password/reply-password.c
+++ b/src/reply-password/reply-password.c
@@ -26,14 +26,12 @@
#include "fd-util.h"
#include "log.h"
#include "macro.h"
+#include "socket-util.h"
#include "string-util.h"
#include "util.h"
static int send_on_socket(int fd, const char *socket_name, const void *packet, size_t size) {
- union {
- struct sockaddr sa;
- struct sockaddr_un un;
- } sa = {
+ union sockaddr_union sa = {
.un.sun_family = AF_UNIX,
};
@@ -43,7 +41,7 @@ static int send_on_socket(int fd, const char *socket_name, const void *packet, s
strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
- if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0)
+ if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return log_error_errno(errno, "Failed to send: %m");
return 0;
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index 6805873f9e..4a4bd8d3b8 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -431,7 +431,7 @@ static int create_socket(char **name) {
snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%" PRIx64, random_u64());
RUN_WITH_UMASK(0177) {
- if (bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0)
+ if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return -errno;
}
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index 2b755cea28..ee388b82db 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -210,7 +210,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
} else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) {
uint64_t u;
- r = cg_cpu_shares_parse(eq, &u);
+ r = cg_blkio_weight_parse(eq, &u);
if (r < 0) {
log_error("Failed to parse %s value %s.", field, eq);
return -EINVAL;
@@ -331,7 +331,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
log_error("Failed to parse %s value %s.", field, weight);
return -EINVAL;
}
- r = sd_bus_message_append(m, "v", "a(st)", path, u);
+ r = sd_bus_message_append(m, "v", "a(st)", 1, path, u);
}
} else if (streq(field, "Nice")) {
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c
index 1157a0c72e..52b4db8875 100644
--- a/src/socket-proxy/socket-proxyd.c
+++ b/src/socket-proxy/socket-proxyd.c
@@ -400,28 +400,19 @@ static int resolve_remote(Connection *c) {
union sockaddr_union sa = {};
const char *node, *service;
- socklen_t salen;
int r;
if (path_is_absolute(arg_remote_host)) {
sa.un.sun_family = AF_UNIX;
- strncpy(sa.un.sun_path, arg_remote_host, sizeof(sa.un.sun_path)-1);
- sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;
-
- salen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
-
- return connection_start(c, &sa.sa, salen);
+ strncpy(sa.un.sun_path, arg_remote_host, sizeof(sa.un.sun_path));
+ return connection_start(c, &sa.sa, SOCKADDR_UN_LEN(sa.un));
}
if (arg_remote_host[0] == '@') {
sa.un.sun_family = AF_UNIX;
sa.un.sun_path[0] = 0;
- strncpy(sa.un.sun_path+1, arg_remote_host+1, sizeof(sa.un.sun_path)-2);
- sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;
-
- salen = offsetof(union sockaddr_union, un.sun_path) + 1 + strlen(sa.un.sun_path + 1);
-
- return connection_start(c, &sa.sa, salen);
+ strncpy(sa.un.sun_path+1, arg_remote_host+1, sizeof(sa.un.sun_path)-1);
+ return connection_start(c, &sa.sa, SOCKADDR_UN_LEN(sa.un));
}
service = strrchr(arg_remote_host, ':');
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 7d0d4966d5..639080bc66 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1355,7 +1355,7 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
} else
id_cols = max_id_len;
- if (!arg_no_legend)
+ if (!arg_no_legend && c > 0)
printf("%-*s %-*s\n",
id_cols, "UNIT FILE",
state_cols, "STATE");
@@ -1422,8 +1422,8 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
n_units = hashmap_size(h);
- units = new(UnitFileList, n_units);
- if (!units && n_units > 0) {
+ units = new(UnitFileList, n_units ?: 1); /* avoid malloc(0) */
+ if (!units) {
unit_file_list_free(h);
return log_oom();
}
@@ -1519,10 +1519,9 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
output_unit_file_list(units, c);
- if (install_client_side()) {
+ if (install_client_side())
for (unit = units; unit < units + c; unit++)
free(unit->path);
- }
return 0;
}
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index 33ff3755bc..9e01f3afd4 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -343,6 +343,21 @@ static void test_sockaddr_equal(void) {
assert_se(!sockaddr_equal(&b, &c));
}
+static void test_sockaddr_un_len(void) {
+ static const struct sockaddr_un fs = {
+ .sun_family = AF_UNIX,
+ .sun_path = "/foo/bar/waldo",
+ };
+
+ static const struct sockaddr_un abstract = {
+ .sun_family = AF_UNIX,
+ .sun_path = "\0foobar",
+ };
+
+ assert_se(SOCKADDR_UN_LEN(fs) == offsetof(struct sockaddr_un, sun_path) + strlen(fs.sun_path));
+ assert_se(SOCKADDR_UN_LEN(abstract) == offsetof(struct sockaddr_un, sun_path) + 1 + strlen(abstract.sun_path + 1));
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
@@ -363,5 +378,7 @@ int main(int argc, char *argv[]) {
test_sockaddr_equal();
+ test_sockaddr_un_len();
+
return 0;
}
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 c7ded451a2..ee879c7b89 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -65,8 +65,8 @@ static int ask_password_plymouth(
const char *flag_file,
char ***ret) {
+ static const union sockaddr_union sa = PLYMOUTH_SOCKET;
_cleanup_close_ int fd = -1, notify = -1;
- union sockaddr_union sa = PLYMOUTH_SOCKET;
_cleanup_free_ char *packet = NULL;
ssize_t k;
int r, n;
@@ -94,7 +94,7 @@ static int ask_password_plymouth(
if (fd < 0)
return -errno;
- r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
+ r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
return -errno;
@@ -269,8 +269,7 @@ static int send_passwords(const char *socket_name, char **passwords) {
strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
- r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa,
- offsetof(struct sockaddr_un, sun_path) + strlen(socket_name));
+ r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, SOCKADDR_UN_LEN(sa.un));
if (r < 0)
r = log_debug_errno(errno, "sendto(): %m");
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index 962de22f43..f68a09d7a8 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -105,7 +105,7 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) {
uctrl->saddr.un.sun_family = AF_LOCAL;
strscpy(uctrl->saddr.un.sun_path, sizeof(uctrl->saddr.un.sun_path), "/run/udev/control");
- uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.un.sun_path);
+ uctrl->addrlen = SOCKADDR_UN_LEN(uctrl->saddr.un);
return uctrl;
}
diff --git a/test/TEST-12-ISSUE-3171/Makefile b/test/TEST-12-ISSUE-3171/Makefile
new file mode 120000
index 0000000000..e9f93b1104
--- /dev/null
+++ b/test/TEST-12-ISSUE-3171/Makefile
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile \ No newline at end of file
diff --git a/test/TEST-12-ISSUE-3171/test.sh b/test/TEST-12-ISSUE-3171/test.sh
new file mode 100755
index 0000000000..925dcad9ea
--- /dev/null
+++ b/test/TEST-12-ISSUE-3171/test.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3171"
+
+. $TEST_BASE_DIR/test-functions
+
+test_run() {
+ run_nspawn || return 1
+ check_result_nspawn || return 1
+ return 0
+}
+
+test_setup() {
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ setup_basic_environment
+ dracut_install cat mv stat nc
+
+ # setup the testsuite service
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/test-socket-group.sh
+Type=oneshot
+EOF
+
+
+ cat >$initdir/test-socket-group.sh <<'EOF'
+#!/bin/bash
+set -x
+set -e
+set -o pipefail
+
+U=/run/systemd/system/test.socket
+cat <<'EOL' >$U
+[Unit]
+Description=Test socket
+[Socket]
+Accept=yes
+ListenStream=/run/test.socket
+SocketGroup=adm
+SocketMode=0660
+EOL
+
+cat <<'EOL' > /run/systemd/system/test@.service
+[Unit]
+Description=Test service
+[Service]
+StandardInput=socket
+ExecStart=/bin/sh -x -c cat
+EOL
+
+systemctl start test.socket
+systemctl is-active test.socket
+[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
+echo A | nc -U /run/test.socket
+
+mv $U ${U}.disabled
+systemctl daemon-reload
+systemctl is-active test.socket
+[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
+echo B | nc -U /run/test.socket && exit 1
+
+mv ${U}.disabled $U
+systemctl daemon-reload
+systemctl is-active test.socket
+echo C | nc -U /run/test.socket && exit 1
+[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
+
+systemctl restart test.socket
+systemctl is-active test.socket
+echo D | nc -U /run/test.socket
+[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
+
+
+touch /testok
+EOF
+
+ chmod 0755 $initdir/test-socket-group.sh
+ setup_testsuite
+ ) || return 1
+
+ setup_nspawn_root
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+test_cleanup() {
+ umount $TESTDIR/root 2>/dev/null
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+ return 0
+}
+
+do_test "$@"