summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2007-03-29 13:08:04 +1000
committerNeil Brown <neilb@suse.de>2007-03-29 13:08:04 +1000
commite8a29cc56f3bf9b550b0f4f4876f23ca379d3e14 (patch)
tree2be6f1fea7e972452f920776905aca52b8a89d3b
parent25001e18ff31933d1f40b510da969a8cee317310 (diff)
downloadnfs-utils-e8a29cc56f3bf9b550b0f4f4876f23ca379d3e14.tar.gz
nfs-utils-e8a29cc56f3bf9b550b0f4f4876f23ca379d3e14.tar.xz
nfs-utils-e8a29cc56f3bf9b550b0f4f4876f23ca379d3e14.zip
mount.nfs - require statd to be running to mount without nolocks
If we are mounting nfsv2 or nfsv3 and statd isn't running and we cannot start statd, then fail the mount request. Also use an RPC ping to check on statd. Signed-off-by: Neil Brown <neilb@suse.de>
-rw-r--r--utils/mount/mount.c53
-rw-r--r--utils/mount/nfsmount.c4
2 files changed, 48 insertions, 9 deletions
diff --git a/utils/mount/mount.c b/utils/mount/mount.c
index 4698d85..52b0d67 100644
--- a/utils/mount/mount.c
+++ b/utils/mount/mount.c
@@ -302,7 +302,33 @@ static void mount_error(char *node)
}
}
-static void start_statd()
+extern u_short getport(
+ struct sockaddr_in *saddr,
+ u_long prog,
+ u_long vers,
+ u_int prot);
+
+static int probe_statd()
+{
+ struct sockaddr_in addr;
+ u_short port;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ port = getport(&addr, 100024, 1, IPPROTO_UDP);
+
+ if (port == 0)
+ return 0;
+ addr.sin_port = htons(port);
+
+ if (clnt_ping(&addr, 100024, 1, IPPROTO_UDP, NULL) <= 0)
+ return 0;
+
+ return 1;
+}
+
+static int start_statd()
{
/* If /var/run/rpc.statd.pid exists and is non-empty,
* assume statd already running.
@@ -311,15 +337,19 @@ static void start_statd()
* else run that file (typically a shell script)
*/
struct stat stb;
- if (stat("/var/run/rpc.statd.pid", &stb) == 0 &&
- stb.st_size > 0)
- return;
+
+ if (probe_statd())
+ return 1;
#ifdef START_STATD
if (stat(START_STATD, &stb) ==0 &&
S_ISREG(stb.st_mode) &&
- (stb.st_mode & S_IXUSR))
+ (stb.st_mode & S_IXUSR)) {
system(START_STATD);
+ if (probe_statd())
+ return 1;
+ }
#endif
+ return 0;
}
int main(int argc, char *argv[])
@@ -485,8 +515,17 @@ int main(int argc, char *argv[])
mnt_err = nfsmount(spec, mount_point, &flags,
&extra_opts, &mount_opts,
0, &need_statd);
- if (!mnt_err && !fake && need_statd)
- start_statd();
+ if (!mnt_err && !fake && need_statd) {
+ if (!start_statd()) {
+ fprintf(stderr,
+ "%s: rpc.statd is not running but is "
+ "required for remote locking\n"
+ " Either use \"-o nolocks\" to keep "
+ "locks local, or start statd.\n",
+ progname);
+ exit(1);
+ }
+ }
}
if (mnt_err)
diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c
index 4049e66..776ef64 100644
--- a/utils/mount/nfsmount.c
+++ b/utils/mount/nfsmount.c
@@ -293,14 +293,14 @@ int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
* instead of reserve ports since reserve ports
* are not needed for pmap requests.
*/
-static u_short
+u_short
getport(
struct sockaddr_in *saddr,
u_long prog,
u_long vers,
u_int prot)
{
- u_short port;
+ u_short port = 0;
int socket;
CLIENT *clnt = NULL;
struct pmap parms;