From owner-svn-src-all@freebsd.org Wed Mar 4 22:27:17 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id A3A76253DA3; Wed, 4 Mar 2020 22:27:17 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48XpQs1rPnz41w0; Wed, 4 Mar 2020 22:27:17 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 17C0E2520D; Wed, 4 Mar 2020 22:27:17 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 024MRGhm072614; Wed, 4 Mar 2020 22:27:16 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 024MRGsW072613; Wed, 4 Mar 2020 22:27:16 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <202003042227.024MRGsW072613@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Wed, 4 Mar 2020 22:27:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r358655 - head/sbin/mount_nfs X-SVN-Group: head X-SVN-Commit-Author: glebius X-SVN-Commit-Paths: head/sbin/mount_nfs X-SVN-Commit-Revision: 358655 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Mar 2020 22:27:17 -0000 Author: glebius Date: Wed Mar 4 22:27:16 2020 New Revision: 358655 URL: https://svnweb.freebsd.org/changeset/base/358655 Log: When a machine boots the NFS mounting script is executed after interfaces are configured, but for many interfaces (e.g. all Intel) ifconfig causes link renegotiation, so the first attempt to mount NFS always fails. After that mount_nfs sleeps for 30 seconds, while only a couple seconds are actually required for interface to get up. Instead of sleeping, do select(2) on routing socket and check if some interface became UP and in this case retry immediately. Reviewed by: rmacklem Differential Revision: https://reviews.freebsd.org/D23934 Modified: head/sbin/mount_nfs/mount_nfs.c Modified: head/sbin/mount_nfs/mount_nfs.c ============================================================================== --- head/sbin/mount_nfs/mount_nfs.c Wed Mar 4 22:23:24 2020 (r358654) +++ head/sbin/mount_nfs/mount_nfs.c Wed Mar 4 22:27:16 2020 (r358655) @@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include @@ -505,6 +507,59 @@ sec_num_to_name(int flavor) return (NULL); } +/* + * Wait for RTM_IFINFO message with interface that is IFF_UP and with + * link on, or until timeout expires. Returns seconds left. + */ +static time_t +rtm_ifinfo_sleep(time_t sec) +{ + char buf[2048]; + fd_set rfds; + struct timeval tv, start; + ssize_t nread; + int n, s; + + s = socket(PF_ROUTE, SOCK_RAW, 0); + if (s < 0) + err(EX_OSERR, "socket"); + (void)gettimeofday(&start, NULL); + + for (tv.tv_sec = sec, tv.tv_usec = 0; + tv.tv_sec > 0; + (void)gettimeofday(&tv, NULL), + tv.tv_sec = sec - (tv.tv_sec - start.tv_sec)) { + FD_ZERO(&rfds); + FD_SET(s, &rfds); + n = select(s + 1, &rfds, NULL, NULL, &tv); + if (n == 0) + continue; + if (n == -1) { + if (errno == EINTR) + continue; + else + err(EX_SOFTWARE, "select"); + } + nread = read(s, buf, 2048); + if (nread < 0) + err(EX_OSERR, "read"); + if ((size_t)nread >= sizeof(struct if_msghdr)) { + struct if_msghdr *ifm; + + ifm = (struct if_msghdr *)buf; + if (ifm->ifm_version == RTM_VERSION && + ifm->ifm_type == RTM_IFINFO && + (ifm->ifm_flags & IFF_UP) && + ifm->ifm_data.ifi_link_state != LINK_STATE_DOWN) + break; + } + } + + close(s); + + return (tv.tv_sec); +} + static int getnfsargs(char *spec, struct iovec **iov, int *iovlen) { @@ -638,7 +693,12 @@ getnfsargs(char *spec, struct iovec **iov, int *iovlen if (daemon(0, 0) != 0) err(1, "daemon"); } - sleep(60); + /* + * If rtm_ifinfo_sleep() returns non-zero, don't count + * that as a retry attempt. + */ + if (rtm_ifinfo_sleep(60) && retrycnt != 0) + retrycnt++; } freeaddrinfo(ai_nfs);