From patchwork Fri Apr 8 22:05:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 8786571 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B91AEC0553 for ; Fri, 8 Apr 2016 22:14:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 24B5E202E9 for ; Fri, 8 Apr 2016 22:14:50 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 567842021A for ; Fri, 8 Apr 2016 22:14:49 +0000 (UTC) Received: from localhost ([::1]:58593 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoefw-0002Te-HM for patchwork-qemu-devel@patchwork.kernel.org; Fri, 08 Apr 2016 18:14:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56237) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoeXn-0001sI-TG for qemu-devel@nongnu.org; Fri, 08 Apr 2016 18:06:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aoeXm-0007Uq-VX for qemu-devel@nongnu.org; Fri, 08 Apr 2016 18:06:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45528) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoeXm-0007Ub-Qe for qemu-devel@nongnu.org; Fri, 08 Apr 2016 18:06:22 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8515B6E77B; Fri, 8 Apr 2016 22:06:22 +0000 (UTC) Received: from red.redhat.com (ovpn-113-199.phx2.redhat.com [10.3.113.199]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u38M67UH029137; Fri, 8 Apr 2016 18:06:22 -0400 From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 8 Apr 2016 16:05:51 -0600 Message-Id: <1460153158-21612-12-git-send-email-eblake@redhat.com> In-Reply-To: <1460153158-21612-1-git-send-email-eblake@redhat.com> References: <1460153158-21612-1-git-send-email-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 11/18] nbd: Let client skip portions of server reply X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , alex@alex.org.uk Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The server has a nice helper function nbd_negotiate_drop_sync() which lets it easily ignore fluff from the client (such as the payload to an unknown option request). We can't quite make it common, since it depends on nbd_negotiate_read() which handles coroutine magic, but we can copy the idea into the client where we have places where we want to ignore data (such as the description tacked on the end of NBD_REP_SERVER). Signed-off-by: Eric Blake Reviewed-by: Alex Bligh --- nbd/client.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index 07b8d2e..b2dfc11 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -75,6 +75,32 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); */ +/* Discard length bytes from channel. Return -errno on failure, or + * the amount of bytes consumed. */ +static ssize_t drop_sync(QIOChannel *ioc, size_t size) +{ + ssize_t ret, dropped = size; + char small[1024]; + char *buffer; + + buffer = sizeof(small) < size ? small : g_malloc(MIN(65536, size)); + while (size > 0) { + ret = read_sync(ioc, buffer, MIN(65536, size)); + if (ret < 0) { + goto cleanup; + } + assert(ret <= size); + size -= ret; + } + ret = dropped; + + cleanup: + if (buffer != small) { + g_free(buffer); + } + return ret; +} + /* Send an option request. Return 0 if successful, -1 with errp set if * it is impossible to continue. */ static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt, @@ -255,18 +281,11 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) } (*name)[namelen] = '\0'; len -= namelen; - if (len) { - char *buf = g_malloc(len + 1); - if (read_sync(ioc, buf, len) != len) { - error_setg(errp, "failed to read export description"); - g_free(*name); - g_free(buf); - *name = NULL; - return -1; - } - buf[len] = '\0'; - TRACE("Ignoring export description: %s", buf); - g_free(buf); + if (drop_sync(ioc, len) != len) { + error_setg(errp, "failed to read export description"); + g_free(*name); + *name = NULL; + return -1; } } else { error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x", @@ -539,7 +558,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags, goto fail; } - if (read_sync(ioc, &buf, 124) != 124) { + if (drop_sync(ioc, 124) != 124) { error_setg(errp, "Failed to read reserved block"); goto fail; }