[daemon-fix] Fixed sending daemon match rules for kdbus broadcasts
[platform/upstream/dbus.git] / bus / stats.c
1 /* stats.c - statistics from the bus driver
2  *
3  * Copyright © 2011-2012 Nokia Corporation
4  * Copyright © 2012-2013 Collabora Ltd.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23
24 #include <config.h>
25 #include "stats.h"
26
27 #include <dbus/dbus-asv-util.h>
28 #include <dbus/dbus-internals.h>
29 #include <dbus/dbus-connection-internal.h>
30
31 #include "connection.h"
32 #include "services.h"
33 #include "utils.h"
34
35 #ifdef DBUS_ENABLE_STATS
36
37 dbus_bool_t
38 bus_stats_handle_get_stats (DBusConnection *connection,
39                             BusTransaction *transaction,
40                             DBusMessage    *message,
41                             DBusError      *error)
42 {
43   BusConnections *connections;
44   DBusMessage *reply = NULL;
45   DBusMessageIter iter, arr_iter;
46   static dbus_uint32_t stats_serial = 0;
47   dbus_uint32_t in_use, in_free_list, allocated;
48
49   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
50
51   connections = bus_transaction_get_connections (transaction);
52
53   reply = _dbus_asv_new_method_return (message, &iter, &arr_iter);
54
55   if (reply == NULL)
56     goto oom;
57
58   /* Globals */
59
60   _dbus_list_get_stats (&in_use, &in_free_list, &allocated);
61
62   if (!_dbus_asv_add_uint32 (&arr_iter, "Serial", stats_serial++) ||
63       !_dbus_asv_add_uint32 (&arr_iter, "ListMemPoolUsedBytes", in_use) ||
64       !_dbus_asv_add_uint32 (&arr_iter, "ListMemPoolCachedBytes", in_free_list) ||
65       !_dbus_asv_add_uint32 (&arr_iter, "ListMemPoolAllocatedBytes", allocated))
66     {
67       _dbus_asv_abandon (&iter, &arr_iter);
68       goto oom;
69     }
70
71   /* Connections */
72
73   if (!_dbus_asv_add_uint32 (&arr_iter, "ActiveConnections",
74         bus_connections_get_n_active (connections)) ||
75       !_dbus_asv_add_uint32 (&arr_iter, "IncompleteConnections",
76         bus_connections_get_n_incomplete (connections)) ||
77       !_dbus_asv_add_uint32 (&arr_iter, "MatchRules",
78         bus_connections_get_total_match_rules (connections)) ||
79       !_dbus_asv_add_uint32 (&arr_iter, "PeakMatchRules",
80         bus_connections_get_peak_match_rules (connections)) ||
81       !_dbus_asv_add_uint32 (&arr_iter, "PeakMatchRulesPerConnection",
82         bus_connections_get_peak_match_rules_per_conn (connections)) ||
83       !_dbus_asv_add_uint32 (&arr_iter, "BusNames",
84         bus_connections_get_total_bus_names (connections)) ||
85       !_dbus_asv_add_uint32 (&arr_iter, "PeakBusNames",
86         bus_connections_get_peak_bus_names (connections)) ||
87       !_dbus_asv_add_uint32 (&arr_iter, "PeakBusNamesPerConnection",
88         bus_connections_get_peak_bus_names_per_conn (connections)))
89     {
90       _dbus_asv_abandon (&iter, &arr_iter);
91       goto oom;
92     }
93
94   /* end */
95
96   if (!_dbus_asv_close (&iter, &arr_iter))
97     goto oom;
98
99   if (!bus_transaction_send_from_driver (transaction, connection, reply))
100     goto oom;
101
102   dbus_message_unref (reply);
103   return TRUE;
104
105 oom:
106   if (reply != NULL)
107     dbus_message_unref (reply);
108
109   BUS_SET_OOM (error);
110   return FALSE;
111 }
112
113 dbus_bool_t
114 bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
115                                        BusTransaction *transaction,
116                                        DBusMessage    *message,
117                                        DBusError      *error)
118 {
119   const char *bus_name = NULL;
120   DBusString bus_name_str;
121   DBusMessage *reply = NULL;
122   DBusMessageIter iter, arr_iter;
123   static dbus_uint32_t stats_serial = 0;
124   dbus_uint32_t in_messages, in_bytes, in_fds, in_peak_bytes, in_peak_fds;
125   dbus_uint32_t out_messages, out_bytes, out_fds, out_peak_bytes, out_peak_fds;
126   BusRegistry *registry;
127   BusService *service;
128   DBusConnection *stats_connection;
129
130   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
131
132   registry = bus_connection_get_registry (caller_connection);
133
134   if (! dbus_message_get_args (message, error,
135                                DBUS_TYPE_STRING, &bus_name,
136                                DBUS_TYPE_INVALID))
137       return FALSE;
138
139   _dbus_string_init_const (&bus_name_str, bus_name);
140   service = bus_registry_lookup (registry, &bus_name_str);
141
142   if (service == NULL)
143     {
144       dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
145                       "Bus name '%s' has no owner", bus_name);
146       return FALSE;
147     }
148
149   stats_connection = bus_service_get_primary_owners_connection (service);
150   _dbus_assert (stats_connection != NULL);
151
152   reply = _dbus_asv_new_method_return (message, &iter, &arr_iter);
153
154   if (reply == NULL)
155     goto oom;
156
157   /* Bus daemon per-connection stats */
158
159   if (!_dbus_asv_add_uint32 (&arr_iter, "Serial", stats_serial++) ||
160       !_dbus_asv_add_uint32 (&arr_iter, "MatchRules",
161         bus_connection_get_n_match_rules (stats_connection)) ||
162       !_dbus_asv_add_uint32 (&arr_iter, "PeakMatchRules",
163         bus_connection_get_peak_match_rules (stats_connection)) ||
164       !_dbus_asv_add_uint32 (&arr_iter, "BusNames",
165         bus_connection_get_n_services_owned (stats_connection)) ||
166       !_dbus_asv_add_uint32 (&arr_iter, "PeakBusNames",
167         bus_connection_get_peak_bus_names (stats_connection)) ||
168       !_dbus_asv_add_string (&arr_iter, "UniqueName",
169         bus_connection_get_name (stats_connection)))
170     {
171       _dbus_asv_abandon (&iter, &arr_iter);
172       goto oom;
173     }
174
175   /* DBusConnection per-connection stats */
176
177   _dbus_connection_get_stats (stats_connection,
178                               &in_messages, &in_bytes, &in_fds,
179                               &in_peak_bytes, &in_peak_fds,
180                               &out_messages, &out_bytes, &out_fds,
181                               &out_peak_bytes, &out_peak_fds);
182
183   if (!_dbus_asv_add_uint32 (&arr_iter, "IncomingMessages", in_messages) ||
184       !_dbus_asv_add_uint32 (&arr_iter, "IncomingBytes", in_bytes) ||
185       !_dbus_asv_add_uint32 (&arr_iter, "IncomingFDs", in_fds) ||
186       !_dbus_asv_add_uint32 (&arr_iter, "PeakIncomingBytes", in_peak_bytes) ||
187       !_dbus_asv_add_uint32 (&arr_iter, "PeakIncomingFDs", in_peak_fds) ||
188       !_dbus_asv_add_uint32 (&arr_iter, "OutgoingMessages", out_messages) ||
189       !_dbus_asv_add_uint32 (&arr_iter, "OutgoingBytes", out_bytes) ||
190       !_dbus_asv_add_uint32 (&arr_iter, "OutgoingFDs", out_fds) ||
191       !_dbus_asv_add_uint32 (&arr_iter, "PeakOutgoingBytes", out_peak_bytes) ||
192       !_dbus_asv_add_uint32 (&arr_iter, "PeakOutgoingFDs", out_peak_fds))
193     {
194       _dbus_asv_abandon (&iter, &arr_iter);
195       goto oom;
196     }
197
198   /* end */
199
200   if (!_dbus_asv_close (&iter, &arr_iter))
201     goto oom;
202
203   if (!bus_transaction_send_from_driver (transaction, caller_connection,
204                                          reply))
205     goto oom;
206
207   dbus_message_unref (reply);
208   return TRUE;
209
210 oom:
211   if (reply != NULL)
212     dbus_message_unref (reply);
213
214   BUS_SET_OOM (error);
215   return FALSE;
216 }
217
218 #endif