mount.nfs - require statd to be running to mount without nolocks
authorNeil Brown <neilb@suse.de>
Thu, 29 Mar 2007 03:08:04 +0000 (13:08 +1000)
committerNeil Brown <neilb@suse.de>
Thu, 29 Mar 2007 03:08:04 +0000 (13:08 +1000)
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>
utils/mount/mount.c
utils/mount/nfsmount.c

index 4698d85..52b0d67 100644 (file)
@@ -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)
index 4049e66..776ef64 100644 (file)
@@ -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;