From: Ido Schimmel <[email protected]>
If we lost an event, there is nothing we can do in order to recover it.
Set above mentioned socket option on the netlink socket when monitoring
devlink events, so that `devlink monitor` will not abort in case we are
not draining the receive buffer fast enough.
The number of events we lost can be retrieved using:
# cat /proc/net/netlink | grep `pidof devlink` | awk '{ print $9 }'
Signed-off-by: Ido Schimmel <[email protected]>
Acked-by: Jiri Pirko <[email protected]>
---
devlink/devlink.c | 22 +++++++++++++++++++++-
devlink/mnlg.c | 12 ++++++++++++
devlink/mnlg.h | 2 ++
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index b9fce850ee00..817b74259ec3 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -140,6 +140,19 @@ static int _mnlg_socket_group_add(struct mnlg_socket *nlg,
return 0;
}
+static int _mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type,
+ void *buf, socklen_t len)
+{
+ int err;
+
+ err = mnlg_socket_setsockopt(nlg, type, buf, len);
+ if (err < 0) {
+ pr_err("Failed to call mnlg_socket_setsockopt\n");
+ return -errno;
+ }
+ return 0;
+}
+
struct ifname_map {
struct list_head list;
char *bus_name;
@@ -4020,7 +4033,7 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh,
void *data)
static int cmd_mon_show(struct dl *dl)
{
- int err;
+ int err, one = 1;
unsigned int index = 0;
const char *cur_obj;
@@ -4035,6 +4048,13 @@ static int cmd_mon_show(struct dl *dl)
return -EINVAL;
}
}
+ /* It is possible to lose some events if we are not draining the socket
+ * receive buffer fast enough. Keep processing events and do not abort.
+ */
+ err = _mnlg_socket_setsockopt(dl->nlg, NETLINK_NO_ENOBUFS, &one,
+ sizeof(one));
+ if (err)
+ return err;
err = _mnlg_socket_group_add(dl->nlg, DEVLINK_GENL_MCGRP_CONFIG_NAME);
if (err)
return err;
diff --git a/devlink/mnlg.c b/devlink/mnlg.c
index ee125df042f0..23e6e794b508 100644
--- a/devlink/mnlg.c
+++ b/devlink/mnlg.c
@@ -231,6 +231,18 @@ int mnlg_socket_group_add(struct mnlg_socket *nlg, const
char *group_name)
return 0;
}
+int mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type, void *buf,
+ socklen_t len)
+{
+ int err;
+
+ err = mnl_socket_setsockopt(nlg->nl, type, buf, len);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
static int get_family_id_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
diff --git a/devlink/mnlg.h b/devlink/mnlg.h
index 4d1babf3b4c2..49154215729e 100644
--- a/devlink/mnlg.h
+++ b/devlink/mnlg.h
@@ -21,6 +21,8 @@ struct nlmsghdr *mnlg_msg_prepare(struct mnlg_socket *nlg,
uint8_t cmd,
int mnlg_socket_send(struct mnlg_socket *nlg, const struct nlmsghdr *nlh);
int mnlg_socket_recv_run(struct mnlg_socket *nlg, mnl_cb_t data_cb, void
*data);
int mnlg_socket_group_add(struct mnlg_socket *nlg, const char *group_name);
+int mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type, void *buf,
+ socklen_t len);
struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version);
void mnlg_socket_close(struct mnlg_socket *nlg);
--
2.20.1