From patchwork Wed Dec 13 14:49:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 847999 X-Patchwork-Delegate: davem@davemloft.net 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yxfjJ4v8Xz9s7m for ; Thu, 14 Dec 2017 01:49:24 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753370AbdLMOtV (ORCPT ); Wed, 13 Dec 2017 09:49:21 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41074 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753115AbdLMOtT (ORCPT ); Wed, 13 Dec 2017 09:49:19 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9149F8210D; Wed, 13 Dec 2017 14:49:18 +0000 (UTC) Received: from localhost (ovpn-116-41.ams2.redhat.com [10.36.116.41]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8283E18B56; Wed, 13 Dec 2017 14:49:17 +0000 (UTC) From: Stefan Hajnoczi To: netdev@vger.kernel.org Cc: Jorgen Hansen , Dexuan Cui , Stefan Hajnoczi Subject: [PATCH 2/5] VSOCK: extract connect/accept functions from vsock_diag_test.c Date: Wed, 13 Dec 2017 14:49:08 +0000 Message-Id: <20171213144911.6428-3-stefanha@redhat.com> In-Reply-To: <20171213144911.6428-1-stefanha@redhat.com> References: <20171213144911.6428-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 13 Dec 2017 14:49:18 +0000 (UTC) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Many test cases will need to connect to the server or accept incoming connections. This patch extracts these operations into utility functions that can be reused. Signed-off-by: Stefan Hajnoczi --- tools/testing/vsock/util.h | 6 ++ tools/testing/vsock/util.c | 108 ++++++++++++++++++++++++++++++++++ tools/testing/vsock/vsock_diag_test.c | 81 ++----------------------- 3 files changed, 119 insertions(+), 76 deletions(-) diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h index a51e17578ccf..3e6971f15caa 100644 --- a/tools/testing/vsock/util.h +++ b/tools/testing/vsock/util.h @@ -1,6 +1,9 @@ #ifndef UTIL_H #define UTIL_H +#include +#include "../../../include/uapi/linux/vm_sockets.h" + /* Tests can either run as the client or the server */ enum test_mode { TEST_MODE_UNSET, @@ -29,6 +32,9 @@ struct test_case { void init_signals(void); unsigned int parse_cid(const char *str); +int vsock_stream_connect(unsigned int cid, unsigned int port); +int vsock_stream_accept(unsigned int cid, unsigned int port, + struct sockaddr_vm *clientaddrp); void run_tests(const struct test_case *test_cases, const struct test_opts *opts); diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c index 2567abd90153..75a78f295b37 100644 --- a/tools/testing/vsock/util.c +++ b/tools/testing/vsock/util.c @@ -15,8 +15,10 @@ #include #include #include +#include #include "timeout.h" +#include "control.h" #include "util.h" /* Install signal handlers */ @@ -45,6 +47,112 @@ unsigned int parse_cid(const char *str) return n; } +/* Connect to and return the file descriptor. */ +int vsock_stream_connect(unsigned int cid, unsigned int port) +{ + union { + struct sockaddr sa; + struct sockaddr_vm svm; + } addr = { + .svm = { + .svm_family = AF_VSOCK, + .svm_port = port, + .svm_cid = cid, + }, + }; + int ret; + int fd; + + control_expectln("LISTENING"); + + fd = socket(AF_VSOCK, SOCK_STREAM, 0); + + timeout_begin(TIMEOUT); + do { + ret = connect(fd, &addr.sa, sizeof(addr.svm)); + timeout_check("connect"); + } while (ret < 0 && errno == EINTR); + timeout_end(); + + if (ret < 0) { + int old_errno = errno; + + close(fd); + fd = -1; + errno = old_errno; + } + return fd; +} + +/* Listen on and return the first incoming connection. The remote + * address is stored to clientaddrp. clientaddrp may be NULL. + */ +int vsock_stream_accept(unsigned int cid, unsigned int port, + struct sockaddr_vm *clientaddrp) +{ + union { + struct sockaddr sa; + struct sockaddr_vm svm; + } addr = { + .svm = { + .svm_family = AF_VSOCK, + .svm_port = port, + .svm_cid = cid, + }, + }; + union { + struct sockaddr sa; + struct sockaddr_vm svm; + } clientaddr; + socklen_t clientaddr_len = sizeof(clientaddr.svm); + int fd; + int client_fd; + int old_errno; + + fd = socket(AF_VSOCK, SOCK_STREAM, 0); + + if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) { + perror("bind"); + exit(EXIT_FAILURE); + } + + if (listen(fd, 1) < 0) { + perror("listen"); + exit(EXIT_FAILURE); + } + + control_writeln("LISTENING"); + + timeout_begin(TIMEOUT); + do { + client_fd = accept(fd, &clientaddr.sa, &clientaddr_len); + timeout_check("accept"); + } while (client_fd < 0 && errno == EINTR); + timeout_end(); + + old_errno = errno; + close(fd); + errno = old_errno; + + if (client_fd < 0) + return client_fd; + + if (clientaddr_len != sizeof(clientaddr.svm)) { + fprintf(stderr, "unexpected addrlen from accept(2), %zu\n", + (size_t)clientaddr_len); + exit(EXIT_FAILURE); + } + if (clientaddr.sa.sa_family != AF_VSOCK) { + fprintf(stderr, "expected AF_VSOCK from accept(2), got %d\n", + clientaddr.sa.sa_family); + exit(EXIT_FAILURE); + } + + if (clientaddrp) + *clientaddrp = clientaddr.svm; + return client_fd; +} + /* Run test cases. The program terminates if a failure occurs. */ void run_tests(const struct test_case *test_cases, const struct test_opts *opts) diff --git a/tools/testing/vsock/vsock_diag_test.c b/tools/testing/vsock/vsock_diag_test.c index f1ace5d96e00..654bbe2fc211 100644 --- a/tools/testing/vsock/vsock_diag_test.c +++ b/tools/testing/vsock/vsock_diag_test.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -26,7 +25,6 @@ #include #include -#include "../../../include/uapi/linux/vm_sockets.h" #include "../../../include/uapi/linux/vm_sockets_diag.h" #include "timeout.h" @@ -383,33 +381,12 @@ static void test_listen_socket_server(const struct test_opts *opts) static void test_connect_client(const struct test_opts *opts) { - union { - struct sockaddr sa; - struct sockaddr_vm svm; - } addr = { - .svm = { - .svm_family = AF_VSOCK, - .svm_port = 1234, - .svm_cid = opts->peer_cid, - }, - }; int fd; - int ret; LIST_HEAD(sockets); struct vsock_stat *st; - control_expectln("LISTENING"); - - fd = socket(AF_VSOCK, SOCK_STREAM, 0); - - timeout_begin(TIMEOUT); - do { - ret = connect(fd, &addr.sa, sizeof(addr.svm)); - timeout_check("connect"); - } while (ret < 0 && errno == EINTR); - timeout_end(); - - if (ret < 0) { + fd = vsock_stream_connect(opts->peer_cid, 1234); + if (fd < 0) { perror("connect"); exit(EXIT_FAILURE); } @@ -429,66 +406,19 @@ static void test_connect_client(const struct test_opts *opts) static void test_connect_server(const struct test_opts *opts) { - union { - struct sockaddr sa; - struct sockaddr_vm svm; - } addr = { - .svm = { - .svm_family = AF_VSOCK, - .svm_port = 1234, - .svm_cid = VMADDR_CID_ANY, - }, - }; - union { - struct sockaddr sa; - struct sockaddr_vm svm; - } clientaddr; - socklen_t clientaddr_len = sizeof(clientaddr.svm); - LIST_HEAD(sockets); struct vsock_stat *st; - int fd; + LIST_HEAD(sockets); int client_fd; - fd = socket(AF_VSOCK, SOCK_STREAM, 0); - - if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) { - perror("bind"); - exit(EXIT_FAILURE); - } - - if (listen(fd, 1) < 0) { - perror("listen"); - exit(EXIT_FAILURE); - } - - control_writeln("LISTENING"); - - timeout_begin(TIMEOUT); - do { - client_fd = accept(fd, &clientaddr.sa, &clientaddr_len); - timeout_check("accept"); - } while (client_fd < 0 && errno == EINTR); - timeout_end(); - + client_fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL); if (client_fd < 0) { perror("accept"); exit(EXIT_FAILURE); } - if (clientaddr.sa.sa_family != AF_VSOCK) { - fprintf(stderr, "expected AF_VSOCK from accept(2), got %d\n", - clientaddr.sa.sa_family); - exit(EXIT_FAILURE); - } - if (clientaddr.svm.svm_cid != opts->peer_cid) { - fprintf(stderr, "expected peer CID %u from accept(2), got %u\n", - opts->peer_cid, clientaddr.svm.svm_cid); - exit(EXIT_FAILURE); - } read_vsock_stat(&sockets); - check_num_sockets(&sockets, 2); - find_vsock_stat(&sockets, fd); + check_num_sockets(&sockets, 1); st = find_vsock_stat(&sockets, client_fd); check_socket_state(st, TCP_ESTABLISHED); @@ -496,7 +426,6 @@ static void test_connect_server(const struct test_opts *opts) control_expectln("DONE"); close(client_fd); - close(fd); free_sock_stat(&sockets); }