From: Kamil Wiatrowski Date: Thu, 28 May 2020 13:58:19 +0000 (+0100) Subject: netlink plugin: increase socket buffer size X-Git-Tag: collectd-5.12.0~15^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14a73b1a79759fb7911547661cc9fb0764b2d654;p=thirdparty%2Fcollectd.git netlink plugin: increase socket buffer size Set socket buffer size so it is big enough to hold all nested VFs data. Check sriov_totalvfs to estimate buffer size. Signed-off-by: Kamil Wiatrowski --- diff --git a/src/netlink.c b/src/netlink.c index abd31eb1a..5e7ccd140 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -47,8 +47,11 @@ #include #endif +#include #include +#define NETLINK_VF_DEFAULT_BUF_SIZE_KB 16 + struct ir_link_stats_storage_s { uint64_t rx_packets; @@ -135,6 +138,7 @@ static char **iflist; static size_t iflist_len; static bool collect_vf_stats = false; +static size_t nl_socket_buffer_size = NETLINK_VF_DEFAULT_BUF_SIZE_KB * 1024; static const char *config_keys[] = { "Interface", "VerboseInterface", "QDisc", "Class", @@ -987,6 +991,62 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { return MNL_CB_OK; } /* int qos_filter_cb */ +static size_t ir_get_buffer_size() { + if (collect_vf_stats == false) { + return MNL_SOCKET_BUFFER_SIZE; + } + + glob_t g; + unsigned int max_num = 0; + if (glob("/sys/class/net/*/device/sriov_totalvfs", GLOB_NOSORT, NULL, &g)) { + ERROR("netlink plugin: ir_get_buffer_size: glob failed"); + /* using default value */ + return NETLINK_VF_DEFAULT_BUF_SIZE_KB * 1024; + } + + for (size_t i = 0; i < g.gl_pathc; i++) { + char buf[16]; + ssize_t len; + int num = 0; + int fd = open(g.gl_pathv[i], O_RDONLY); + if (fd < 0) { + WARNING("netlink plugin: ir_get_buffer_size: failed to open `%s.`", + g.gl_pathv[i]); + continue; + } + + if ((len = read(fd, buf, sizeof(buf) - 1)) <= 0) { + WARNING("netlink plugin: ir_get_buffer_size: failed to read `%s.`", + g.gl_pathv[i]); + close(fd); + continue; + } + buf[len] = '\0'; + + if (sscanf(buf, "%d", &num) != 1) { + WARNING("netlink plugin: ir_get_buffer_size: failed to read number from " + "`%s.`", + buf); + close(fd); + continue; + } + + if (num > max_num) + max_num = num; + + close(fd); + } + globfree(&g); + DEBUG("netlink plugin: ir_get_buffer_size: max sriov_totalvfs = %u", max_num); + + unsigned int mp = NETLINK_VF_DEFAULT_BUF_SIZE_KB; + /* allign to power of two, buffer size should be at least totalvfs/2 kb */ + while (mp < max_num / 2) + mp *= 2; + + return mp * 1024; +} + static int ir_config(const char *key, const char *value) { char *new_val; char *fields[8]; @@ -1072,11 +1132,14 @@ static int ir_init(void) { return -1; } + nl_socket_buffer_size = ir_get_buffer_size(); + INFO("netlink plugin: ir_init: buffer size = %zu", nl_socket_buffer_size); + return 0; } /* int ir_init */ static int ir_read(void) { - char buf[MNL_SOCKET_BUFFER_SIZE]; + char buf[nl_socket_buffer_size]; struct nlmsghdr *nlh; struct rtgenmsg *rt; int ret;