1 From a2b8220f4e82e454bbc0013ee83ea3220111d92e Mon Sep 17 00:00:00 2001
2 From: Jan Willem Janssen <j.w.janssen@lxtreme.nl>
3 Date: Mon, 25 Mar 2019 12:42:23 +0100
4 Subject: [PATCH 52/57] Improved UBus supported
6 - aligned the handling of UBus connections with the DBus code as it
7 makes it a bit easier to comprehend;
8 - added logging to the various UBus calls to aid debugging from an
9 enduser point of view, but be careful to not flood the logs;
10 - show the (lack of) support for UBus in the configuration string.
12 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
15 src/dnsmasq.c | 32 +++++++++++-
17 src/ubus.c | 138 ++++++++++++++++++++++++++++++++++++++++++--------
18 4 files changed, 157 insertions(+), 23 deletions(-)
22 @@ -362,6 +362,10 @@ static char *compile_opts =
35 @@ -420,6 +420,16 @@ int main (int argc, char **argv)
36 die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
39 + if (option_bool(OPT_UBUS))
42 + daemon->ubus = NULL;
46 + die(_("UBus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
49 if (daemon->port != 0)
52 @@ -811,6 +821,16 @@ int main (int argc, char **argv)
57 + if (option_bool(OPT_UBUS))
60 + my_syslog(LOG_INFO, _("UBus support enabled: connected to system bus"));
62 + my_syslog(LOG_INFO, _("UBus support enabled: bus connection pending"));
67 if (option_bool(OPT_DNSSEC_VALID))
69 @@ -999,7 +1019,7 @@ int main (int argc, char **argv)
72 if (option_bool(OPT_UBUS))
73 - set_ubus_listeners();
74 + set_ubus_listeners();
78 @@ -1134,7 +1154,15 @@ int main (int argc, char **argv)
81 if (option_bool(OPT_UBUS))
82 - check_ubus_listeners();
84 + /* if we didn't create a UBus connection, retry now. */
90 + check_ubus_listeners();
94 check_dns_listeners(now);
97 @@ -1130,6 +1130,11 @@ extern struct daemon {
99 struct watch *watches;
103 + /* void * here to avoid depending on ubus headers outside ubus.c */
108 struct tftp_transfer *tftp_trans, *tftp_done_trans;
109 @@ -1467,6 +1472,7 @@ void emit_dbus_signal(int action, struct
113 +void ubus_init(void);
114 void set_ubus_listeners(void);
115 void check_ubus_listeners(void);
116 void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface);
123 -static struct ubus_context *ubus = NULL;
124 static struct blob_buf b;
126 +static int error_logged = 0;
128 static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
129 struct ubus_request_data *req, const char *method,
130 struct blob_attr *msg);
131 -static struct ubus_method ubus_object_methods[] = {
132 - {.name = "metrics", .handler = ubus_handle_metrics},
134 +static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj);
136 +static const struct ubus_method ubus_object_methods[] = {
137 + UBUS_METHOD_NOARG("metrics", ubus_handle_metrics),
140 -static struct ubus_object_type ubus_object_type = UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
141 +static struct ubus_object_type ubus_object_type =
142 + UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
144 static struct ubus_object ubus_object = {
146 .type = &ubus_object_type,
147 .methods = ubus_object_methods,
148 .n_methods = ARRAY_SIZE(ubus_object_methods),
149 + .subscribe_cb = ubus_subscribe_cb,
152 +static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
156 + my_syslog(LOG_DEBUG, _("UBus subscription callback: %s subscriber(s)"), obj->has_subscribers ? "1" : "0");
157 + notify = obj->has_subscribers;
160 +static void ubus_destroy(struct ubus_context *ubus)
162 + // Forces re-initialization when we're reusing the same definitions later on.
163 + ubus_object.id = 0;
164 + ubus_object_type.id = 0;
167 + daemon->ubus = NULL;
170 +static void ubus_disconnect_cb(struct ubus_context *ubus)
174 + ret = ubus_reconnect(ubus, NULL);
177 + my_syslog(LOG_ERR, _("Cannot reconnect to UBus: %s"), ubus_strerror(ret));
179 + ubus_destroy(ubus);
185 + struct ubus_context *ubus = NULL;
188 + ubus = ubus_connect(NULL);
193 + my_syslog(LOG_ERR, _("Cannot initialize UBus: connection failed"));
197 + ubus_destroy(ubus);
201 + ret = ubus_add_object(ubus, &ubus_object);
206 + my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret));
212 + ubus->connection_lost = ubus_disconnect_cb;
213 + daemon->ubus = ubus;
216 + my_syslog(LOG_INFO, _("Connected to system UBus"));
219 void set_ubus_listeners()
221 + struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
227 + my_syslog(LOG_ERR, _("Cannot set UBus listeners: no connection"));
235 poll_listen(ubus->sock.fd, POLLIN);
236 poll_listen(ubus->sock.fd, POLLERR);
237 @@ -51,46 +134,57 @@ void set_ubus_listeners()
239 void check_ubus_listeners()
241 + struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
244 - ubus = ubus_connect(NULL);
247 - ubus_add_object(ubus, &ubus_object);
250 + my_syslog(LOG_ERR, _("Cannot poll UBus listeners: no connection"));
258 if (poll_check(ubus->sock.fd, POLLIN))
259 ubus_handle_event(ubus);
261 - if (poll_check(ubus->sock.fd, POLLHUP))
262 + if (poll_check(ubus->sock.fd, POLLHUP | POLLERR))
266 + my_syslog(LOG_INFO, _("Disconnecting from UBus"));
268 + ubus_destroy(ubus);
273 static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
274 struct ubus_request_data *req, const char *method,
275 struct blob_attr *msg)
278 - blob_buf_init(&b, 0);
280 - for(i=0; i < __METRIC_MAX; i++)
285 + blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
287 + for (i=0; i < __METRIC_MAX; i++)
288 blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
290 - ubus_send_reply(ctx, req, b.head);
293 + return ubus_send_reply(ctx, req, b.head);
296 void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
298 - if (!ubus || !ubus_object.has_subscribers)
299 + struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
302 + if (!ubus || !notify)
305 - blob_buf_init(&b, 0);
306 + blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
308 blobmsg_add_string(&b, "mac", mac);
310 @@ -100,7 +194,9 @@ void ubus_event_bcast(const char *type,
312 blobmsg_add_string(&b, "interface", interface);
314 - ubus_notify(ubus, &ubus_object, type, b.head, -1);
315 + ret = ubus_notify(ubus, &ubus_object, type, b.head, -1);
317 + my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));