[systemd-devel] [PATCH] [RFCv3] Add Listen* to dbus properties

Oleksii Shevchuk alxchk at gmail.com
Mon Apr 1 06:22:53 PDT 2013


> dctl status sockets.socket
sockets.socket - Test
  Loaded: loaded (/home/alxchk/.config/systemd/user/sockets.socket; static)
  Active: inactive (dead)
  Listen: Unix/TCP: /tmp/stream1
          Unix/UDP: /tmp/stream2
          Unix/PKT: /tmp/stream3
          Unix/TCP: @stream4
          Unix/UDP: @stream5
          Unix/PKT: @stream6
          IPv6/TCP: [::]:9999
          IPv6/UDP: [::]:9998
          IPv4/TCP: 127.0.0.2:9996
          IPv4/UDP: 127.0.0.2:9995
          IPv6/TCP: [::1]:9996
          IPv6/UDP: [::1]:9995
              FIFO: /tmp/fifo1
           Special: /dev/input/event9
---
 src/core/dbus-socket.c    | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 src/core/dbus-unit.h      |  1 +
 src/core/socket.c         | 33 ++++++++++++++++++++
 src/core/socket.h         |  3 ++
 src/systemctl/systemctl.c | 69 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 185 insertions(+)

diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index 2092a63..eb2a595 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -63,6 +63,7 @@
         "  <property name=\"NConnections\" type=\"u\" access=\"read\"/>\n" \
         "  <property name=\"MessageQueueMaxMessages\" type=\"x\" access=\"read\"/>\n" \
         "  <property name=\"MessageQueueMessageSize\" type=\"x\" access=\"read\"/>\n" \
+        "  <property name=\"Listen\" type=\"a(ss)\" access=\"read\"/>\n"    \
         "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
         "  <property name=\"SmackLabel\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"SmackLabelIPIn\" type=\"s\" access=\"read\"/>\n" \
@@ -98,6 +99,83 @@ const char bus_socket_invalidating_properties[] =
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_socket_result, socket_result, SocketResult);
 
+static int bus_socket_append_listen(DBusMessageIter *i, const char *property, void *data) {
+
+        Unit *u = data;
+        SocketPort *p;
+        Socket *s = SOCKET(u);
+        DBusMessageIter array, stru;
+
+        assert(data);
+        assert(property);
+        assert(s);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &array))
+                return log_oom();
+
+        LIST_FOREACH(port, p, s->ports) {
+                char *t;
+                const char * type = socket_address_type_to_string(p);
+
+                if (!dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT, NULL, &stru))
+                        return log_oom();
+
+                if (type)
+                        t = strjoin(socket_port_type_to_string(p), "/", type, NULL);
+                else
+                        t = strdup(socket_port_type_to_string(p));
+
+                if (!t)
+                        return log_oom();
+
+                if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &t)) {
+                        free(t);
+                        return log_oom();
+                }
+
+                free(t);
+
+                switch (p->type) {
+                        case SOCKET_SOCKET: {
+                                int r;
+                                _cleanup_free_ char *a = NULL;
+                                char *k;
+
+                                r = socket_address_print(&p->address, &a);
+                                if (r && !k)
+                                        k = strerror(-errno);
+                                else
+                                        k = a;
+
+                                if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &k))
+                                        return log_oom();
+                        }
+                                break;
+
+
+                        case SOCKET_SPECIAL:
+                        case SOCKET_MQUEUE:
+                        case SOCKET_FIFO:
+                                if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &p->path))
+                                        return log_oom();
+
+                                break;
+
+                        default:
+                                if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &t))
+                                        return -ENOMEM;
+                }
+
+                if (!dbus_message_iter_close_container(&array, &stru))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &array))
+                return -ENOMEM;
+
+        return 0;
+}
+
 static const BusProperty bus_socket_properties[] = {
         { "BindIPv6Only",   bus_socket_append_bind_ipv6_only,  "s", offsetof(Socket, bind_ipv6_only)  },
         { "Backlog",        bus_property_append_unsigned,      "u", offsetof(Socket, backlog)         },
@@ -123,6 +201,7 @@ static const BusProperty bus_socket_properties[] = {
         { "Broadcast",      bus_property_append_bool,          "b", offsetof(Socket, broadcast)       },
         { "PassCredentials",bus_property_append_bool,          "b", offsetof(Socket, pass_cred)       },
         { "PassSecurity",   bus_property_append_bool,          "b", offsetof(Socket, pass_sec)        },
+        { "Listen",         bus_socket_append_listen,      "a(ss)", 0,                                },
         { "Mark",           bus_property_append_int,           "i", offsetof(Socket, mark)            },
         { "MaxConnections", bus_property_append_unsigned,      "u", offsetof(Socket, max_connections) },
         { "NConnections",   bus_property_append_unsigned,      "u", offsetof(Socket, n_connections)   },
diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h
index 34980b0..e4c5666 100644
--- a/src/core/dbus-unit.h
+++ b/src/core/dbus-unit.h
@@ -88,6 +88,7 @@
         "  <property name=\"RequiresMountsFor\" type=\"as\" access=\"read\"/>\n" \
         "  <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"SourcePath\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"DropinPaths\" type=\"as\" access=\"read\"/>\n" \
         "  <property name=\"Documentation\" type=\"as\" access=\"read\"/>\n" \
         "  <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
diff --git a/src/core/socket.c b/src/core/socket.c
index 31f4bf4..a80f211 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1969,6 +1969,39 @@ static const char *socket_sub_state_to_string(Unit *u) {
         return socket_state_to_string(SOCKET(u)->state);
 }
 
+const char* socket_port_type_to_string(SocketPort *p) {
+
+        assert(p);
+
+        switch (p->type) {
+                case SOCKET_SOCKET:
+                        switch (socket_address_family(&p->address)) {
+                                case AF_NETLINK: return "Netlink";
+                                case AF_INET: return "IPv4";
+                                case AF_INET6: return "IPv6";
+                                case AF_UNIX: return "Unix";
+                                default: return "Invalid";
+                        }
+
+                case SOCKET_SPECIAL: return "Special";
+                case SOCKET_MQUEUE: return "MQueue";
+                case SOCKET_FIFO: return "FIFO";
+                default: return NULL;
+        }
+}
+
+const char* socket_address_type_to_string(SocketPort *p) {
+        assert(p);
+
+        switch (p->address.type) {
+                case SOCK_STREAM: return "TCP";
+                case SOCK_DGRAM: return "UDP";
+                case SOCK_SEQPACKET: return "PKT";
+                case SOCK_RAW: return "RAW";
+                default: return NULL;
+        }
+}
+
 static bool socket_check_gc(Unit *u) {
         Socket *s = SOCKET(u);
 
diff --git a/src/core/socket.h b/src/core/socket.h
index e0bae29..3139dd4 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -175,3 +175,6 @@ SocketExecCommand socket_exec_command_from_string(const char *s);
 
 const char* socket_result_to_string(SocketResult i);
 SocketResult socket_result_from_string(const char *s);
+
+const char* socket_port_type_to_string(SocketPort *p);
+const char* socket_address_type_to_string(SocketPort *p);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 328b91b..948e5aa 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2255,6 +2255,8 @@ typedef struct UnitStatusInfo {
         unsigned n_connections;
         bool accept;
 
+        char ** listen;
+
         /* Device */
         const char *sysfs_path;
 
@@ -2386,6 +2388,19 @@ static void print_status_info(UnitStatusInfo *i) {
                 }
         }
 
+        if (!strv_isempty(i->listen)) {
+                char **t;
+                bool first = true;
+
+                STRV_FOREACH(t, i->listen) {
+                        if (first) {
+                                printf("\t  Listen: %s\n", *t);
+                                first = false;
+                        } else
+                                printf("\t          %s\n", *t);
+                }
+        }
+
         if (i->accept)
                 printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
 
@@ -2736,6 +2751,37 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
 
                                 dbus_message_iter_next(&sub);
                         }
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Listen")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *type, *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0) {
+                                        char * buf, **l;
+                                        if (asprintf(&buf, "%8s: %s", type, path) < 0)
+                                                return -ENOMEM;
+
+                                        l = strv_append(i->listen, buf);
+                                        free(buf);
+
+                                        if (!l)
+                                                return -ENOMEM;
+
+                                        strv_free(i->listen);
+                                        i->listen = l;
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
                 } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING &&
                            streq(name, "Documentation")) {
 
@@ -2866,6 +2912,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
                         DBusMessageIter sub, sub2;
 
                         dbus_message_iter_recurse(iter, &sub);
+
                         while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
                                 const char *type, *path;
 
@@ -2880,6 +2927,28 @@ static int print_property(const char *name, DBusMessageIter *iter) {
 
                         return 0;
 
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Listen")) {
+                        DBusMessageIter sub, sub2;
+
+                        printf("Listen=");
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *type, *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0)
+                                        printf("%s (%s); ", path, type);
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        printf("\n");
+
+                        return 0;
+
                 } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Timers")) {
                         DBusMessageIter sub, sub2;
 
-- 
1.8.1.2



More information about the systemd-devel mailing list