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