From patchwork Fri Jun 30 13:21:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 9819597 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E97AF603F2 for ; Fri, 30 Jun 2017 13:21:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D883328668 for ; Fri, 30 Jun 2017 13:21:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CD3CE28671; Fri, 30 Jun 2017 13:21:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E0B9205AD for ; Fri, 30 Jun 2017 13:21:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751887AbdF3NVp (ORCPT ); Fri, 30 Jun 2017 09:21:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:9047 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751659AbdF3NVp (ORCPT ); Fri, 30 Jun 2017 09:21:45 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DC31783F44; Fri, 30 Jun 2017 13:21:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com DC31783F44 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=stefanha@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com DC31783F44 Received: from localhost (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2459186C3D; Fri, 30 Jun 2017 13:21:40 +0000 (UTC) From: Stefan Hajnoczi To: linux-nfs@vger.kernel.org Cc: Jeff Layton , Abbas Naderi , Steve Dickson , Stefan Hajnoczi Subject: [PATCH nfs-utils v2 06/12] mount: AF_VSOCK address parsing Date: Fri, 30 Jun 2017 14:21:14 +0100 Message-Id: <20170630132120.31578-7-stefanha@redhat.com> In-Reply-To: <20170630132120.31578-1-stefanha@redhat.com> References: <20170630132120.31578-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 30 Jun 2017 13:21:45 +0000 (UTC) Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP getaddrinfo(3) does not have AF_VSOCK support. Parse the CID in the hostname option and build a struct sockaddr_vm. There is one tricky thing here: struct addrinfo is normally allocated by getaddrinfo(3) and freed by freeaddrinfo(3). The memory allocation of the struct addrinfo and struct sockaddr are an implementation detail of libc. Therefore we must avoid freeaddrinfo(3) calls when the addrinfo details were filled out by us for AF_VSOCK instead of by getaddrinfo(3). Signed-off-by: Stefan Hajnoczi --- utils/mount/stropts.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index 99656dd..3161609 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -898,6 +898,42 @@ fall_back: return nfs_try_mount_v3v2(mi, FALSE); } +#ifdef AF_VSOCK +/* There are no guarantees on how getaddrinfo(3) allocates struct addrinfo so + * be sure to call free(3) on *address instead of freeaddrinfo(3). + */ +static int vsock_getaddrinfo(struct nfsmount_info *mi, + struct addrinfo **address) +{ + struct { + struct addrinfo ai; + struct sockaddr_vm svm; + } *vai; + long cid; + char *endptr; + + errno = 0; + cid = strtol(mi->hostname, &endptr, 10); + if (errno != 0 || *endptr != '\0' || + cid < 0 || cid > UINT_MAX) + return EAI_NONAME; + + vai = calloc(1, sizeof(*vai)); + if (!vai) + return EAI_MEMORY; + + vai->ai.ai_family = AF_VSOCK; + vai->ai.ai_socktype = SOCK_STREAM; + vai->ai.ai_addrlen = sizeof(vai->svm); + vai->ai.ai_addr = (struct sockaddr *)&vai->svm; + vai->svm.svm_family = AF_VSOCK; + vai->svm.svm_cid = cid; + + *address = &vai->ai; + return 0; +} +#endif /* AF_VSOCK */ + /* * This is a single pass through the fg/bg loop. * @@ -909,12 +945,21 @@ static int nfs_try_mount(struct nfsmount_info *mi) int result = 0; if (mi->address == NULL) { - struct addrinfo hint = {}; - int error; - struct addrinfo *address; + int error = 0; + struct addrinfo *address = NULL; + +#ifdef AF_VSOCK + if (mi->family == AF_VSOCK) + error = vsock_getaddrinfo(mi, &address); +#endif + + if (error == 0 && !address) { + struct addrinfo hint = {}; + + hint.ai_family = (int)mi->family; + error = getaddrinfo(mi->hostname, NULL, &hint, &address); + } - hint.ai_family = (int)mi->family; - error = getaddrinfo(mi->hostname, NULL, &hint, &address); if (error != 0) { if (error == EAI_AGAIN) errno = EAGAIN; @@ -1209,6 +1254,14 @@ int nfsmount_string(const char *spec, const char *node, const char *type, } else nfs_error(_("%s: internal option parsing error"), progname); +#ifdef AF_VSOCK + /* See vsock_getaddrinfo() for why we cannot use freeaddrinfo(3) */ + if (mi.address && mi.address->ai_family == AF_VSOCK) { + free(mi.address); + mi.address = NULL; + } +#endif + freeaddrinfo(mi.address); free(mi.hostname); return retval;