[systemd-devel] [PATCH] [RFCv2] Add Listen* to dbus properties
Oleksii Shevchuk
alxchk at gmail.com
Mon Apr 1 05:28:15 PDT 2013
> dctl status mpd.socket
mpd.socket - MPD sockets
Loaded: loaded (/home/alxchk/.config/systemd/user/mpd.socket; enabled)
Active: inactive (dead)
Listen: TCP/Unix: /home/alxchk/.config/mpd/socket
TCP/IPv6: [::]:6600
---
src/core/dbus-socket.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++
src/core/dbus-unit.h | 1 +
src/core/socket.c | 33 +++++++++++++++++++++
src/core/socket.h | 3 ++
src/systemctl/systemctl.c | 69 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 180 insertions(+)
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index 2092a63..66f69cd 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,78 @@ 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;
+
+ if (!dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT, NULL, &stru))
+ return log_oom();
+
+ if (asprintf(&t, "%s/%s", socket_address_type_to_string(p),
+ socket_port_type_to_string(p)) < 0)
+ 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 +196,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..f71889b 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 "Invalid";
+ }
+}
+
+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 "Packets";
+ case SOCK_RAW: return "RAW";
+ default: return "Invalid";
+ }
+}
+
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..8a6add7 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, "%s: %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