rpms/util-linux/devel util-linux-2.13-nfsmount-retry.patch, NONE, 1.1 util-linux.spec, 1.113, 1.114

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Mon May 1 15:12:06 UTC 2006


Author: steved

Update of /cvs/dist/rpms/util-linux/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv12158

Modified Files:
	util-linux.spec 
Added Files:
	util-linux-2.13-nfsmount-retry.patch 
Log Message:
fix #183713 - foreground mounts are not retrying as advertised


util-linux-2.13-nfsmount-retry.patch:
 nfs.5       |    8 ++-
 nfs4mount.c |   37 +++++++++++----
 nfsmount.c  |  147 +++++++++++++++++++++++++++++++++++++++++-------------------
 3 files changed, 135 insertions(+), 57 deletions(-)

--- NEW FILE util-linux-2.13-nfsmount-retry.patch ---
--- util-linux-2.13-pre6/mount/nfsmount.c.retry	2006-05-01 10:55:38.000000000 -0400
+++ util-linux-2.13-pre6/mount/nfsmount.c	2006-05-01 11:01:05.000000000 -0400
@@ -125,9 +125,30 @@ void rpc_strerror()
 		if ((ptr = index(estr, ':')))
 			estr = ++ptr;
 
-		fprintf(stderr, "RPC Error: %d (%s )\n", cf_stat, estr);
 		if (cf_stat == RPC_SYSTEMERROR)
-			fprintf(stderr, "System Error: %d (%s)\n", cf_errno, strerror(cf_errno));
+			fprintf(stderr, "System Error: %s", strerror(cf_errno));
+		else
+			fprintf(stderr, "RPC Error:%s", estr);
+	}
+}
+void mount_errors(char *, int, int);
+void mount_errors(char *server, int will_retry, int bg)
+{
+	fprintf(stderr, "mount: mount to NFS server '%s' failed: ", server);
+	if (rpc_createerr.cf_stat == RPC_TIMEDOUT) {
+		if (will_retry)
+			fprintf(stderr, "timed out (retrying).\n");
+		else
+			fprintf(stderr, "timed out (giving up).\n");
+	} else {
+		rpc_strerror();
+		if (bg) {
+			if (will_retry)
+				fprintf(stderr, "(retrying).\n");
+			else
+				fprintf(stderr, "(giving up).\n");
+		} else
+			fprintf(stderr, ".\n");
 	}
 }
 
@@ -289,6 +310,8 @@ get_socket(struct sockaddr_in *saddr, u_
 
 	type = (p_prot == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM);
 	if ((so = socket (AF_INET, type, p_prot)) < 0) {
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = errno;
 		if (verbose) {
 			fprintf(stderr, 
 				"mount: Unable to create %s socket: errno %d (%s)\n",
@@ -302,6 +325,8 @@ get_socket(struct sockaddr_in *saddr, u_
 	laddr.sin_addr.s_addr = htonl(INADDR_ANY);
 	if (resvp) {
 		if (bindresvport(so, &laddr) < 0) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = errno;
 			if (verbose) {
 				fprintf(stderr, 
 					"mount: Unable to bindresvport %s socket: errno %d (%s)\n",
@@ -314,6 +339,8 @@ get_socket(struct sockaddr_in *saddr, u_
 	} else {
 		cc = bind(so, (struct sockaddr *)&laddr, namelen);
 		if (cc < 0) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = errno;
 			if (verbose) {
 				fprintf(stderr, 
 					"mount: Unable to bind to %s socket: errno %d (%s)\n",
@@ -327,6 +354,8 @@ get_socket(struct sockaddr_in *saddr, u_
 	if (type == SOCK_STREAM) {
 		cc = connect(so, (struct sockaddr *)saddr, namelen);
 		if (cc < 0) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = errno;
 			if (verbose) {
 				fprintf(stderr, 
 					"mount: Unable to connect to %s:%d, errno %d (%s)\n",
@@ -410,8 +439,16 @@ clnt_ping(struct sockaddr_in *saddr, con
 	int sock, stat;
 	static char clnt_res;
 
-	rpc_createerr.cf_stat = stat = 0;
+	rpc_createerr.cf_stat = stat = errno = 0;
 	sock = get_socket(saddr, prot, FALSE);
+	if (sock == RPC_ANYSOCK && errno == ETIMEDOUT) {
+		/*
+		 * TCP timeout. Bubble up the error to see 
+		 * how it should be handled.
+		 */
+		rpc_createerr.cf_stat = RPC_TIMEDOUT;
+		goto out_bad;
+	}
 
 	switch(prot) {
 	case IPPROTO_UDP:
@@ -475,10 +512,21 @@ probe_port(clnt_addr_t *server, 
 		if (p_port) {
 			if (!port || port == p_port) {
 				saddr->sin_port = htons(p_port);
+				if (verbose) {
+					fprintf(stderr, 
+						"mount: trying %s prog %ld vers %ld prot %s port %d\n", 
+						inet_ntoa(saddr->sin_addr), prog, *p_vers,
+						*p_prot == IPPROTO_UDP ? "udp" : "tcp", p_port);
+				}
 				if (clnt_ping(saddr, prog, *p_vers, *p_prot))
 					goto out_ok;
+				if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
+					goto out_bad;
 			}
 		}
+		if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) 
+			goto out_bad;
+
 		if (!prot) {
 			if (*++p_prot)
 				continue;
@@ -491,7 +539,9 @@ probe_port(clnt_addr_t *server, 
 		if (vers || !*++p_vers)
 			break;
 	}
+out_bad:
 	return 0;
+
  out_ok:
 	if (!vers)
 		pmap->pm_vers = *p_vers;
@@ -556,8 +606,13 @@ probe_bothports(clnt_addr_t *mnt_server,
 				return 1;
 			memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
 		}
-		if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED)
+		switch (rpc_createerr.cf_stat) {
+		case RPC_PROGVERSMISMATCH:
+		case RPC_PROGNOTREGISTERED:
 			break;
+		default:
+			goto out_bad;
+		}
 		memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
 	}
  out_bad:
@@ -569,11 +624,11 @@ probe_bothports(clnt_addr_t *mnt_server,
 }
 
 static CLIENT *
-mnt_openclnt(clnt_addr_t *mnt_server, int *msock, const int report_errs)
+mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
 {
 	struct sockaddr_in *mnt_saddr = &mnt_server->saddr;
 	struct pmap *mnt_pmap = &mnt_server->pmap;
-	CLIENT *clnt;
+	CLIENT *clnt = NULL;
 
 	/* contact the mount daemon via TCP */
 	mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
@@ -592,18 +647,12 @@ mnt_openclnt(clnt_addr_t *mnt_server, in
 				      msock,
 				      MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
 		break;
-	default:
-		goto out_bad;
 	}
-	if (!clnt)
-		goto report_err;
-	/* try to mount hostname:dirname */
-	clnt->cl_auth = authunix_create_default();
-	return clnt;
- report_err:
-	if (report_errs)
-		clnt_pcreateerror("mount");
- out_bad:
+	if (clnt) {
+		/* try to mount hostname:dirname */
+		clnt->cl_auth = authunix_create_default();
+		return clnt;
+	}
 	return NULL;
 }
 
@@ -635,33 +684,16 @@ nfs2_mount(CLIENT *clnt, mnt2arg_t *mnt2
 
 static int
 nfs_call_mount(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server,
-	       mntarg_t *mntarg, mntres_t *mntres, const int report_errs)
+	       mntarg_t *mntarg, mntres_t *mntres)
 {
 	CLIENT *clnt;
 	enum clnt_stat stat;
 	int msock;
 
-	if (!probe_bothports(mnt_server, nfs_server)) {
-		if (report_errs) {
-			fprintf(stderr, "mount to NFS server '%s' failed", 
-				*nfs_server->hostname);
-			if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) {
-				fprintf(stderr, ": server is down.\n");
-			} else  if (nfs_server->pmap.pm_prot) {
-				fprintf(stderr, ": possible invalid protocol.\n");
-			} else if (nfs_server->pmap.pm_port) {
-				fprintf(stderr, ": possible invalid port.\n");
-			} else {
-				fprintf(stderr, ".\n");
-			}
-			if (verbose) {
-				rpc_strerror();
-			}
-		}
+	if (!probe_bothports(mnt_server, nfs_server))
 		goto out_bad;
-	}
 
-	clnt = mnt_openclnt(mnt_server, &msock, report_errs);
+	clnt = mnt_openclnt(mnt_server, &msock);
 	if (!clnt)
 		goto out_bad;
 	/* make pointers in xdr_mountres3 NULL so
@@ -679,8 +711,10 @@ nfs_call_mount(clnt_addr_t *mnt_server, 
 	default:
 		goto out_bad;
 	}
-	if (stat != RPC_SUCCESS && report_errs)
-		clnt_perror(clnt, "mount");
+	if (stat != RPC_SUCCESS) {
+		clnt_geterr(clnt, &rpc_createerr.cf_error);
+		rpc_createerr.cf_stat = stat;
+	}
 	mnt_closeclnt(clnt, msock);
 	if (stat == RPC_SUCCESS)
 		return 1;
@@ -1070,7 +1104,10 @@ nfsmount(const char *spec, const char *n
 		goto fail;
 	if (!nfsmnt_check_compat(nfs_pmap, mnt_pmap))
 		goto fail;
-
+	
+	if (retry == 10000 && !bg)
+		retry = 2; /* reset for fg mounts */
+	
 
 #ifdef NFS_MOUNT_DEBUG
 	printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
@@ -1160,17 +1197,32 @@ nfsmount(const char *spec, const char *n
 				sleep(30);
 
 			stat = nfs_call_mount(&mnt_server, &nfs_server,
-					      &dirname, &mntres,
-					      !running_bg && prevt == 0);
+					      &dirname, &mntres);
 			if (stat)
 				break;
 			memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
 			memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
 			prevt = t;
 		}
-
-		if (!bg)
+		if (!bg) {
+			switch(rpc_createerr.cf_stat){
+			case RPC_TIMEDOUT:
+				break;
+			case RPC_SYSTEMERROR:
+				if (errno == ETIMEDOUT)
+					break;
+			default:
+				mount_errors(*nfs_server.hostname, 0, bg);
 		        goto fail;
+			}
+			t = time(NULL);
+			if (t >= timeout) {
+				mount_errors(*nfs_server.hostname, 0, bg);
+				goto fail;
+			}
+			mount_errors(*nfs_server.hostname, 1, bg);
+			continue;
+		}
 		if (!running_bg) {
 			prev_bg_host = xstrdup(hostname);
 			if (retry > 0)
@@ -1178,8 +1230,11 @@ nfsmount(const char *spec, const char *n
 			goto fail;
 		}
 		t = time(NULL);
-		if (t >= timeout)
+		if (t >= timeout) {
+			mount_errors(*nfs_server.hostname, 0, bg);
 			goto fail;
+		}
+		mount_errors(*nfs_server.hostname, 1, bg);
 	}
 
 	if (nfs_pmap->pm_vers == 2) {
@@ -1342,7 +1397,7 @@ nfs_call_umount(clnt_addr_t *mnt_server,
 	enum clnt_stat res = 0;
 	int msock;
 
-	clnt = mnt_openclnt(mnt_server, &msock, 1);
+	clnt = mnt_openclnt(mnt_server, &msock);
 	if (!clnt)
 		goto out_bad;
 	switch (mnt_server->pmap.pm_vers) {
--- util-linux-2.13-pre6/mount/nfs4mount.c.retry	2006-05-01 10:55:36.000000000 -0400
+++ util-linux-2.13-pre6/mount/nfs4mount.c	2006-05-01 10:59:49.000000000 -0400
@@ -77,7 +77,7 @@ char *GSSDLCK = DEFAULT_DIR "/rpcgssd";
 #endif
 
 extern int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int);
-extern void rpc_strerror();
+extern void mount_errors(char *, int);
 
 struct {
 	char    *flavour;
@@ -211,6 +211,7 @@ int nfs4mount(const char *spec, const ch
 	int nocto, noac;
 	int retry;
 	int retval;
+	time_t timeout, t;
 
 	retval = EX_FAIL;
 	if (strlen(spec) >= sizeof(hostdir)) {
@@ -413,12 +414,33 @@ int nfs4mount(const char *spec, const ch
 	printf("proto = %s\n", (data.proto == IPPROTO_TCP) ? "tcp" : "udp");
 #endif
 
+	timeout = time(NULL) + 60 * retry;
 	data.version = NFS4_MOUNT_VERSION;
-
-	clnt_ping(&server_addr, NFS_PROGRAM, 4, data.proto);
-	if (rpc_createerr.cf_stat) {
-		fprintf(stderr, "mount to NFS server '%s' failed.\n", data.hostname.data);
-		goto fail;
+	for (;;) {
+		if (verbose) {
+			fprintf(stderr, 
+				"mount: pinging: prog %d vers %d prot %s port %d\n", 
+				NFS_PROGRAM, 4, data.proto == IPPROTO_UDP ? "udp" : "tcp", 
+				ntohs(server_addr.sin_port));
+		}
+		clnt_ping(&server_addr, NFS_PROGRAM, 4, data.proto);
+		switch(rpc_createerr.cf_stat){
+		case RPC_TIMEDOUT:
+			break;
+		case RPC_SYSTEMERROR:
+			if (errno == ETIMEDOUT)
+				break;
+		default:
+			mount_errors(hostname, 0);
+			goto fail;
+		}
+		t = time(NULL);
+		if (t >= timeout) {
+			mount_errors(hostname, 0);
+			goto fail;
+		}
+		mount_errors(hostname, 1);
+		continue;
 	}
 
 	*mount_opts = (char *) &data;
@@ -426,8 +448,5 @@ int nfs4mount(const char *spec, const ch
 	return 0;
 
 fail:
-	if (verbose) {
-		rpc_strerror();
-	}
 	return retval;
 }
--- util-linux-2.13-pre6/mount/nfs.5.retry	2006-05-01 10:55:38.000000000 -0400
+++ util-linux-2.13-pre6/mount/nfs.5	2006-05-01 10:59:49.000000000 -0400
@@ -134,7 +134,9 @@ There is no default value.
 .I retry=n
 The number of minutes to retry an NFS mount operation
 in the foreground or background before giving up.
-The default value is 10000 minutes, which is roughly one week.
+The default value for forground mounts is 2 minutes.  
+The default value for background mounts is 10000 minutes, 
+which is roughly one week.
 .TP 1.5i
 .I namlen=n
 When an NFS server does not support version two of the
@@ -355,7 +357,9 @@ There is no default value.
 .I retry=n
 The number of minutes to retry an NFS mount operation
 in the foreground or background before giving up.
-The default value is 10000 minutes, which is roughly one week.
+The default value for forground mounts is 2 minutes.  
+The default value for background mounts is 10000 minutes, 
+which is roughly one week.
 .TP 1.5i
 .I port=n
 The numeric value of the port to connect to the NFS server on.


Index: util-linux.spec
===================================================================
RCS file: /cvs/dist/rpms/util-linux/devel/util-linux.spec,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -r1.113 -r1.114
--- util-linux.spec	1 May 2006 14:56:50 -0000	1.113
+++ util-linux.spec	1 May 2006 15:12:03 -0000	1.114
@@ -25,7 +25,7 @@
 Summary: A collection of basic system utilities.
 Name: util-linux
 Version: 2.13
-Release: 0.20
+Release: 0.21
 License: distributable
 Group: System Environment/Base
 
@@ -185,6 +185,8 @@
 Patch229: util-linux-2.13-nfsmount-mountd-udp.patch
 # 151549 - Added 'noacl' mount flag
 Patch230: util-linux-2.13-nfs-noacl.patch
+# 183713 - foreground nfs mount timeout options to get hard mount semantic
+Patch231: util-linux-2.13-nfsmount-retry.patch
 
 
 # When adding patches, please make sure that it is easy to find out what bug # the 
@@ -268,6 +270,7 @@
 %patch228 -p1
 %patch229 -p1
 %patch230 -p1
+%patch231 -p1
 
 %build
 unset LINGUAS || :
@@ -653,6 +656,7 @@
 
 %changelog
 * Mon May  1 2006 Steve Dickson <steved at redhat.com> 2.13-0.21
+- fix #183713 - foreground mounts are not retrying as advertised
 - fix #151549 - Added 'noacl' mount flag
 - fix #169042 - Changed nfsmount to try udp before using tcp when rpc-ing
                 the remote rpc.mountd (iff -o tcp is not specified).




More information about the fedora-cvs-commits mailing list