* amd/srvr_nfs.c (find_nfs_srvr): check to see if the IP address
authorErez Zadok <ezk@cs.sunysb.edu>
Sun, 10 Jul 2005 21:41:48 +0000 (21:41 +0000)
committerErez Zadok <ezk@cs.sunysb.edu>
Sun, 10 Jul 2005 21:41:48 +0000 (21:41 +0000)
of a named but down fserver changed (i.e., the previous IP address
is no longer responding).  If so, then reset the fserver to the
new IP address, and set the fserver's flags such that the function
will fall through to doing the usual NFS version/proto checks and
pinging.  (This should fix one case of bug #308.)

* conf/umount/umount_linux.c (umount_fs): warn if plain umount()
failed, before we try to ignore any errors or try optional
umount2(), possibly with forced/lazy unmount.
(umount_fs): dlog when unmount succeeded.

ChangeLog
amd/srvr_nfs.c
conf/umount/umount_linux.c

index 44e5f08b3fe021e020a82fbe3862d16d3aacc73e..db1535a128f478cdec662c6ff1ccdc2af382f71d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-07-10  Erez Zadok  <ezk@cs.sunysb.edu>
+
+       * amd/srvr_nfs.c (find_nfs_srvr): check to see if the IP address
+       of a named but down fserver changed (i.e., the previous IP address
+       is no longer responding).  If so, then reset the fserver to the
+       new IP address, and set the fserver's flags such that the function
+       will fall through to doing the usual NFS version/proto checks and
+       pinging.  (This should fix one case of bug #308.)
+
+       * conf/umount/umount_linux.c (umount_fs): warn if plain umount()
+       failed, before we try to ignore any errors or try optional
+       umount2(), possibly with forced/lazy unmount.
+       (umount_fs): dlog when unmount succeeded.
+
 2005-07-08  Erez Zadok  <ezk@cs.sunysb.edu>
 
        * conf/mount/mount_linux.c: add a couple more NFSv2 error codes
index 6821ea44e327c6c6177acab15bb986242f86c32a..49b3f7630e2df0c1eb845aaa151862dba8e60e7e 100644 (file)
@@ -37,7 +37,7 @@
  * SUCH DAMAGE.
  *
  *
- * $Id: srvr_nfs.c,v 1.39 2005/03/02 03:00:09 ezk Exp $
+ * $Id: srvr_nfs.c,v 1.40 2005/07/10 21:41:48 ezk Exp $
  *
  */
 
@@ -744,14 +744,38 @@ find_nfs_srvr(mntfs *mf)
   /*
    * This may not be the best way to do things, but it really doesn't make
    * sense to query a file server which is marked as 'down' for any
-   * version/proto combination.
+   * version/proto combination: so just return that 'downed' server if it
+   * matched.  We also check here if by any chance, the IP address of the
+   * server was changed; this happens when NFS servers are migrated, or a
+   * temporary server is made available for one that failed.
    */
   ITER(fs, fserver, &nfs_srvr_list) {
-    if (FSRV_ISDOWN(fs) &&
-       STREQ(host, fs->fs_host)) {
+    if (!FSRV_ISDOWN(fs) || !STREQ(host, fs->fs_host))
+      continue;
+    if (memcmp((voidp) &fs->fs_ip->sin_addr,
+              (voidp) &ip->sin_addr,
+              sizeof(ip->sin_addr)) != 0) {
+      /* IP address of downed server has changed! */
+      char *old_ipaddr = strdup(inet_ntoa(fs->fs_ip->sin_addr));
+      char *new_ipaddr = inet_ntoa(ip->sin_addr); /* ntoa uses static buf */
+      plog(XLOG_WARNING, "down fileserver %s changed ip: %s -> %s",
+          host, old_ipaddr, new_ipaddr);
+      XFREE(old_ipaddr);
+      /* Now fix the fserver to the new IP */
+      dlog("resetting fileserver %s to ip %s (flags: valid, not down)",
+          host, new_ipaddr);
+      memmove((voidp) &fs->fs_ip->sin_addr,
+             (voidp) &ip->sin_addr,
+             sizeof(ip->sin_addr));
+      fs->fs_flags |= FSF_VALID;
+      fs->fs_flags &= ~(FSF_DOWN|FSF_ERROR);
+      /* fall through to checking available NFS protocols, pinging, etc. */
+    } else {
+      /* server was down and is still down.  Not much we can do. */
       plog(XLOG_WARNING, "fileserver %s is already hung - not running NFS proto/version discovery", host);
       fs->fs_refc++;
-      XFREE(ip);
+      if (ip)
+       XFREE(ip);
       return fs;
     }
   }
index 280437d2349fbdd6a76b75be58ebad0c317c0a26..4e5e4cf35bc7a959f1e75e5fb2f33e18b24f326e 100644 (file)
@@ -37,7 +37,7 @@
  * SUCH DAMAGE.
  *
  *
- * $Id: umount_linux.c,v 1.4 2005/05/02 00:27:47 ottavio Exp $
+ * $Id: umount_linux.c,v 1.5 2005/07/10 21:41:49 ezk Exp $
  *
  */
 
@@ -85,7 +85,8 @@ umount_fs(char *mntdir, const char *mnttabname, int on_autofs)
 
     error = UNMOUNT_TRAP(mp_save->mnt);
     if (error < 0) {
-      switch (error = errno) {
+      plog(XLOG_WARNING, "unmount(%s) failed: %m", mp_save->mnt->mnt_dir);
+      switch ((error = errno)) {
       case EINVAL:
       case ENOTBLK:
        plog(XLOG_WARNING, "unmount: %s is not mounted", mp_save->mnt->mnt_dir);
@@ -121,6 +122,8 @@ umount_fs(char *mntdir, const char *mnttabname, int on_autofs)
        dlog("%s: unmount: %m", mp_save->mnt->mnt_dir);
        break;
       }
+    } else {
+      dlog("unmount(%s) succeeded", mp_save->mnt->mnt_dir);
     }
     dlog("Finished unmount(%s)", mp_save->mnt->mnt_dir);