summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2016-01-16 12:06:32 -0500
committerSteve Dickson <steved@redhat.com>2016-01-16 12:30:13 -0500
commit37cd45cb913403b9f3b0c2aaa705e06cd70cc1d7 (patch)
treec1f916bf130dca27cb7afa6f3af3d44848434396
parent78bb645a42c216b37b8d930c7c849a3fa89babf8 (diff)
downloadnfs-utils-37cd45cb913403b9f3b0c2aaa705e06cd70cc1d7.tar.gz
nfs-utils-37cd45cb913403b9f3b0c2aaa705e06cd70cc1d7.tar.xz
nfs-utils-37cd45cb913403b9f3b0c2aaa705e06cd70cc1d7.zip
mount.nfs: trust the exit status of "start_statd".
If DNS service is particularly slow, nfs_probe_statd() can fail even though rpc.statd is actually running. This happens because rpc.statd is single threaded and could be waiting longer for DNS than nfs_probe_statd() will wait for it. This causes problems when mount.nfs uses nfs_probe_statd() to see if statd is running, as is needed for NFSv3. Currently in these circumstances there are two possible outcomes. 1/ if systemd is in use, it will be told to start rpc-statd, which is already running so no change. mount.nfs will try pinging rpc.statd a few more times and could eventually give up and fail the mount. While slow DNS may well result in slow service, it shouldn't cause a mount attempt to fail. 2/ if systemd is not in use, a new rpc.statd will be started. This can (and has) lead to a large number of rpc.statd processes running on the one machine. This patch addresses the first scenario. If START_STATD is run and exits with a success status, mount.nfs assumes statd is running and allows the mount to succeed. A separate patch will address the other scenario. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--utils/mount/network.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/utils/mount/network.c b/utils/mount/network.c
index 8a9bf14..7240ca7 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -794,6 +794,7 @@ int start_statd(void)
if (stat(START_STATD, &stb) == 0) {
if (S_ISREG(stb.st_mode) && (stb.st_mode & S_IXUSR)) {
int cnt = STATD_TIMEOUT * 10;
+ int status = 0;
const struct timespec ts = {
.tv_sec = 0,
.tv_nsec = 100000000,
@@ -808,7 +809,10 @@ int start_statd(void)
progname, strerror(errno));
break;
default: /* parent */
- waitpid(pid, NULL,0);
+ if (waitpid(pid, &status,0) == pid &&
+ status == 0)
+ /* assume it worked */
+ return 1;
break;
}
while (1) {