From patchwork Fri Sep 8 10:14:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hangbin Liu X-Patchwork-Id: 811473 X-Patchwork-Delegate: shemminger@vyatta.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="cU0WvBPe"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xpY9m6Q1Jz9s3T for ; Fri, 8 Sep 2017 20:15:40 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754523AbdIHKPi (ORCPT ); Fri, 8 Sep 2017 06:15:38 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:36824 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752372AbdIHKPf (ORCPT ); Fri, 8 Sep 2017 06:15:35 -0400 Received: by mail-pg0-f68.google.com with SMTP id d8so1126807pgt.3 for ; Fri, 08 Sep 2017 03:15:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=c1u8smMcBM9njXyYbCAonO05NF+aExRWasBiElOZs8Q=; b=cU0WvBPez8E8hEDeI2vS/EzHhfipBL1HEWlc9uCTERiAp7KhR+SFIudUl/vIyYq1Ib 21HPkm8tYnH8UpcSn7D5EmtM5e77PXSdIXWUyrnMCLpRRJRkOHsbNTDgL29M3POVQfdF zuwrz1UGlDhFP8LMZvcapAdVMyn+8+5Q1T2zsiORT6y3djYcXvp4BFmnsoS6xX8UzV1X npNCWJuZZeDtskwR4aqBq2W7tjMZAqhning91Iri1NvxAWg2aLtBRmeMtX2OtAEQKsob swjj/TQaOh9tAriSRcloetjNDfWpbdB4igpc72S6i1LZuApijxAYKyYOT29nCP1MhBKh WpTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=c1u8smMcBM9njXyYbCAonO05NF+aExRWasBiElOZs8Q=; b=kuUhC7vm7gVAS574RIliLlhfn6YZgwfuNvxu+Crc2YWri4TaicTPu9RxQzaZ4NUlfi xiufeAcRltasufE78UXMJza90RyxjrPkhY7j4QqV6TkTlKxkY1Vsl7vg4qX8vuCsjxCL SeeLb6qwg8Lvf34ioV5VEVooFmEvHjPQwpcptVAdSWpd6N7PKt4JjAIv7ZVhBvP2iYRd Wfj5flXePqAj4A7jBWfyM+JhFfAbQmpxuqIiPmQvtBeAge8usya00TWj/lWiSGezPk/p 4rQoGBK2I7eWX1rlNvAbkrQX/i/57/VuPmYAFSXU76nGOW829iTVIeMWC2DFOBRmS4r3 Mlew== X-Gm-Message-State: AHPjjUhJMu/X1Rqo9355hPa+OtjFdooxNsjuIT+Hq8s5dmarMVKFHP6/ jl+42ehFUpOiWahw X-Google-Smtp-Source: ADKCNb75N8t8J4/sfrRhH/CoCXnK5NBf/EQhx9ZOFdZINTs+TrVPMyTv2hoLOnQ1CKfxpiwZ/Y00mg== X-Received: by 10.98.7.78 with SMTP id b75mr2563445pfd.19.1504865734431; Fri, 08 Sep 2017 03:15:34 -0700 (PDT) Received: from leo.usersys.redhat.com ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id i2sm3325822pfd.21.2017.09.08.03.15.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Sep 2017 03:15:34 -0700 (PDT) From: Hangbin Liu To: netdev@vger.kernel.org Cc: Stephen Hemminger , Michal Kubecek , Phil Sutter , Hangbin Liu Subject: [PATCH iproute2 1/2] lib/libnetlink: re malloc buff if size is not enough Date: Fri, 8 Sep 2017 18:14:56 +0800 Message-Id: <1504865697-27274-2-git-send-email-liuhangbin@gmail.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1504865697-27274-1-git-send-email-liuhangbin@gmail.com> References: <1504865697-27274-1-git-send-email-liuhangbin@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org With commit 72b365e8e0fd ("libnetlink: Double the dump buffer size") we doubled the buffer size to support more VFs. But the VFs number is increasing all the time. Some customers even use more than 200 VFs now. We could not double it everytime when the buffer is not enough. Let's just not hard code the buffer size and malloc the correct number when running. Introduce a new function rtnl_recvmsg() to get correct buffer. Signed-off-by: Hangbin Liu --- lib/libnetlink.c | 98 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index be7ac86..37cfb5a 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -402,6 +402,59 @@ static void rtnl_dump_error(const struct rtnl_handle *rth, } } +static int rtnl_recvmsg(int fd, struct msghdr *msg, char **buf) +{ + struct iovec *iov; + int len = -1, buf_len = 32768; + char *buffer = *buf; + + int flag = MSG_PEEK | MSG_TRUNC; + + if (buffer == NULL) +re_malloc: + buffer = malloc(buf_len); + + if (buffer == NULL) { + fprintf(stderr, "malloc error: no enough buffer\n"); + return -1; + } + + iov = msg->msg_iov; + iov->iov_base = buffer; + iov->iov_len = buf_len; + +re_recv: + len = recvmsg(fd, msg, flag); + + if (len < 0) { + if (errno == EINTR || errno == EAGAIN) + return 0; + fprintf(stderr, "netlink receive error %s (%d)\n", + strerror(errno), errno); + return len; + } + + if (len == 0) { + fprintf(stderr, "EOF on netlink\n"); + return -1; + } + + if (len > buf_len) { + free(buffer); + buf_len = len; + flag = 0; + goto re_malloc; + } + + if (flag != 0) { + flag = 0; + goto re_recv; + } + + *buf = buffer; + return len; +} + int rtnl_dump_filter_l(struct rtnl_handle *rth, const struct rtnl_dump_filter_arg *arg) { @@ -413,31 +466,20 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth, .msg_iov = &iov, .msg_iovlen = 1, }; - char buf[32768]; + static char *buf = NULL; int dump_intr = 0; - iov.iov_base = buf; while (1) { int status; const struct rtnl_dump_filter_arg *a; int found_done = 0; int msglen = 0; - iov.iov_len = sizeof(buf); - status = recvmsg(rth->fd, &msg, 0); - - if (status < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - fprintf(stderr, "netlink receive error %s (%d)\n", - strerror(errno), errno); - return -1; - } - - if (status == 0) { - fprintf(stderr, "EOF on netlink\n"); - return -1; - } + status = rtnl_recvmsg(rth->fd, &msg, &buf); + if (status < 0) + return status; + else if (status == 0) + continue; if (rth->dump_fp) fwrite(buf, 1, NLMSG_ALIGN(status), rth->dump_fp); @@ -543,7 +585,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, .msg_iov = &iov, .msg_iovlen = 1, }; - char buf[32768] = {}; + static char *buf = NULL; n->nlmsg_seq = seq = ++rtnl->seq; @@ -556,22 +598,14 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, return -1; } - iov.iov_base = buf; while (1) { - iov.iov_len = sizeof(buf); - status = recvmsg(rtnl->fd, &msg, 0); + status = rtnl_recvmsg(rtnl->fd, &msg, &buf); + + if (status < 0) + return status; + else if (status == 0) + continue; - if (status < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - fprintf(stderr, "netlink receive error %s (%d)\n", - strerror(errno), errno); - return -1; - } - if (status == 0) { - fprintf(stderr, "EOF on netlink\n"); - return -1; - } if (msg.msg_namelen != sizeof(nladdr)) { fprintf(stderr, "sender address length == %d\n",