]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #3205 from poettering/iaid
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 7 May 2016 19:31:58 +0000 (15:31 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 7 May 2016 19:31:58 +0000 (15:31 -0400)
more dhcp fixes

37 files changed:
Makefile.am
NEWS
po/it.po
src/basic/log.c
src/basic/socket-util.h
src/cgroups-agent/cgroups-agent.c
src/core/cgroup.c
src/core/dbus-socket.c
src/core/dbus.c
src/core/dbus.h
src/core/execute.c
src/core/manager.c
src/core/manager.h
src/core/socket.c
src/core/unit.c
src/core/unit.h
src/coredump/coredump.c
src/fsck/fsck.c
src/import/importd.c
src/journal/journal-send.c
src/journal/journald-native.c
src/journal/journald-server.c
src/journal/journald-stream.c
src/journal/journald-syslog.c
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-daemon/sd-daemon.c
src/login/pam_systemd.c
src/reply-password/reply-password.c
src/shared/ask-password-api.c
src/shared/bus-unit-util.c
src/socket-proxy/socket-proxyd.c
src/systemctl/systemctl.c
src/test/test-socket-util.c
src/tty-ask-password-agent/tty-ask-password-agent.c
src/udev/udev-ctrl.c
test/TEST-12-ISSUE-3171/Makefile [new symlink]
test/TEST-12-ISSUE-3171/test.sh [new file with mode: 0755]

index cf4e75996d5790255dd8ef30da3c8c3f107caaae..ee9e91a33982bda0b16132558ced1683fac3197b 100644 (file)
@@ -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 7abe338e8b0381a2e8cc42e9c0aa639308ca8034..8f1cde01e8307d311a9a1059bec94a6655b267aa 100644 (file)
--- 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.
 
index a8547b9395229ca575b296c56de81ba20ae9b5e3..24504da42b9ece5c4d357da37d8c95278ab84565 100644 (file)
--- 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)'."
index d89e6f72747a3ecf0754b784c9abbf9196f6fe9f..3ea643b6e6f84fe24abc57ca953d55f20e787c62 100644 (file)
@@ -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;
         }
index d17a2f35f822bcbdfbf9baf0fdd3e29bb55de8e6..daa4b24a374718d82e7594cd95212d25577e7c71 100644 (file)
@@ -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))); \
+        })
index aadfba0707dfb1c029f3ee95b66f4b62229e0927..d7c722ac3da9510c59067b7a577e6e0dc86d4c80 100644 (file)
 ***/
 
 #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;
         }
 
index 25cc6962f9be52451cc1ca59309ea46e1978e114..996efde22b46ad3452f6879c31aab2db11fb9cc5 100644 (file)
@@ -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;
index bb09a515f88c8afd1c20163585a769d2d39d805c..961340608d30d31af533efcde5075db8d68d2674 100644 (file)
@@ -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),
index 263955d874652065ce8832597461110a6e77995b..3422a02d680324ea5ed5f33358fed13fc61bc4dd 100644 (file)
@@ -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;
index e16a84fbb87e88905acc4e54e2f10db960ef89e7..6baaffbd75e37d2608b4ed1e029539e313b11cfd 100644 (file)
@@ -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);
index ac2ac398926c69322abbb902be3019d79a8b4503..5eb3f13695cacfd1a34f937eed163c4e351d7771 100644 (file)
@@ -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;
 
index bd00c224f4a49af956353fc1bbd7d1c461200f20..e192cd475dc7a68d3e8aaf00faad80d0ee0802ba 100644 (file)
@@ -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);
 
index 17f84e6963068b392ab96e1e5a69122e29fc6cbf..4bccca75cb38246ec9de09c55818f0aa0a40f587 100644 (file)
@@ -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;
 
index 016df40b8c4abc9456808490fbdaa0082bca8b3a..d4b409ef531d56d16a43481cc447cba6ed908d13 100644 (file)
@@ -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);
 
index 8153515e894b964d9b3d4433847a5eb26f5f89fc..d8ab5781b06fb9e95ba348efc4e912e8053a89fa 100644 (file)
@@ -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) {
index f14972728e24bbe62365cff6060ba41e259936fd..08a927962d6310b4cc5b9626d4b924877b7dbace 100644 (file)
@@ -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;
index 41fc1993d5ef36f243a81373ae7e00ee3c16590e..01fdcfa9090258e590e9bd755bd6806de9611d19 100644 (file)
@@ -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++) {
index 6f56066da8226352281c347295338e701c55c73c..d32e1d923e0882ae96d573e8668cc78dd322ecd2 100644 (file)
@@ -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);
index d2a5867a6edefd2b22f25c70166e7e9897dbf1d1..956a82945c22cc832bdef6ed8da69951ebcfa735 100644 (file)
@@ -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)
index f0959b623761e291dab3dcd4a063aa14d70ba390..5e8a3e320049b946cad7e4df84eb92ffccd20ff1 100644 (file)
@@ -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;
 
index a445291a5e397f849282500cac86d6d494c88a13..0a1ce205c2f53363b56481aed9c8483a1d26687c 100644 (file)
@@ -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);
 
index e14d0ad980a905f9ddd9bfe0e666947e15c72680..8f82d2a838fc6bc9709902c213a1ab80d64b0221 100644 (file)
@@ -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");
 
index 59352bcb3fdabdd5c6a4a7b18902aed63a4212fa..4ad16ee41ca61f27bf3cb8cccb73e34462775128 100644 (file)
@@ -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);
 
index 5153fd0cce16d8748c072bf768450ef7378c0d27..0609b4b6947014db34025c21f6977e725fd5514f 100644 (file)
@@ -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)
index 04da94e7e3a9a695f5d94a4ff09df5a93e69630e..ed5f94e13688adf0144220b2aa10bc1b9dcaeb51 100644 (file)
@@ -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;
 }
index bd1c7f15ff4a7b986444ce375db13349deea6a40..4da9dbfd63f894e1c02cf37954c847721764d6a5 100644 (file)
@@ -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();
 
index 40e246bb06cd6d07f23ece54816931df0f870e94..98dc20134052f5357dc0e2a413a4c69502027aee 100644 (file)
@@ -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);
index e29175896942a5f55343d1311c94053009ec5995..17eab9772e25313fb8ed8f5a781b3a8aca0ad121 100644 (file)
 #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;
index 6805873f9e032dc6cbfa2bbd83c42e43e3b13690..4a4bd8d3b8ae8c82cb845eaf267205d73e433034 100644 (file)
@@ -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;
         }
 
index 2b755cea28bc390981454158f903106446c3fe8e..ee388b82db6a48514fbced19cff02039677e2f06 100644 (file)
@@ -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")) {
index 1157a0c72e4bfffa57badfe98000268f7b52134e..52b4db8875fb2de71dab07cd3153b8b7b5fb28f6 100644 (file)
@@ -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, ':');
index 7d0d4966d5db7d6821ab49479637996fa060efdc..639080bc66328da6e140f274bdda1fd2a76db749 100644 (file)
@@ -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;
 }
index 33ff3755bc6d5c66c26b561915305485f2d3a7f4..9e01f3afd45de6d5aba2e550060cd41ee41557a7 100644 (file)
@@ -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;
 }
index c7ded451a2f409eb0f579818bbd7ef71ba920ae1..ee879c7b896a6bb7bd7cc227e95e435e51edc1dc 100644 (file)
@@ -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");
 
index 962de22f43b1b745632c45f6ddd2ef9ee0e298b5..f68a09d7a8cc28ef3a52248ae960f27881e5d42b 100644 (file)
@@ -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 (symlink)
index 0000000..e9f93b1
--- /dev/null
@@ -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 (executable)
index 0000000..925dcad
--- /dev/null
@@ -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 "$@"