|
|
9425f0 |
From c65cda183609116760c54f1c2ad458eef9f44d56 Mon Sep 17 00:00:00 2001
|
|
|
9425f0 |
From: "Chang S. Bae" <chang.seok.bae@intel.com>
|
|
|
9425f0 |
Date: Fri, 11 Feb 2022 12:27:00 -0800
|
|
|
9425f0 |
Subject: [PATCH 05/14] Implement Netlink helper functions to subscribe thermal
|
|
|
9425f0 |
events
|
|
|
9425f0 |
|
|
|
9425f0 |
Establish Netlink socket connection in a nonblocking mode and callback
|
|
|
9425f0 |
notification.
|
|
|
9425f0 |
|
|
|
9425f0 |
Tolerate a few times on failures from receiving events. In practice, such
|
|
|
9425f0 |
delivery failure is rare. But it may indicate more fundamental issues if
|
|
|
9425f0 |
it repeats. So disconnect it unless the failure is transient.
|
|
|
9425f0 |
|
|
|
9425f0 |
Event-specific handler will be implemented in the next patch.
|
|
|
9425f0 |
|
|
|
9425f0 |
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
|
|
|
9425f0 |
---
|
|
|
9425f0 |
thermal.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++++---
|
|
|
9425f0 |
1 file changed, 313 insertions(+), 14 deletions(-)
|
|
|
9425f0 |
|
|
|
9425f0 |
diff --git a/thermal.c b/thermal.c
|
|
|
9425f0 |
index 308bc48..16a6f39 100644
|
|
|
9425f0 |
--- a/thermal.c
|
|
|
9425f0 |
+++ b/thermal.c
|
|
|
9425f0 |
@@ -14,43 +14,342 @@
|
|
|
9425f0 |
|
|
|
9425f0 |
cpumask_t thermal_banned_cpus;
|
|
|
9425f0 |
|
|
|
9425f0 |
+#define INVALID_NL_FD -1
|
|
|
9425f0 |
+#define MAX_RECV_ERRS 2
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+#define THERMAL_GENL_FAMILY_NAME "thermal"
|
|
|
9425f0 |
+#define THERMAL_GENL_EVENT_GROUP_NAME "event"
|
|
|
9425f0 |
+#define NL_FAMILY_NAME "nlctrl"
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+struct family_data {
|
|
|
9425f0 |
+ const char *group;
|
|
|
9425f0 |
+ int id;
|
|
|
9425f0 |
+};
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+static struct nl_sock *sock;
|
|
|
9425f0 |
+static struct nl_cb *callback;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+/*
|
|
|
9425f0 |
+ * return value: TRUE with an error; otherwise, FALSE
|
|
|
9425f0 |
+ */
|
|
|
9425f0 |
static gboolean prepare_netlink(void)
|
|
|
9425f0 |
{
|
|
|
9425f0 |
- gboolean error = TRUE;
|
|
|
9425f0 |
+ int rc;
|
|
|
9425f0 |
|
|
|
9425f0 |
- log(TO_ALL, LOG_ERR, "thermal: not yet implement to alloc memory for netlink.\n");
|
|
|
9425f0 |
- return error;
|
|
|
9425f0 |
+ sock = nl_socket_alloc();
|
|
|
9425f0 |
+ if (!sock) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: socket allocation failed.\n");
|
|
|
9425f0 |
+ return TRUE;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = genl_connect(sock);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: socket bind failed.\n");
|
|
|
9425f0 |
+ return TRUE;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ callback = nl_cb_alloc(NL_CB_DEFAULT);
|
|
|
9425f0 |
+ if (!callback) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: callback allocation failed.\n");
|
|
|
9425f0 |
+ return TRUE;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ return FALSE;
|
|
|
9425f0 |
}
|
|
|
9425f0 |
|
|
|
9425f0 |
-#define NL_FAMILY_NAME "nlctrl"
|
|
|
9425f0 |
+static int handle_groupid(struct nl_msg *msg, void *arg)
|
|
|
9425f0 |
+{
|
|
|
9425f0 |
+ struct nlattr *attrhdr, *mcgrp, *cur_mcgrp;
|
|
|
9425f0 |
+ struct nlattr *attrs[CTRL_ATTR_MAX + 1];
|
|
|
9425f0 |
+ struct nla_policy *policy = NULL;
|
|
|
9425f0 |
+ struct genlmsghdr *gnlhdr = NULL;
|
|
|
9425f0 |
+ struct family_data *data = NULL;
|
|
|
9425f0 |
+ struct nlmsghdr *msghdr = NULL;
|
|
|
9425f0 |
+ int attrlen, rc, i;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ if (!arg) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: group id - failed to receive argument.\n");
|
|
|
9425f0 |
+ return NL_SKIP;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+ data = arg;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /* get actual netlink message header */
|
|
|
9425f0 |
+ msghdr = nlmsg_hdr(msg);
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /* get the start of the message payload */
|
|
|
9425f0 |
+ gnlhdr = nlmsg_data(msghdr);
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /* get the start of the message attribute section */
|
|
|
9425f0 |
+ attrhdr = genlmsg_attrdata(gnlhdr, 0);
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /* get the length of the message attribute section */
|
|
|
9425f0 |
+ attrlen = genlmsg_attrlen(gnlhdr, 0);
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /* create attribute index based on a stream of attributes */
|
|
|
9425f0 |
+ rc = nla_parse(
|
|
|
9425f0 |
+ attrs, /* index array to be filled */
|
|
|
9425f0 |
+ CTRL_ATTR_MAX, /* the maximum acceptable attribute type */
|
|
|
9425f0 |
+ attrhdr, /* head of attribute stream */
|
|
|
9425f0 |
+ attrlen, /* length of attribute stream */
|
|
|
9425f0 |
+ policy); /* validation policy */
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: group id - failed to create attributes.\n");
|
|
|
9425f0 |
+ return NL_SKIP;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /* start of the multi-cast group attribute */
|
|
|
9425f0 |
+ mcgrp = attrs[CTRL_ATTR_MCAST_GROUPS];
|
|
|
9425f0 |
+ if (!mcgrp) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: group id - no multi-cast group attributes.\n");
|
|
|
9425f0 |
+ return NL_SKIP;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /* iterate a stream of nested attributes to get the group id */
|
|
|
9425f0 |
+ nla_for_each_nested(cur_mcgrp, mcgrp, i) {
|
|
|
9425f0 |
+ struct nlattr *nested_attrs[CTRL_ATTR_MCAST_GRP_MAX + 1];
|
|
|
9425f0 |
+ struct nlattr *name, *id;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /* get start and length of payload section */
|
|
|
9425f0 |
+ attrhdr = nla_data(cur_mcgrp);
|
|
|
9425f0 |
+ attrlen = nla_len(cur_mcgrp);
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nla_parse(nested_attrs, CTRL_ATTR_MCAST_GRP_MAX, attrhdr, attrlen, policy);
|
|
|
9425f0 |
+ if (rc)
|
|
|
9425f0 |
+ continue;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ name = nested_attrs[CTRL_ATTR_MCAST_GRP_NAME];
|
|
|
9425f0 |
+ id = nested_attrs[CTRL_ATTR_MCAST_GRP_ID];
|
|
|
9425f0 |
+ if (!name || !id)
|
|
|
9425f0 |
+ continue;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ if (strncmp(nla_data(name), data->group, nla_len(name)) != 0)
|
|
|
9425f0 |
+ continue;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ data->id = nla_get_u32(id);
|
|
|
9425f0 |
+ log(TO_ALL, LOG_DEBUG, "thermal: received group id (%d).\n", data->id);
|
|
|
9425f0 |
+ break;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+ return NL_OK;
|
|
|
9425f0 |
+}
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+static int handle_error(struct sockaddr_nl *sk_addr __attribute__((unused)),
|
|
|
9425f0 |
+ struct nlmsgerr *err, void *arg)
|
|
|
9425f0 |
+{
|
|
|
9425f0 |
+ if (arg) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_INFO, "thermal: received a netlink error (%s).\n",
|
|
|
9425f0 |
+ nl_geterror(err->error));
|
|
|
9425f0 |
+ *((int *)arg) = err->error;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+ return NL_SKIP;
|
|
|
9425f0 |
+}
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+static int handle_end(struct nl_msg *msg __attribute__((unused)), void *arg)
|
|
|
9425f0 |
+{
|
|
|
9425f0 |
+ if (arg)
|
|
|
9425f0 |
+ *((int *)arg) = 0;
|
|
|
9425f0 |
+ return NL_SKIP;
|
|
|
9425f0 |
+}
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+struct msgheader {
|
|
|
9425f0 |
+ unsigned char cmd, version;
|
|
|
9425f0 |
+ unsigned int port, seq;
|
|
|
9425f0 |
+ int id, hdrlen, flags;
|
|
|
9425f0 |
+};
|
|
|
9425f0 |
|
|
|
9425f0 |
static gboolean establish_netlink(void)
|
|
|
9425f0 |
{
|
|
|
9425f0 |
+ struct msgheader msghdr = { CTRL_CMD_GETFAMILY, 0, 0, 0, 0, 0, 0 };
|
|
|
9425f0 |
+ struct family_data nldata = { THERMAL_GENL_EVENT_GROUP_NAME, -ENOENT };
|
|
|
9425f0 |
+ struct nl_cb *cloned_callback = NULL;
|
|
|
9425f0 |
+ int rc, group_id, callback_rc = 1;
|
|
|
9425f0 |
+ struct nl_msg *msg = NULL;
|
|
|
9425f0 |
gboolean error = TRUE;
|
|
|
9425f0 |
+ void *hdr;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ msg = nlmsg_alloc();
|
|
|
9425f0 |
+ if (!msg) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: message allocation failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ msghdr.id = genl_ctrl_resolve(sock, NL_FAMILY_NAME);
|
|
|
9425f0 |
+ if (msghdr.id < 0) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: message id enumeration failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ hdr = genlmsg_put(msg, msghdr.port, msghdr.seq, msghdr.id, msghdr.hdrlen,
|
|
|
9425f0 |
+ msghdr.flags, msghdr.cmd, msghdr.version);
|
|
|
9425f0 |
+ if (!hdr) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: netlink header setup failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, THERMAL_GENL_FAMILY_NAME);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: message setup failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ cloned_callback = nl_cb_clone(callback);
|
|
|
9425f0 |
+ if (!cloned_callback) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: callback handle duplication failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nl_send_auto(sock, msg);
|
|
|
9425f0 |
+ if (rc < 0) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: failed to send the first message.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
|
|
|
9425f0 |
- log(TO_ALL, LOG_ERR, "thermal: not yet implemented to establish netlink.\n");
|
|
|
9425f0 |
+ rc = nl_cb_err(cloned_callback, NL_CB_CUSTOM, handle_error, &callback_rc);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: error callback setup failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nl_cb_set(cloned_callback, NL_CB_ACK, NL_CB_CUSTOM, handle_end, &callback_rc);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: ack callback setup failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nl_cb_set(cloned_callback, NL_CB_FINISH, NL_CB_CUSTOM, handle_end, &callback_rc);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: finish callback setup failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nl_cb_set(cloned_callback, NL_CB_VALID, NL_CB_CUSTOM, handle_groupid, &nldata);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: group id callback setup failed.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ while (callback_rc != 0) {
|
|
|
9425f0 |
+ rc = nl_recvmsgs(sock, cloned_callback);
|
|
|
9425f0 |
+ if (rc < 0) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: failed to receive messages.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ group_id = nldata.id;
|
|
|
9425f0 |
+ if (group_id < 0) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: invalid group_id was received.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nl_socket_add_membership(sock, group_id);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: failed to join the netlink group.\n");
|
|
|
9425f0 |
+ goto err_out;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ error = FALSE;
|
|
|
9425f0 |
+err_out:
|
|
|
9425f0 |
+ nl_cb_put(cloned_callback);
|
|
|
9425f0 |
+ nlmsg_free(msg);
|
|
|
9425f0 |
return error;
|
|
|
9425f0 |
}
|
|
|
9425f0 |
|
|
|
9425f0 |
-static gboolean register_netlink_handler(nl_recvmsg_msg_cb_t handler __attribute__((unused)))
|
|
|
9425f0 |
+static int handle_thermal_event(struct nl_msg *msg __attribute__((unused)),
|
|
|
9425f0 |
+ void *arg __attribute__((unused)))
|
|
|
9425f0 |
{
|
|
|
9425f0 |
- gboolean error = TRUE;
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: not yet implemented to process thermal event.\n");
|
|
|
9425f0 |
+ return NL_SKIP;
|
|
|
9425f0 |
+}
|
|
|
9425f0 |
|
|
|
9425f0 |
- log(TO_ALL, LOG_ERR, "thermal: not yet implemented to register thermal handler.\n");
|
|
|
9425f0 |
- return error;
|
|
|
9425f0 |
+static int handler_for_debug(struct nl_msg *msg __attribute__((unused)),
|
|
|
9425f0 |
+ void *arg __attribute__((unused)))
|
|
|
9425f0 |
+{
|
|
|
9425f0 |
+ return NL_SKIP;
|
|
|
9425f0 |
+}
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+/*
|
|
|
9425f0 |
+ * return value: TRUE with an error; otherwise, FALSE
|
|
|
9425f0 |
+ */
|
|
|
9425f0 |
+static gboolean register_netlink_handler(void)
|
|
|
9425f0 |
+{
|
|
|
9425f0 |
+ int rc;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nl_cb_set(callback, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, handler_for_debug, NULL);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: debug handler registration failed.\n");
|
|
|
9425f0 |
+ return TRUE;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ rc = nl_cb_set(callback, NL_CB_VALID, NL_CB_CUSTOM, handle_thermal_event, NULL);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: thermal handler registration failed.\n");
|
|
|
9425f0 |
+ return TRUE;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ return FALSE;
|
|
|
9425f0 |
}
|
|
|
9425f0 |
|
|
|
9425f0 |
+/*
|
|
|
9425f0 |
+ * return value: TRUE to keep the source; FALSE to disconnect.
|
|
|
9425f0 |
+ */
|
|
|
9425f0 |
+gboolean receive_thermal_event(gint fd __attribute__((unused)),
|
|
|
9425f0 |
+ GIOCondition condition,
|
|
|
9425f0 |
+ gpointer user_data __attribute__((unused)))
|
|
|
9425f0 |
+{
|
|
|
9425f0 |
+ if (condition == G_IO_IN) {
|
|
|
9425f0 |
+ static unsigned int retry = 0;
|
|
|
9425f0 |
+ int err;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ err = nl_recvmsgs(sock, callback);
|
|
|
9425f0 |
+ if (err) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: failed to receive messages (rc=%d).\n", err);
|
|
|
9425f0 |
+ retry++;
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ /*
|
|
|
9425f0 |
+ * Pass a few failures then turn off if it keeps
|
|
|
9425f0 |
+ * failing down.
|
|
|
9425f0 |
+ */
|
|
|
9425f0 |
+ if (retry <= MAX_RECV_ERRS) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: but keep the connection.\n");
|
|
|
9425f0 |
+ } else {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: disconnect now with %u failures.\n",
|
|
|
9425f0 |
+ retry);
|
|
|
9425f0 |
+ return FALSE;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+ return TRUE;
|
|
|
9425f0 |
+}
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+/*
|
|
|
9425f0 |
+ * return value: TRUE with an error; otherwise, FALSE
|
|
|
9425f0 |
+ */
|
|
|
9425f0 |
static gboolean set_netlink_nonblocking(void)
|
|
|
9425f0 |
{
|
|
|
9425f0 |
- gboolean error = TRUE;
|
|
|
9425f0 |
+ int rc, fd;
|
|
|
9425f0 |
|
|
|
9425f0 |
- log(TO_ALL, LOG_ERR, "thermal: not yet implemented to set nonblocking socket.\n");
|
|
|
9425f0 |
- return error;
|
|
|
9425f0 |
+ rc = nl_socket_set_nonblocking(sock);
|
|
|
9425f0 |
+ if (rc) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: non-blocking mode setup failed.\n");
|
|
|
9425f0 |
+ return TRUE;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ fd = nl_socket_get_fd(sock);
|
|
|
9425f0 |
+ if (fd == INVALID_NL_FD) {
|
|
|
9425f0 |
+ log(TO_ALL, LOG_ERR, "thermal: file descriptor setup failed.\n");
|
|
|
9425f0 |
+ return TRUE;
|
|
|
9425f0 |
+ }
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ g_unix_fd_add(fd, G_IO_IN, receive_thermal_event, NULL);
|
|
|
9425f0 |
+
|
|
|
9425f0 |
+ return FALSE;
|
|
|
9425f0 |
}
|
|
|
9425f0 |
|
|
|
9425f0 |
void deinit_thermal(void)
|
|
|
9425f0 |
{
|
|
|
9425f0 |
- return;
|
|
|
9425f0 |
+ nl_cb_put(callback);
|
|
|
9425f0 |
+ nl_socket_free(sock);
|
|
|
9425f0 |
}
|
|
|
9425f0 |
|
|
|
9425f0 |
/*
|
|
|
9425f0 |
@@ -68,7 +367,7 @@ gboolean init_thermal(void)
|
|
|
9425f0 |
if (error)
|
|
|
9425f0 |
goto err_out;
|
|
|
9425f0 |
|
|
|
9425f0 |
- error = register_netlink_handler(NULL);
|
|
|
9425f0 |
+ error = register_netlink_handler();
|
|
|
9425f0 |
if (error)
|
|
|
9425f0 |
goto err_out;
|
|
|
9425f0 |
|
|
|
9425f0 |
--
|
|
|
9425f0 |
2.33.1
|
|
|
9425f0 |
|