<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">Index: openafs/src/LICENSE
diff -c openafs/src/LICENSE:1.2 openafs/src/LICENSE:1.3
*** openafs/src/LICENSE:1.2	Fri Apr 15 15:02:08 2005
--- openafs/src/LICENSE	Mon Feb 27 15:17:24 2006
***************
*** 690,692 ****
--- 690,694 ----
   * 2550 Garcia Avenue
   * Mountain View, California  94043
   */
+ 
+ src/afs/LINUX/osi_flush.s included code under IBM Public License with permission of the author, Paul MacKerras.
Index: openafs/src/WINNT/afsd/NTMakefile
diff -c openafs/src/WINNT/afsd/NTMakefile:1.45 openafs/src/WINNT/afsd/NTMakefile:1.46
*** openafs/src/WINNT/afsd/NTMakefile:1.45	Thu Feb 16 17:03:47 2006
--- openafs/src/WINNT/afsd/NTMakefile	Thu Apr 20 13:18:42 2006
***************
*** 101,106 ****
--- 101,107 ----
  	$(OUT)\cm_cell.obj \
  	$(OUT)\cm_server.obj \
  	$(OUT)\cm_volume.obj \
+ 	$(OUT)\cm_config.obj \
  	$(OUT)\cm_conn.obj \
  	$(OUT)\cm_user.obj \
  	$(OUT)\cm_buf.obj \
Index: openafs/src/WINNT/afsd/afsd_init.c
diff -c openafs/src/WINNT/afsd/afsd_init.c:1.75 openafs/src/WINNT/afsd/afsd_init.c:1.79
*** openafs/src/WINNT/afsd/afsd_init.c:1.75	Thu Feb 16 17:01:45 2006
--- openafs/src/WINNT/afsd/afsd_init.c	Fri Apr 21 11:03:34 2006
***************
*** 38,43 ****
--- 38,44 ----
  extern int RXSTATS_ExecuteRequest(struct rx_call *z_call);
  
  extern afs_int32 cryptall;
+ extern int cm_enableServerLocks;
  
  osi_log_t *afsd_logp;
  
***************
*** 66,71 ****
--- 67,73 ----
  
  char cm_HostName[200];
  long cm_HostAddr;
+ unsigned short cm_callbackport = CM_DEFAULT_CALLBACKPORT;
  
  char cm_NetbiosName[MAX_NB_NAME_LENGTH] = "";
  
***************
*** 852,859 ****
      if (code != ERROR_SUCCESS || !buf[0]) {
  #if defined(_IA64_)
          StringCbCopyA(buf, sizeof(buf), "ia64_win64");
! #elif defined(_AMD64)
!         StringCbCopyA(buf, sizeof(buf), "amd64_win64");
  #else /* assume x86 32-bit */
          StringCbCopyA(buf, sizeof(buf), "x86_win32 i386_w2k i386_nt40");
  #endif
--- 854,861 ----
      if (code != ERROR_SUCCESS || !buf[0]) {
  #if defined(_IA64_)
          StringCbCopyA(buf, sizeof(buf), "ia64_win64");
! #elif defined(_AMD64_)
!         StringCbCopyA(buf, sizeof(buf), "amd64_win64 x86_win32 i386_w2k");
  #else /* assume x86 32-bit */
          StringCbCopyA(buf, sizeof(buf), "x86_win32 i386_w2k i386_nt40");
  #endif
***************
*** 920,926 ****
                    cm_freelanceEnabled ? "is" : "is not");
      }       
      else {
!         cm_freelanceEnabled = 0;  /* default off */
      }
  #endif /* AFS_FREELANCE_CLIENT */
  
--- 922,928 ----
                    cm_freelanceEnabled ? "is" : "is not");
      }       
      else {
!         cm_freelanceEnabled = 1;  /* default on */
      }
  #endif /* AFS_FREELANCE_CLIENT */
  
***************
*** 1047,1052 ****
--- 1049,1080 ----
  	cm_daemonTokenCheckInterval = dwValue;
      afsi_log("daemonCheckTokenInterval is %d", cm_daemonTokenCheckInterval);
  
+     dummyLen = sizeof(DWORD);
+     code = RegQueryValueEx(parmKey, "CallBackPort", NULL, NULL,
+                            (BYTE *) &amp;dwValue, &amp;dummyLen);
+     if (code == ERROR_SUCCESS) {
+         cm_callbackport = (unsigned short) dwValue;
+     }
+     afsi_log("CM CallBackPort is %u", cm_callbackport);
+ 
+     dummyLen = sizeof(DWORD);
+     code = RegQueryValueEx(parmKey, "EnableServerLocks", NULL, NULL,
+                            (BYTE *) &amp;dwValue, &amp;dummyLen);
+     if (code == ERROR_SUCCESS) {
+         cm_enableServerLocks = (unsigned short) dwValue;
+     } 
+     switch (cm_enableServerLocks) {
+     case 0:
+ 	afsi_log("EnableServerLocks: never");
+     	break;
+     case 2:
+ 	afsi_log("EnableServerLocks: always");
+ 	break;
+     case 1:
+     default:
+ 	afsi_log("EnableServerLocks: server requested");
+     	break;
+     }
      RegCloseKey (parmKey);
  
      /* Call lanahelper to get Netbios name, lan adapter number and gateway flag */
***************
*** 1137,1149 ****
          afsi_log("rx_SetMaxMTU %d successful", rx_mtu);
      }
  
!     /* initialize RX, and tell it to listen to port 7001, which is used for
!      * callback RPC messages.
       */
!     code = rx_Init(htons(7001));
      afsi_log("rx_Init code %x", code);
      if (code != 0) {
!         *reasonP = "afsd: failed to init rx client on port 7001";
          return -1;
      }
  
--- 1165,1181 ----
          afsi_log("rx_SetMaxMTU %d successful", rx_mtu);
      }
  
!     /* initialize RX, and tell it to listen to the callbackport, 
!      * which is used for callback RPC messages.
       */
!     code = rx_Init(htons(cm_callbackport));
!     if (code != 0) {
! 	afsi_log("rx_Init code %x - retrying with a random port number", code);
! 	code = rx_Init(0);
!     }
      afsi_log("rx_Init code %x", code);
      if (code != 0) {
!         *reasonP = "afsd: failed to init rx client";
          return -1;
      }
  
***************
*** 1519,1525 ****
              DWORD dummyLen;
              DWORD dwValue;
              DWORD code;
!             DWORD dwMiniDumpType = MiniDumpNormal;
  
              code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
                                   0, KEY_QUERY_VALUE, &amp;parmKey);
--- 1551,1557 ----
              DWORD dummyLen;
              DWORD dwValue;
              DWORD code;
!             DWORD dwMiniDumpType = MiniDumpWithDataSegs;
  
              code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
                                   0, KEY_QUERY_VALUE, &amp;parmKey);
***************
*** 1528,1534 ****
                  code = RegQueryValueEx(parmKey, "MiniDumpType", NULL, NULL,
                                          (BYTE *) &amp;dwValue, &amp;dummyLen);
                  if (code == ERROR_SUCCESS)
!                     dwMiniDumpType = dwValue ? 1 : 0;
                  RegCloseKey (parmKey);
              }
  
--- 1560,1566 ----
                  code = RegQueryValueEx(parmKey, "MiniDumpType", NULL, NULL,
                                          (BYTE *) &amp;dwValue, &amp;dummyLen);
                  if (code == ERROR_SUCCESS)
!                     dwMiniDumpType = dwValue;
                  RegCloseKey (parmKey);
              }
  
Index: openafs/src/WINNT/afsd/cm.h
diff -c openafs/src/WINNT/afsd/cm.h:1.16 openafs/src/WINNT/afsd/cm.h:1.17
*** openafs/src/WINNT/afsd/cm.h:1.16	Sun Nov 13 09:16:20 2005
--- openafs/src/WINNT/afsd/cm.h	Mon Mar  6 15:07:08 2006
***************
*** 231,236 ****
--- 231,238 ----
  	struct AFSCallBack *CallBack,
  	struct AFSVolSync *Sync);
  
+ #define CM_DEFAULT_CALLBACKPORT         7001
+ 
  /* common flags to many procedures */
  #define CM_FLAG_CREATE		1		/* create entry */
  #define CM_FLAG_CASEFOLD	2		/* fold case in namei, lookup, etc. */
Index: openafs/src/WINNT/afsd/cm_access.c
diff -c openafs/src/WINNT/afsd/cm_access.c:1.6 openafs/src/WINNT/afsd/cm_access.c:1.7
*** openafs/src/WINNT/afsd/cm_access.c:1.6	Fri Mar 11 00:33:21 2005
--- openafs/src/WINNT/afsd/cm_access.c	Sat Apr 22 15:44:28 2006
***************
*** 32,39 ****
   * can't be locked.  Thus, this must always be called in a while loop to stabilize
   * things, since we can always lose the race condition getting to the parent vnode.
   */
! int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up, long rights,
!                         long *outRightsp)
  {
      cm_scache_t *aclScp;
      long code;
--- 32,39 ----
   * can't be locked.  Thus, this must always be called in a while loop to stabilize
   * things, since we can always lose the race condition getting to the parent vnode.
   */
! int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up, afs_uint32 rights,
!                         afs_uint32 *outRightsp)
  {
      cm_scache_t *aclScp;
      long code;
Index: openafs/src/WINNT/afsd/cm_access.h
diff -c openafs/src/WINNT/afsd/cm_access.h:1.3 openafs/src/WINNT/afsd/cm_access.h:1.4
*** openafs/src/WINNT/afsd/cm_access.h:1.3	Mon Apr 30 02:48:02 2001
--- openafs/src/WINNT/afsd/cm_access.h	Sat Apr 22 15:44:28 2006
***************
*** 13,19 ****
  #include "cm_user.h"
  
  extern int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up,
! 	long rights, long *outRights);
  
  extern long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *up,
  	struct cm_req *reqp);
--- 13,19 ----
  #include "cm_user.h"
  
  extern int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up,
! 	afs_uint32 rights, afs_uint32 *outRights);
  
  extern long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *up,
  	struct cm_req *reqp);
Index: openafs/src/WINNT/afsd/cm_aclent.c
diff -c openafs/src/WINNT/afsd/cm_aclent.c:1.13 openafs/src/WINNT/afsd/cm_aclent.c:1.14
*** openafs/src/WINNT/afsd/cm_aclent.c:1.13	Mon Feb 13 11:33:49 2006
--- openafs/src/WINNT/afsd/cm_aclent.c	Sat Apr 22 15:44:28 2006
***************
*** 68,74 ****
   * Get an acl cache entry for a particular user and file, or return that it doesn't exist.
   * Called with the scp locked.
   */
! long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, long *rightsp)
  {
      cm_aclent_t *aclp;
      long retval = -1;
--- 68,74 ----
   * Get an acl cache entry for a particular user and file, or return that it doesn't exist.
   * Called with the scp locked.
   */
! long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, afs_uint32 *rightsp)
  {
      cm_aclent_t *aclp;
      long retval = -1;
***************
*** 147,153 ****
   *
   * The scp must be locked when this function is called.
   */
! long cm_AddACLCache(cm_scache_t *scp, cm_user_t *userp, long rights)
  {
      register struct cm_aclent *aclp;
  
--- 147,153 ----
   *
   * The scp must be locked when this function is called.
   */
! long cm_AddACLCache(cm_scache_t *scp, cm_user_t *userp, afs_uint32 rights)
  {
      register struct cm_aclent *aclp;
  
Index: openafs/src/WINNT/afsd/cm_aclent.h
diff -c openafs/src/WINNT/afsd/cm_aclent.h:1.5 openafs/src/WINNT/afsd/cm_aclent.h:1.6
*** openafs/src/WINNT/afsd/cm_aclent.h:1.5	Sat Nov  5 01:47:46 2005
--- openafs/src/WINNT/afsd/cm_aclent.h	Sat Apr 22 15:44:28 2006
***************
*** 25,31 ****
      struct cm_aclent *nextp;	/* next guy same vnode */
      struct cm_scache *backp;	/* back ptr to vnode */
      struct cm_user *userp;	/* user whose access is cached */
!     long randomAccess;		/* watch for more rights in acl.h */
      unsigned long tgtLifetime;	/* time this expires */
  } cm_aclent_t;
  
--- 25,31 ----
      struct cm_aclent *nextp;	/* next guy same vnode */
      struct cm_scache *backp;	/* back ptr to vnode */
      struct cm_user *userp;	/* user whose access is cached */
!     afs_uint32 randomAccess;	/* watch for more rights in acl.h */
      unsigned long tgtLifetime;	/* time this expires */
  } cm_aclent_t;
  
***************
*** 33,43 ****
  
  extern long cm_InitACLCache(int newFile, long size);
  
! extern long cm_FindACLCache(struct cm_scache *scp, struct cm_user *userp, long *rightsp);
  
  static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp);
  
! extern long cm_AddACLCache(struct cm_scache *scp, struct cm_user *userp, long rights);
  
  extern void cm_FreeAllACLEnts(struct cm_scache *scp);
  
--- 33,43 ----
  
  extern long cm_InitACLCache(int newFile, long size);
  
! extern long cm_FindACLCache(struct cm_scache *scp, struct cm_user *userp, afs_uint32 *rightsp);
  
  static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp);
  
! extern long cm_AddACLCache(struct cm_scache *scp, struct cm_user *userp, afs_uint32 rights);
  
  extern void cm_FreeAllACLEnts(struct cm_scache *scp);
  
Index: openafs/src/WINNT/afsd/cm_buf.c
diff -c openafs/src/WINNT/afsd/cm_buf.c:1.30 openafs/src/WINNT/afsd/cm_buf.c:1.31
*** openafs/src/WINNT/afsd/cm_buf.c:1.30	Fri Nov 18 18:45:02 2005
--- openafs/src/WINNT/afsd/cm_buf.c	Thu Apr 27 11:49:55 2006
***************
*** 885,891 ****
       */
      lock_ReleaseMutex(&amp;bp-&gt;mx);
      *bufpp = bp;
!     osi_Log3(buf_logp, "buf_GetNew returning bp 0x%p for file 0x%p, offset 0x%x",
                bp, scp, offsetp-&gt;LowPart);
      return 0;
  }
--- 885,891 ----
       */
      lock_ReleaseMutex(&amp;bp-&gt;mx);
      *bufpp = bp;
!     osi_Log3(buf_logp, "buf_GetNew returning bp 0x%p for scp 0x%p, offset 0x%x",
                bp, scp, offsetp-&gt;LowPart);
      return 0;
  }
***************
*** 1032,1038 ****
      }
      lock_ReleaseWrite(&amp;buf_globalLock);
  
!     osi_Log3(buf_logp, "buf_Get returning bp 0x%p for file 0x%p, offset 0x%x",
                bp, scp, offsetp-&gt;LowPart);
  #ifdef TESTING
      buf_ValidateBufQueues();
--- 1032,1038 ----
      }
      lock_ReleaseWrite(&amp;buf_globalLock);
  
!     osi_Log3(buf_logp, "buf_Get returning bp 0x%p for scp 0x%p, offset 0x%x",
                bp, scp, offsetp-&gt;LowPart);
  #ifdef TESTING
      buf_ValidateBufQueues();
Index: openafs/src/WINNT/afsd/cm_conn.c
diff -c openafs/src/WINNT/afsd/cm_conn.c:1.48 openafs/src/WINNT/afsd/cm_conn.c:1.49
*** openafs/src/WINNT/afsd/cm_conn.c:1.48	Wed Feb  1 13:02:29 2006
--- openafs/src/WINNT/afsd/cm_conn.c	Mon Mar  6 15:07:08 2006
***************
*** 18,23 ****
--- 18,24 ----
  #include &lt;osi.h&gt;
  #include &lt;rx/rx.h&gt;
  #include &lt;rx/rxkad.h&gt;
+ #include &lt;afs/unified_afs.h&gt;
  #include "afsd.h"
  
  osi_rwlock_t cm_connLock;
***************
*** 510,516 ****
--- 511,521 ----
              case VRESTARTING       : s = "VRESTARTING";        break;
              case VREADONLY         : s = "VREADONLY";          break;
              case EAGAIN            : s = "EAGAIN";             break;
+ 	    case UAEAGAIN          : s = "UAEAGAIN";	       break;
+             case EINVAL            : s = "EINVAL";             break;
+ 	    case UAEINVAL          : s = "UAEINVAL";	       break;
              case EACCES            : s = "EACCES";             break;
+ 	    case UAEACCES 	   : s = "UAECCES";            break;
              }
              osi_Log2(afsd_logp, "cm_Analyze: ignoring error code 0x%x (%s)", 
                       errorCode, s);
Index: openafs/src/WINNT/afsd/cm_freelance.c
diff -c openafs/src/WINNT/afsd/cm_freelance.c:1.32 openafs/src/WINNT/afsd/cm_freelance.c:1.33
*** openafs/src/WINNT/afsd/cm_freelance.c:1.32	Mon Feb  6 02:06:33 2006
--- openafs/src/WINNT/afsd/cm_freelance.c	Fri Feb 24 02:45:35 2006
***************
*** 29,35 ****
  cm_localMountPoint_t* cm_localMountPoints;
  osi_mutex_t cm_Freelance_Lock;
  int cm_localMountPointChangeFlag = 0;
! int cm_freelanceEnabled = 0;
  time_t FakeFreelanceModTime = 0x3b49f6e2;
  
  static int freelance_ShutdownFlag = 0;
--- 29,35 ----
  cm_localMountPoint_t* cm_localMountPoints;
  osi_mutex_t cm_Freelance_Lock;
  int cm_localMountPointChangeFlag = 0;
! int cm_freelanceEnabled = 1;
  time_t FakeFreelanceModTime = 0x3b49f6e2;
  
  static int freelance_ShutdownFlag = 0;
Index: openafs/src/WINNT/afsd/cm_ioctl.c
diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.68 openafs/src/WINNT/afsd/cm_ioctl.c:1.73
*** openafs/src/WINNT/afsd/cm_ioctl.c:1.68	Wed Feb  1 13:02:29 2006
--- openafs/src/WINNT/afsd/cm_ioctl.c	Sat Apr 22 15:44:28 2006
***************
*** 9,14 ****
--- 9,17 ----
  
  #include &lt;afs/param.h&gt;
  #include &lt;afs/stds.h&gt;
+ #include &lt;afs/cellconfig.h&gt;
+ #include &lt;afs/ptserver.h&gt;
+ #include &lt;ubik.h&gt;
  
  #ifndef DJGPP
  #include &lt;windows.h&gt;
***************
*** 476,482 ****
                          userp, ioctlp-&gt;tidPathp, reqp, &amp;substRootp);
          if (code) return code;
  
!         code = cm_NameI(substRootp, tbuffer, CM_FLAG_FOLLOW,
                          userp, NULL, reqp, scpp);
          if (code) return code;
      }
--- 479,485 ----
                          userp, ioctlp-&gt;tidPathp, reqp, &amp;substRootp);
          if (code) return code;
  
!         code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                          userp, NULL, reqp, scpp);
          if (code) return code;
      }
***************
*** 552,558 ****
           scp-&gt;fid.cell==AFS_FAKE_ROOT_CELL_ID &amp;&amp;
           scp-&gt;fid.volume==AFS_FAKE_ROOT_VOL_ID &amp;&amp;
           scp-&gt;fid.vnode==0x1 &amp;&amp; scp-&gt;fid.unique==0x1 ) {
!         StringCbCopyA(ioctlp-&gt;outDatap, 999999, "Freelance.Local.Root");
          ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) + 1;
          code = 0;
      } else 
--- 555,561 ----
           scp-&gt;fid.cell==AFS_FAKE_ROOT_CELL_ID &amp;&amp;
           scp-&gt;fid.volume==AFS_FAKE_ROOT_VOL_ID &amp;&amp;
           scp-&gt;fid.vnode==0x1 &amp;&amp; scp-&gt;fid.unique==0x1 ) {
!         StringCbCopyA(ioctlp-&gt;outDatap, SMB_IOCTL_MAXDATA - (ioctlp-&gt;outDatap - ioctlp-&gt;outAllocp), "Freelance.Local.Root");
          ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) + 1;
          code = 0;
      } else 
***************
*** 560,566 ****
      {
          cellp = cm_FindCellByID(scp-&gt;fid.cell);
          if (cellp) {
!             StringCbCopyA(ioctlp-&gt;outDatap, 999999, cellp-&gt;name);
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) + 1;
              code = 0;
          }
--- 563,569 ----
      {
          cellp = cm_FindCellByID(scp-&gt;fid.cell);
          if (cellp) {
!             StringCbCopyA(ioctlp-&gt;outDatap, SMB_IOCTL_MAXDATA - (ioctlp-&gt;outDatap - ioctlp-&gt;outAllocp), cellp-&gt;name);
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) + 1;
              code = 0;
          }
***************
*** 762,772 ****
      cp = ioctlp-&gt;outDatap;
      memcpy(cp, (char *)&amp;volStat, sizeof(VolumeStatus));
      cp += sizeof(VolumeStatus);
!     StringCbCopyA(cp, 999999, volName);
      cp += strlen(volName)+1;
!     StringCbCopyA(cp, 999999, offLineMsg);
      cp += strlen(offLineMsg)+1;
!     StringCbCopyA(cp, 999999, motd);
      cp += strlen(motd)+1;
  
      /* now return updated return data pointer */
--- 765,775 ----
      cp = ioctlp-&gt;outDatap;
      memcpy(cp, (char *)&amp;volStat, sizeof(VolumeStatus));
      cp += sizeof(VolumeStatus);
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), volName);
      cp += strlen(volName)+1;
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), offLineMsg);
      cp += strlen(offLineMsg)+1;
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), motd);
      cp += strlen(motd)+1;
  
      /* now return updated return data pointer */
***************
*** 818,828 ****
      cp = ioctlp-&gt;outDatap;
      memcpy(cp, (char *)&amp;volStat, sizeof(AFSFetchVolumeStatus));
      cp += sizeof(AFSFetchVolumeStatus);
!     StringCbCopyA(cp, 999999, volName);
      cp += strlen(volName)+1;
!     StringCbCopyA(cp, 999999, offLineMsg);
      cp += strlen(offLineMsg)+1;
!     StringCbCopyA(cp, 999999, motd);
      cp += strlen(motd)+1;
  
      /* return new size */
--- 821,831 ----
      cp = ioctlp-&gt;outDatap;
      memcpy(cp, (char *)&amp;volStat, sizeof(AFSFetchVolumeStatus));
      cp += sizeof(AFSFetchVolumeStatus);
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), volName);
      cp += strlen(volName)+1;
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), offLineMsg);
      cp += strlen(offLineMsg)+1;
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), motd);
      cp += strlen(motd)+1;
  
      /* return new size */
***************
*** 971,977 ****
      code = cm_ReadMountPoint(scp, userp, &amp;req);
      if (code == 0) {
          cp = ioctlp-&gt;outDatap;
!         StringCbCopyA(cp, 999999, scp-&gt;mountPointStringp);
          cp += strlen(cp) + 1;
          ioctlp-&gt;outDatap = cp;
      }
--- 974,980 ----
      code = cm_ReadMountPoint(scp, userp, &amp;req);
      if (code == 0) {
          cp = ioctlp-&gt;outDatap;
!         StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), scp-&gt;mountPointStringp);
          cp += strlen(cp) + 1;
          ioctlp-&gt;outDatap = cp;
      }
***************
*** 1258,1264 ****
          }
          lock_ReleaseRead(&amp;cm_serverLock);
          cp = basep + max * sizeof(afs_int32);
!         StringCbCopyA(cp, 999999, tcellp-&gt;name);
          cp += strlen(tcellp-&gt;name)+1;
          ioctlp-&gt;outDatap = cp;
      }
--- 1261,1267 ----
          }
          lock_ReleaseRead(&amp;cm_serverLock);
          cp = basep + max * sizeof(afs_int32);
!         StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), tcellp-&gt;name);
          cp += strlen(tcellp-&gt;name)+1;
          ioctlp-&gt;outDatap = cp;
      }
***************
*** 1331,1341 ****
  
  	if (cm_freelanceEnabled) {
              if (cm_GetRootCellName(ioctlp-&gt;outDatap))
!                 StringCbCopyA(ioctlp-&gt;outDatap, 999999, "Freelance.Local.Root");
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
  	} else if (cm_data.rootCellp) {
  	    /* return the default cellname to the caller */
! 	    StringCbCopyA(ioctlp-&gt;outDatap, 999999, cm_data.rootCellp-&gt;name);
  	    ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
  	} else {
  	    /* if we don't know our default cell, return failure */
--- 1334,1344 ----
  
  	if (cm_freelanceEnabled) {
              if (cm_GetRootCellName(ioctlp-&gt;outDatap))
!                 StringCbCopyA(ioctlp-&gt;outDatap, SMB_IOCTL_MAXDATA - (ioctlp-&gt;outDatap - ioctlp-&gt;outAllocp), "Freelance.Local.Root");
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
  	} else if (cm_data.rootCellp) {
  	    /* return the default cellname to the caller */
! 	    StringCbCopyA(ioctlp-&gt;outDatap, SMB_IOCTL_MAXDATA - (ioctlp-&gt;outDatap - ioctlp-&gt;outAllocp), cm_data.rootCellp-&gt;name);
  	    ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
  	} else {
  	    /* if we don't know our default cell, return failure */
***************
*** 1417,1423 ****
          memcpy(cp, (char *)&amp;foundname, sizeof(afs_int32));
          cp += sizeof(afs_int32);	/* skip found flag */
          if (foundname) {
!             StringCbCopyA(cp, 999999, outname);
              cp += strlen(outname) + 1;	/* skip name and terminating null char */
              for ( count=1; count &lt; foundname ; ++count) {   /* ... or list */
                  if ( !(*sysnamelist)[count] )
--- 1420,1426 ----
          memcpy(cp, (char *)&amp;foundname, sizeof(afs_int32));
          cp += sizeof(afs_int32);	/* skip found flag */
          if (foundname) {
!             StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), outname);
              cp += strlen(outname) + 1;	/* skip name and terminating null char */
              for ( count=1; count &lt; foundname ; ++count) {   /* ... or list */
                  if ( !(*sysnamelist)[count] )
***************
*** 1427,1433 ****
                  if (t &gt;= MAXSYSNAME)
                      osi_panic("cm_IoctlSysName: sysname entry garbled\n", 
                                 __FILE__, __LINE__);
!                 StringCbCopyA(cp, 999999, (*sysnamelist)[count]);
                  cp += t + 1;
              }
          }
--- 1430,1436 ----
                  if (t &gt;= MAXSYSNAME)
                      osi_panic("cm_IoctlSysName: sysname entry garbled\n", 
                                 __FILE__, __LINE__);
!                 StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), (*sysnamelist)[count]);
                  cp += t + 1;
              }
          }
***************
*** 1768,1778 ****
      if (code == 0) {
          cp = ioctlp-&gt;outDatap;
          if (newRootScp != NULL) {
!             StringCbCopyA(cp, 999999, cm_mountRoot);
!             StringCbCatA(cp, 999999, "/");
              cp += strlen(cp);
          }
!         StringCbCopyA(cp, 999999, spacep-&gt;data);
          cp += strlen(cp) + 1;
          ioctlp-&gt;outDatap = cp;
          cm_FreeSpace(spacep);
--- 1771,1781 ----
      if (code == 0) {
          cp = ioctlp-&gt;outDatap;
          if (newRootScp != NULL) {
!             StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), cm_mountRoot);
!             StringCbCatA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), "/");
              cp += strlen(cp);
          }
!         StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), spacep-&gt;data);
          cp += strlen(cp) + 1;
          ioctlp-&gt;outDatap = cp;
          cm_FreeSpace(spacep);
***************
*** 1784,1790 ****
                 code == CM_ERROR_NOSUCHPATH &amp;&amp;
                  scp-&gt;fileType == CM_SCACHETYPE_INVALID) {
          cp = ioctlp-&gt;outDatap;
!         StringCbCopyA(cp, 999999, spacep-&gt;data);
          cp += strlen(cp) + 1;
          ioctlp-&gt;outDatap = cp;
          cm_FreeSpace(spacep);
--- 1787,1793 ----
                 code == CM_ERROR_NOSUCHPATH &amp;&amp;
                  scp-&gt;fileType == CM_SCACHETYPE_INVALID) {
          cp = ioctlp-&gt;outDatap;
!         StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), spacep-&gt;data);
          cp += strlen(cp) + 1;
          ioctlp-&gt;outDatap = cp;
          cm_FreeSpace(spacep);
***************
*** 1893,1898 ****
--- 1896,1978 ----
      return code;
  }
  
+ #ifdef QUERY_AFSID
+ long cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
+ {
+     afs_int32 code;
+     namelist lnames;
+     idlist lids;
+     static struct afsconf_cell info;
+     struct rx_connection *serverconns[MAXSERVERS];
+     struct rx_securityClass *sc[3];
+     afs_int32 scIndex = 2;	/* authenticated - we have a token */
+     struct ubik_client *pruclient = NULL;
+     struct afsconf_dir *tdir;
+     int i;
+     char * p, * r;
+ 
+     tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
+     code = afsconf_GetCellInfo(tdir, ucellp-&gt;cellp-&gt;name, "afsprot", &amp;info);
+     afsconf_Close(tdir);
+ 
+     sc[0] = 0;
+     sc[1] = 0;
+     sc[2] = 0;
+ 
+     /* we have the token that was given to us in the settoken 
+      * call.   we just have to use it. 
+      */
+     scIndex = 2;	/* kerberos ticket */
+     sc[2] = rxkad_NewClientSecurityObject(rxkad_clear, &amp;ucellp-&gt;sessionKey,
+ 					  ucellp-&gt;kvno, ucellp-&gt;ticketLen,
+ 					  ucellp-&gt;ticketp);
+ 
+     memset(serverconns, 0, sizeof(serverconns));	/* terminate list!!! */
+     for (i = 0; i &lt; info.numServers; i++)
+ 	serverconns[i] =
+ 	    rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
+ 			     info.hostAddr[i].sin_port, PRSRV, sc[scIndex],
+ 			     scIndex);
+ 
+     code = ubik_ClientInit(serverconns, &amp;pruclient);
+     if (code) {
+ 	return code;
+     }
+ 
+     code = rxs_Release(sc[scIndex]);
+ 
+     lids.idlist_len = 0;
+     lids.idlist_val = 0;
+     lnames.namelist_len = 1;
+     lnames.namelist_val = (prname *) malloc(PR_MAXNAMELEN);
+     strncpy(lnames.namelist_val[0], uname, PR_MAXNAMELEN);
+     lnames.namelist_val[0][PR_MAXNAMELEN-1] = '\0';
+     for ( p=lnames.namelist_val[0], r=NULL; *p; p++ ) {
+ 	if (isupper(*p))
+ 	    *p = tolower(*p);
+ 	if (*p == '@')
+ 	    r = p;
+     }
+     if (r &amp;&amp; !stricmp(r+1,ucellp-&gt;cellp-&gt;name))
+ 	*r = '\0';
+ 
+     code = ubik_Call(PR_NameToID, pruclient, 0, &amp;lnames, &amp;lids);
+     if (lids.idlist_val) {
+ 	*uid = *lids.idlist_val;
+ 	free(lids.idlist_val);
+     }
+     if (lnames.namelist_val)
+ 	free(lnames.namelist_val);
+ 
+     if ( pruclient ) {
+ 	ubik_ClientDestroy(pruclient);
+ 	pruclient = NULL;
+     }
+ 
+     return 0;
+ }
+ #endif /* QUERY_AFSID */
+ 
  long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
  {
      char *saveDataPtr;
***************
*** 1909,1914 ****
--- 1989,1995 ----
      char sessionKey[8];
      char *smbname;
      int release_userp = 0;
+     char * wdir = NULL;
  
      saveDataPtr = ioctlp-&gt;inDatap;
  
***************
*** 2008,2015 ****
      ucellp-&gt;kvno = ct.AuthHandle;
      ucellp-&gt;expirationTime = ct.EndTimestamp;
      ucellp-&gt;gen++;
!     if (uname) 
          StringCbCopyA(ucellp-&gt;userName, MAXKTCNAMELEN, uname);
      ucellp-&gt;flags |= CM_UCELLFLAG_RXKAD;
      lock_ReleaseMutex(&amp;userp-&gt;mx);
  
--- 2089,2103 ----
      ucellp-&gt;kvno = ct.AuthHandle;
      ucellp-&gt;expirationTime = ct.EndTimestamp;
      ucellp-&gt;gen++;
! #ifdef QUERY_AFSID
!     ucellp-&gt;uid = ANONYMOUSID;
! #endif
!     if (uname) {
          StringCbCopyA(ucellp-&gt;userName, MAXKTCNAMELEN, uname);
+ #ifdef QUERY_AFSID
+ 	cm_UsernameToId(uname, ucellp, &amp;ucellp-&gt;uid);
+ #endif
+     }
      ucellp-&gt;flags |= CM_UCELLFLAG_RXKAD;
      lock_ReleaseMutex(&amp;userp-&gt;mx);
  
***************
*** 2098,2108 ****
      cp += sizeof(temp);
  
      /* cell name */
!     StringCbCopyA(cp, 999999, ucellp-&gt;cellp-&gt;name);
      cp += strlen(cp) + 1;
  
      /* user name */
!     StringCbCopyA(cp, 999999, ucellp-&gt;userName);
      cp += strlen(cp) + 1;
  
      ioctlp-&gt;outDatap = cp;
--- 2186,2196 ----
      cp += sizeof(temp);
  
      /* cell name */
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), ucellp-&gt;cellp-&gt;name);
      cp += strlen(cp) + 1;
  
      /* user name */
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), ucellp-&gt;userName);
      cp += strlen(cp) + 1;
  
      ioctlp-&gt;outDatap = cp;
***************
*** 2187,2197 ****
      cp += sizeof(temp);
  
      /* cell name */
!     StringCbCopyA(cp, 999999, ucellp-&gt;cellp-&gt;name);
      cp += strlen(cp) + 1;
  
      /* user name */
!     StringCbCopyA(cp, 999999, ucellp-&gt;userName);
      cp += strlen(cp) + 1;
  
      ioctlp-&gt;outDatap = cp;
--- 2275,2285 ----
      cp += sizeof(temp);
  
      /* cell name */
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), ucellp-&gt;cellp-&gt;name);
      cp += strlen(cp) + 1;
  
      /* user name */
!     StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp-&gt;outAllocp), ucellp-&gt;userName);
      cp += strlen(cp) + 1;
  
      ioctlp-&gt;outDatap = cp;
***************
*** 2233,2238 ****
--- 2321,2331 ----
          free(ucellp-&gt;ticketp);
          ucellp-&gt;ticketp = NULL;
      }
+     ucellp-&gt;ticketLen = 0;
+     memset(ucellp-&gt;sessionKey.data, 0, 8);
+     ucellp-&gt;kvno = 0;
+     ucellp-&gt;expirationTime = 0;
+     ucellp-&gt;userName[0] = '\0';
      ucellp-&gt;flags &amp;= ~CM_UCELLFLAG_RXKAD;
      ucellp-&gt;gen++;
  
***************
*** 2251,2256 ****
--- 2344,2359 ----
  
      for (ucellp = userp-&gt;cellInfop; ucellp; ucellp = ucellp-&gt;nextp) {
          osi_Log1(smb_logp,"cm_IoctlDelAllToken ucellp %lx", ucellp);
+ 
+ 	if (ucellp-&gt;ticketp) {
+ 	    free(ucellp-&gt;ticketp);
+ 	    ucellp-&gt;ticketp = NULL;
+ 	}
+ 	ucellp-&gt;ticketLen = 0;
+ 	memset(ucellp-&gt;sessionKey.data, 0, 8);
+ 	ucellp-&gt;kvno = 0;
+ 	ucellp-&gt;expirationTime = 0;
+ 	ucellp-&gt;userName[0] = '\0';
          ucellp-&gt;flags &amp;= ~CM_UCELLFLAG_RXKAD;
          ucellp-&gt;gen++;
      }
***************
*** 2324,2330 ****
                             (DWORD)strlen(&amp;afspath[strlen(cm_mountRoot)])+1:2);
  
              RegCloseKey( hkSubmounts );
!             StringCbCopyA(ioctlp-&gt;outDatap, 999999, submountreqp);
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
              lock_ReleaseMutex(&amp;cm_Afsdsbmt_Lock);
              return 0;
--- 2427,2433 ----
                             (DWORD)strlen(&amp;afspath[strlen(cm_mountRoot)])+1:2);
  
              RegCloseKey( hkSubmounts );
!             StringCbCopyA(ioctlp-&gt;outDatap, SMB_IOCTL_MAXDATA - (ioctlp-&gt;outDatap - ioctlp-&gt;outAllocp), submountreqp);
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
              lock_ReleaseMutex(&amp;cm_Afsdsbmt_Lock);
              return 0;
***************
*** 2336,2342 ****
           */
          cm_NormalizeAfsPath (submountPathNormalized, sizeof(submountPathNormalized), submountPath);
          if (!strcmp (submountPathNormalized, afspath)) {
!             StringCbCopyA(ioctlp-&gt;outDatap, 999999, submountreqp);
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
              RegCloseKey( hkSubmounts );
              lock_ReleaseMutex(&amp;cm_Afsdsbmt_Lock);
--- 2439,2445 ----
           */
          cm_NormalizeAfsPath (submountPathNormalized, sizeof(submountPathNormalized), submountPath);
          if (!strcmp (submountPathNormalized, afspath)) {
!             StringCbCopyA(ioctlp-&gt;outDatap, SMB_IOCTL_MAXDATA - (ioctlp-&gt;outDatap - ioctlp-&gt;outAllocp), submountreqp);
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
              RegCloseKey( hkSubmounts );
              lock_ReleaseMutex(&amp;cm_Afsdsbmt_Lock);
***************
*** 2405,2411 ****
           */
          cm_NormalizeAfsPath (submountPathNormalized, sizeof(submountPathNormalized), submountPath);
          if (!strcmp (submountPathNormalized, afspath)) {
!             StringCbCopyA(ioctlp-&gt;outDatap, 999999, submountName);
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
              RegCloseKey(hkSubmounts);
              lock_ReleaseMutex(&amp;cm_Afsdsbmt_Lock);
--- 2508,2514 ----
           */
          cm_NormalizeAfsPath (submountPathNormalized, sizeof(submountPathNormalized), submountPath);
          if (!strcmp (submountPathNormalized, afspath)) {
!             StringCbCopyA(ioctlp-&gt;outDatap, SMB_IOCTL_MAXDATA - (ioctlp-&gt;outDatap - ioctlp-&gt;outAllocp), submountName);
              ioctlp-&gt;outDatap += strlen(ioctlp-&gt;outDatap) +1;
              RegCloseKey(hkSubmounts);
              lock_ReleaseMutex(&amp;cm_Afsdsbmt_Lock);
***************
*** 2420,2426 ****
       * when writing out the submount.
       */
  
!     StringCbPrintfA(ioctlp-&gt;outDatap, 999999, "auto%ld", nextAutoSubmount);
  
      RegSetValueEx( hkSubmounts, 
                     ioctlp-&gt;outDatap,
--- 2523,2529 ----
       * when writing out the submount.
       */
  
!     StringCbPrintfA(ioctlp-&gt;outDatap, SMB_IOCTL_MAXDATA - (ioctlp-&gt;outDatap - ioctlp-&gt;outAllocp), "auto%ld", nextAutoSubmount);
  
      RegSetValueEx( hkSubmounts, 
                     ioctlp-&gt;outDatap,
Index: openafs/src/WINNT/afsd/cm_scache.c
diff -c openafs/src/WINNT/afsd/cm_scache.c:1.34 openafs/src/WINNT/afsd/cm_scache.c:1.35
*** openafs/src/WINNT/afsd/cm_scache.c:1.34	Wed Feb  1 13:02:30 2006
--- openafs/src/WINNT/afsd/cm_scache.c	Sat Apr 22 15:44:28 2006
***************
*** 668,679 ****
   * CM_SCACHESYNC_STOREDATA_EXCL and CM_SCACHEFLAG_DATASTORING.
   */
  long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
!                long rights, long flags)
  {
      osi_queueData_t *qdp;
      long code;
      cm_buf_t *tbufp;
!     long outRights;
      int bufLocked;
  
      /* lookup this first */
--- 668,679 ----
   * CM_SCACHESYNC_STOREDATA_EXCL and CM_SCACHEFLAG_DATASTORING.
   */
  long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
!                afs_uint32 rights, afs_uint32 flags)
  {
      osi_queueData_t *qdp;
      long code;
      cm_buf_t *tbufp;
!     afs_uint32 outRights;
      int bufLocked;
  
      /* lookup this first */
***************
*** 874,880 ****
                  return CM_ERROR_READONLY;
  
              if (cm_HaveAccessRights(scp, up, rights, &amp;outRights)) {
!                 if (~outRights &amp; rights) return CM_ERROR_NOACCESS;
              }
              else {
                  /* we don't know the required access rights */
--- 874,881 ----
                  return CM_ERROR_READONLY;
  
              if (cm_HaveAccessRights(scp, up, rights, &amp;outRights)) {
!                 if (~outRights &amp; rights) 
! 		    return CM_ERROR_NOACCESS;
              }
              else {
                  /* we don't know the required access rights */
***************
*** 990,996 ****
  /* for those syncops that setup for RPCs.
   * Called with scache locked.
   */
! void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, long flags)
  {
      osi_queueData_t *qdp;
      cm_buf_t *tbufp;
--- 991,997 ----
  /* for those syncops that setup for RPCs.
   * Called with scache locked.
   */
! void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, afs_uint32 flags)
  {
      osi_queueData_t *qdp;
      cm_buf_t *tbufp;
***************
*** 1074,1080 ****
   * started before that, can cause old info to be merged from the first call.
   */
  void cm_MergeStatus(cm_scache_t *scp, AFSFetchStatus *statusp, AFSVolSync *volp,
!                     cm_user_t *userp, int flags)
  {
      // yj: i want to create some fake status for the /afs directory and the
      // entries under that directory
--- 1075,1081 ----
   * started before that, can cause old info to be merged from the first call.
   */
  void cm_MergeStatus(cm_scache_t *scp, AFSFetchStatus *statusp, AFSVolSync *volp,
!                     cm_user_t *userp, afs_uint32 flags)
  {
      // yj: i want to create some fake status for the /afs directory and the
      // entries under that directory
Index: openafs/src/WINNT/afsd/cm_scache.h
diff -c openafs/src/WINNT/afsd/cm_scache.h:1.19 openafs/src/WINNT/afsd/cm_scache.h:1.21
*** openafs/src/WINNT/afsd/cm_scache.h:1.19	Wed Feb  1 13:02:30 2006
--- openafs/src/WINNT/afsd/cm_scache.h	Sat Apr 22 15:44:28 2006
***************
*** 23,36 ****
          unsigned long unique;
  } cm_fid_t;
  
- #if 0
- typedef struct cm_accessCache {
- 	osi_queue_t q;			/* queue header */
-         struct cm_user *userp;		/* user having access rights */
-         unsigned long rights;		/* rights */
- } cm_accessCache_t;
- #endif
- 
  /* Key used for byte range locking.  Each unique key identifies a
     unique client per cm_scache_t for the purpose of locking. */
  typedef afs_uint64 cm_key_t;
--- 23,28 ----
***************
*** 94,142 ****
  #define CM_SCACHE_MAGIC ('S' | 'C'&lt;&lt;8 | 'A'&lt;&lt;16 | 'C'&lt;&lt;24)
  
  typedef struct cm_scache {
!     osi_queue_t q;              /* lru queue; cm_scacheLock */
      afs_uint32      magic;
!     struct cm_scache *nextp;	/* next in hash; cm_scacheLock */
      cm_fid_t fid;
!     afs_uint32 flags;		/* flags; locked by mx */
  
      /* synchronization stuff */
!     osi_mutex_t mx;		/* mutex for this structure */
!     osi_rwlock_t bufCreateLock;	/* read-locked during buffer creation;
!         			 * write-locked to prevent buffers from
!                                  * being created during a truncate op, etc.
!                                  */
      afs_uint32 refCount;		/* reference count; cm_scacheLock */
!     osi_queueData_t *bufReadsp;	/* queue of buffers being read */
      osi_queueData_t *bufWritesp;	/* queue of buffers being written */
  
      /* parent info for ACLs */
      afs_uint32 parentVnode;		/* parent vnode for ACL callbacks */
!     afs_uint32 parentUnique;	/* for ACL callbacks */
  
      /* local modification stat */
!     afs_uint32 mask;		/* for clientModTime, length and
!                                  * truncPos */
  
      /* file status */
      afs_uint32 fileType;		/* file type */
      time_t clientModTime;	        /* mtime */
      time_t serverModTime;	        /* at server, for concurrent call
                                           * comparisons */
!     osi_hyper_t length;		/* file length */
      cm_prefetch_t prefetch;		/* prefetch info structure */
!     afs_uint32 unixModeBits;	/* unix protection mode bits */
      afs_uint32 linkCount;		/* link count */
      afs_uint32 dataVersion;		/* data version */
!     afs_uint32 owner; 		/* file owner */
!     afs_uint32 group;		/* file owning group */
  
      /* pseudo file status */
!     osi_hyper_t serverLength;	/* length known to server */
  
      /* aux file status */
!     osi_hyper_t truncPos;	/* file size to truncate to before
!                                  * storing data */
  
      /* symlink and mount point info */
      char mountPointStringp[MOUNTPOINTLEN];	/* the string stored in a mount point;
--- 86,135 ----
  #define CM_SCACHE_MAGIC ('S' | 'C'&lt;&lt;8 | 'A'&lt;&lt;16 | 'C'&lt;&lt;24)
  
  typedef struct cm_scache {
!     osi_queue_t q;              	/* lru queue; cm_scacheLock */
      afs_uint32      magic;
!     struct cm_scache *nextp;		/* next in hash; cm_scacheLock */
      cm_fid_t fid;
!     afs_uint32 flags;			/* flags; locked by mx */
  
      /* synchronization stuff */
!     osi_mutex_t mx;			/* mutex for this structure */
!     osi_rwlock_t bufCreateLock;		/* read-locked during buffer creation;
!                                          * write-locked to prevent buffers from
! 					 * being created during a truncate op, etc.
! 					 */
      afs_uint32 refCount;		/* reference count; cm_scacheLock */
!     osi_queueData_t *bufReadsp;		/* queue of buffers being read */
      osi_queueData_t *bufWritesp;	/* queue of buffers being written */
  
      /* parent info for ACLs */
      afs_uint32 parentVnode;		/* parent vnode for ACL callbacks */
!     afs_uint32 parentUnique;		/* for ACL callbacks */
  
      /* local modification stat */
!     afs_uint32 mask;			/* for clientModTime, length and
!                                          * truncPos */
  
      /* file status */
      afs_uint32 fileType;		/* file type */
      time_t clientModTime;	        /* mtime */
      time_t serverModTime;	        /* at server, for concurrent call
                                           * comparisons */
!     osi_hyper_t length;			/* file length */
      cm_prefetch_t prefetch;		/* prefetch info structure */
!     afs_uint32 unixModeBits;		/* unix protection mode bits */
      afs_uint32 linkCount;		/* link count */
      afs_uint32 dataVersion;		/* data version */
!     afs_uint32 owner; 			/* file owner */
!     afs_uint32 group;			/* file owning group */
!     cm_user_t *creator;			/* user, if new file */
  
      /* pseudo file status */
!     osi_hyper_t serverLength;		/* length known to server */
  
      /* aux file status */
!     osi_hyper_t truncPos;		/* file size to truncate to before
!                                          * storing data */
  
      /* symlink and mount point info */
      char mountPointStringp[MOUNTPOINTLEN];	/* the string stored in a mount point;
***************
*** 177,188 ****
                                     time. */
      osi_queue_t *fileLocksH;    /* queue of locks (head) */
      osi_queue_t *fileLocksT;    /* queue of locks (tail) */
      afs_uint32   sharedLocks;   /* number of shared locks on
!                                  * ::fileLocks */
      afs_uint32   exclusiveLocks; /* number of exclusive locks on
!                                   * ::fileLocks
                                    */
  	
      /* volume info */
      struct cm_volume *volp;		/* volume info; held reference */
  
--- 170,191 ----
                                     time. */
      osi_queue_t *fileLocksH;    /* queue of locks (head) */
      osi_queue_t *fileLocksT;    /* queue of locks (tail) */
+ 
      afs_uint32   sharedLocks;   /* number of shared locks on
!                                  * ::fileLocks.  This count does not
!                                  * include locks which have
!                                  * CM_FILELOCK_FLAG_CLIENTONLY set. */
! 
      afs_uint32   exclusiveLocks; /* number of exclusive locks on
!                                   * ::fileLocks.  This count does not
!                                   * include locks which have
!                                   * CM_FILELOCK_FLAG_CLIENTONLY set.
                                    */
  	
+     afs_uint32   clientLocks;   /* number of locks on ::fileLocks that
+                                    have CM_FILELOCK_FLAG_CLIENTONLY
+                                    set. */
+ 	
      /* volume info */
      struct cm_volume *volp;		/* volume info; held reference */
  
***************
*** 307,318 ****
  extern int cm_FidCmp(cm_fid_t *, cm_fid_t *);
  
  extern long cm_SyncOp(cm_scache_t *, struct cm_buf *, struct cm_user *,
! 	struct cm_req *, long, long);
  
! extern void cm_SyncOpDone(cm_scache_t *, struct cm_buf *, long);
  
  extern void cm_MergeStatus(cm_scache_t *, struct AFSFetchStatus *, struct AFSVolSync *,
! 	struct cm_user *, int flags);
  
  extern void cm_AFSFidFromFid(struct AFSFid *, cm_fid_t *);
  
--- 310,321 ----
  extern int cm_FidCmp(cm_fid_t *, cm_fid_t *);
  
  extern long cm_SyncOp(cm_scache_t *, struct cm_buf *, struct cm_user *,
! 	struct cm_req *, afs_uint32, afs_uint32);
  
! extern void cm_SyncOpDone(cm_scache_t *, struct cm_buf *, afs_uint32);
  
  extern void cm_MergeStatus(cm_scache_t *, struct AFSFetchStatus *, struct AFSVolSync *,
! 	struct cm_user *, afs_uint32 flags);
  
  extern void cm_AFSFidFromFid(struct AFSFid *, cm_fid_t *);
  
Index: openafs/src/WINNT/afsd/cm_user.h
diff -c openafs/src/WINNT/afsd/cm_user.h:1.6 openafs/src/WINNT/afsd/cm_user.h:1.8
*** openafs/src/WINNT/afsd/cm_user.h:1.6	Thu Jan 19 18:07:50 2006
--- openafs/src/WINNT/afsd/cm_user.h	Sat Apr 22 15:44:28 2006
***************
*** 32,37 ****
--- 32,40 ----
      int iterator;			/* for use as ListTokens cookie */
      long flags;			        /* flags */
      char userName[MAXKTCNAMELEN];	/* user name */
+ #ifdef QUERY_AFSID
+     afs_uint32 uid;			/* User's AFS ID in this cell */
+ #endif
  } cm_ucell_t;
  
  #define CM_UCELLFLAG_HASTIX	1	/* has Kerberos tickets */
Index: openafs/src/WINNT/afsd/cm_vnodeops.c
diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.66 openafs/src/WINNT/afsd/cm_vnodeops.c:1.69
*** openafs/src/WINNT/afsd/cm_vnodeops.c:1.66	Sun Feb  5 12:45:34 2006
--- openafs/src/WINNT/afsd/cm_vnodeops.c	Thu Apr 27 11:49:55 2006
***************
*** 265,271 ****
  
      code = cm_SyncOp(scp, NULL, userp, reqp, rights,
                        CM_SCACHESYNC_GETSTATUS
!                       | CM_SCACHESYNC_NEEDCALLBACK);
  
      if (code == 0 &amp;&amp; 
          ((rights &amp; PRSFS_WRITE) || (rights &amp; PRSFS_READ)) &amp;&amp;
--- 265,272 ----
  
      code = cm_SyncOp(scp, NULL, userp, reqp, rights,
                        CM_SCACHESYNC_GETSTATUS
!                      | CM_SCACHESYNC_NEEDCALLBACK
!                      | CM_SCACHESYNC_LOCK);
  
      if (code == 0 &amp;&amp; 
          ((rights &amp; PRSFS_WRITE) || (rights &amp; PRSFS_READ)) &amp;&amp;
***************
*** 315,322 ****
--- 316,330 ----
  		}
  	    }
          }
+ 
+     } else if (code != 0) {
+         goto _done;
      }
  
+     cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
+ 
+  _done:
+ 
      lock_ReleaseMutex(&amp;scp-&gt;mx);
  
      return code;
***************
*** 346,352 ****
  
      code = cm_SyncOp(scp, NULL, userp, reqp, rights,
                        CM_SCACHESYNC_GETSTATUS
!                       | CM_SCACHESYNC_NEEDCALLBACK);
  
      /*
       * If the open will fail because the volume is readonly, then we will
--- 354,361 ----
  
      code = cm_SyncOp(scp, NULL, userp, reqp, rights,
                        CM_SCACHESYNC_GETSTATUS
!                      | CM_SCACHESYNC_NEEDCALLBACK
!                      | CM_SCACHESYNC_LOCK);
  
      /*
       * If the open will fail because the volume is readonly, then we will
***************
*** 356,362 ****
       */
      if (code == CM_ERROR_READONLY)
          code = CM_ERROR_NOACCESS;
!     else if (code == 0 &amp;&amp;
               ((rights &amp; PRSFS_WRITE) || (rights &amp; PRSFS_READ)) &amp;&amp;
               scp-&gt;fileType == CM_SCACHETYPE_FILE) {
          cm_key_t key;
--- 365,372 ----
       */
      if (code == CM_ERROR_READONLY)
          code = CM_ERROR_NOACCESS;
! 
!     if (code == 0 &amp;&amp;
               ((rights &amp; PRSFS_WRITE) || (rights &amp; PRSFS_READ)) &amp;&amp;
               scp-&gt;fileType == CM_SCACHETYPE_FILE) {
          cm_key_t key;
***************
*** 403,410 ****
--- 413,425 ----
  		}
  	    }
          }
+     } else if (code != 0) {
+         goto _done;
      }
  
+     cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
+ 
+  _done:
      lock_ReleaseMutex(&amp;scp-&gt;mx);
  
      return code;
***************
*** 2270,2275 ****
--- 2285,2291 ----
          code = cm_GetSCache(&amp;newFid, &amp;scp, userp, reqp);
          if (code == 0) {
              lock_ObtainMutex(&amp;scp-&gt;mx);
+ 	    scp-&gt;creator = userp;		/* remember who created it */
              if (!cm_HaveCallback(scp)) {
                  cm_MergeStatus(scp, &amp;newFileStatus, &amp;volSync,
                                  userp, 0);
***************
*** 3300,3306 ****
      osi_QAdd(&amp;cm_freeFileLocks, &amp;l-&gt;q);
  }
  
! /* called with scp-&gt;mx held.  Releases it during processing */
  long cm_IntSetLock(cm_scache_t * scp, cm_user_t * userp, int lockType,
                     cm_req_t * reqp) {
      long code = 0;
--- 3316,3323 ----
      osi_QAdd(&amp;cm_freeFileLocks, &amp;l-&gt;q);
  }
  
! /* called with scp-&gt;mx held.  May release it during processing, but
!    leaves it held on exit. */
  long cm_IntSetLock(cm_scache_t * scp, cm_user_t * userp, int lockType,
                     cm_req_t * reqp) {
      long code = 0;
***************
*** 3387,3392 ****
--- 3404,3474 ----
      return code;
  }
  
+ /* called with scp-&gt;mx held.  May release it during processing, but
+    will exit with lock held.
+ 
+    This will return:
+ 
+    - 0 if the user has permission to get the specified lock for the scp
+ 
+    - CM_ERROR_NOACCESS if not
+ 
+    Any other error from cm_SyncOp will be sent down untranslated.
+ */
+ long cm_LockCheckPerms(cm_scache_t * scp,
+                        int lock_type,
+                        cm_user_t * userp,
+                        cm_req_t * reqp)
+ {
+     long rights = 0;
+     long code = 0;
+ 
+     /* lock permissions are slightly tricky because of the 'i' bit.
+        If the user has PRSFS_LOCK, she can read-lock the file.  If the
+        user has PRSFS_WRITE, she can write-lock the file.  However, if
+        the user has PRSFS_INSERT, then she can write-lock new files,
+        but not old ones.  Since we don't have information about
+        whether a file is new or not, we assume that if the user owns
+        the scp, then she has the permissions that are granted by
+        PRSFS_INSERT. */
+ 
+     osi_Log3(afsd_logp, "cm_LockCheckPerms for scp[0x%p] type[%d] user[0x%p]",
+              scp, lock_type, userp);
+ 
+     if (lock_type == LockRead)
+         rights |= PRSFS_LOCK;
+     else if (lock_type == LockWrite)
+         rights |= PRSFS_WRITE;
+     else {
+         /* hmmkay */
+         osi_assert(FALSE);
+         return 0;
+     }
+ 
+     code = cm_SyncOp(scp, NULL, userp, reqp, rights,
+                      CM_SCACHESYNC_GETSTATUS |
+                      CM_SCACHESYNC_NEEDCALLBACK);
+ 
+     if (code == CM_ERROR_NOACCESS &amp;&amp;
+         lock_type == LockWrite &amp;&amp;
+ 	scp-&gt;creator == userp) {
+         /* check for PRSFS_INSERT. */
+         cm_ucell_t * ucp;
+ 
+         code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_INSERT,
+                          CM_SCACHESYNC_GETSTATUS |
+                          CM_SCACHESYNC_NEEDCALLBACK);
+ 
+ 	if (code == CM_ERROR_NOACCESS)
+ 	    osi_Log0(afsd_logp, "cm_LockCheckPerms user is creator but has no INSERT bits for scp");
+     }
+ 
+  return_code:
+     osi_Log1(afsd_logp, "cm_LockCheckPerms returning code %d", code);
+ 
+     return code;
+ }
+ 
  /* called with scp-&gt;mx held */
  long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
               LARGE_INTEGER LOffset, LARGE_INTEGER LLength,
***************
*** 3400,3405 ****
--- 3482,3488 ----
      osi_queue_t *q;
      cm_range_t range;
      int wait_unlock = FALSE;
+     int force_client_lock = FALSE;
  
      osi_Log4(afsd_logp, "cm_Lock scp 0x%x type 0x%x offset %d length %d",
               scp, sLockType, (unsigned long)LOffset.QuadPart, (unsigned long)LLength.QuadPart);
***************
*** 3471,3477 ****
              /* we already have the lock we need */
              osi_Log3(afsd_logp, "   we already have the correct lock. exclusives[%d], shared[%d], serverLock[%d]", 
                       scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, (int)(signed char) scp-&gt;serverLock);
!             code = 0; /* redundant */
  
          } else if ((scp-&gt;exclusiveLocks &gt; 0) ||
                  (scp-&gt;sharedLocks &gt; 0 &amp;&amp; scp-&gt;serverLock != LockRead)) {
--- 3554,3571 ----
              /* we already have the lock we need */
              osi_Log3(afsd_logp, "   we already have the correct lock. exclusives[%d], shared[%d], serverLock[%d]", 
                       scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, (int)(signed char) scp-&gt;serverLock);
! 
!             code = cm_LockCheckPerms(scp, Which, userp, reqp);
! 
!             /* special case: if we don't have permission to read-lock
!                the file, then we force a clientside lock.  This is to
!                compensate for applications that obtain a read-lock for
!                reading files off of directories that don't grant
!                read-locks to the user. */
!             if (code == CM_ERROR_NOACCESS &amp;&amp; Which == LockRead) {
!                 osi_Log0(afsd_logp, "   User has no read-lock perms. Forcing client-side lock");
!                 force_client_lock = TRUE;
!             }
  
          } else if ((scp-&gt;exclusiveLocks &gt; 0) ||
                  (scp-&gt;sharedLocks &gt; 0 &amp;&amp; scp-&gt;serverLock != LockRead)) {
***************
*** 3481,3492 ****
                 flood of SetLock calls. */
              osi_Log3(afsd_logp, "   already waiting for other lock. exclusives[%d], shared[%d], serverLock[%d]",
                       scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, (int)(signed char) scp-&gt;serverLock);
!             code = CM_ERROR_WOULDBLOCK;
  
          } else {
              int newLock;
              int check_data_version = FALSE;
  
              if (scp-&gt;serverLock == LockRead &amp;&amp; Which == LockWrite) {
              
                  /* We want to escalate the lock to a LockWrite.
--- 3575,3608 ----
                 flood of SetLock calls. */
              osi_Log3(afsd_logp, "   already waiting for other lock. exclusives[%d], shared[%d], serverLock[%d]",
                       scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, (int)(signed char) scp-&gt;serverLock);
! 
!             /* see if we have permission to create the lock in the
!                first place. */
!             code = cm_LockCheckPerms(scp, Which, userp, reqp);
!             if (code == 0)
! 		code = CM_ERROR_WOULDBLOCK;
!             else if (code == CM_ERROR_NOACCESS &amp;&amp; Which == LockRead) {
!                 osi_Log0(afsd_logp, "   User has no read-lock perms.  Forcing client-side lock");
!                 force_client_lock = TRUE;
!             }
! 
!             /* leave any other codes as-is */
  
          } else {
              int newLock;
              int check_data_version = FALSE;
  
+             /* first check if we have permission to elevate or obtain
+                the lock. */
+             code = cm_LockCheckPerms(scp, Which, userp, reqp);
+             if (code) {
+                 if (code == CM_ERROR_NOACCESS &amp;&amp; Which == LockRead) {
+                     osi_Log0(afsd_logp, "   User has no read-lock perms.  Forcing client-side lock");
+                     force_client_lock = TRUE;
+                 }
+                 goto check_code;
+             }
+ 
              if (scp-&gt;serverLock == LockRead &amp;&amp; Which == LockWrite) {
              
                  /* We want to escalate the lock to a LockWrite.
***************
*** 3573,3579 ****
  
   check_code:
  
!     if (code != 0) {
          /* Special case error translations
  
             Applications don't expect certain errors from a
--- 3689,3695 ----
  
   check_code:
  
!     if (code != 0 &amp;&amp; !force_client_lock) {
          /* Special case error translations
  
             Applications don't expect certain errors from a
***************
*** 3588,3594 ****
          }
      }
  
!     if (code == 0 || (code == CM_ERROR_WOULDBLOCK &amp;&amp; allowWait)) {
  
          lock_ObtainWrite(&amp;cm_scacheLock);
          fileLock = cm_GetFileLock();
--- 3704,3716 ----
          }
      }
  
!     if (code == 0 || (code == CM_ERROR_WOULDBLOCK &amp;&amp; allowWait) ||
!         force_client_lock) {
! 
!         /* clear the error if we are forcing a client lock, so we
!            don't get confused later. */
!         if (force_client_lock &amp;&amp; code != CM_ERROR_WOULDBLOCK)
!             code = 0;
  
          lock_ObtainWrite(&amp;cm_scacheLock);
          fileLock = cm_GetFileLock();
***************
*** 3606,3615 ****
                              CM_FILELOCK_FLAG_WAITUNLOCK :
                              CM_FILELOCK_FLAG_WAITLOCK));
  
!         if (!SERVERLOCKS_ENABLED(scp))
              fileLock-&gt;flags |= CM_FILELOCK_FLAG_CLIENTONLY;
  
!         fileLock-&gt;lastUpdate = (code == 0) ? time(NULL) : 0;
  
          lock_ObtainWrite(&amp;cm_scacheLock);
          osi_QAddT(&amp;scp-&gt;fileLocksH, &amp;scp-&gt;fileLocksT, &amp;fileLock-&gt;fileq);
--- 3728,3737 ----
                              CM_FILELOCK_FLAG_WAITUNLOCK :
                              CM_FILELOCK_FLAG_WAITLOCK));
  
!         if (force_client_lock || !SERVERLOCKS_ENABLED(scp))
              fileLock-&gt;flags |= CM_FILELOCK_FLAG_CLIENTONLY;
  
!         fileLock-&gt;lastUpdate = (code == 0 &amp;&amp; !force_client_lock) ? time(NULL) : 0;
  
          lock_ObtainWrite(&amp;cm_scacheLock);
          osi_QAddT(&amp;scp-&gt;fileLocksH, &amp;scp-&gt;fileLocksT, &amp;fileLock-&gt;fileq);
***************
*** 3622,3644 ****
              *lockpp = fileLock;
          }
  
!         if (IS_LOCK_ACCEPTED(fileLock)) {
              if (Which == LockRead)
                  scp-&gt;sharedLocks++;
              else
                  scp-&gt;exclusiveLocks++;
          }
  
!         osi_Log2(afsd_logp,
!                  "cm_Lock Lock added 0x%p flags 0x%x",
!                  fileLock, fileLock-&gt;flags);
          osi_Log4(afsd_logp,
!                  "   scp[0x%p] exclusives[%d] shared[%d] serverLock[%d]",
!                  scp, scp-&gt;exclusiveLocks, scp-&gt;sharedLocks,
                   (int)(signed char) scp-&gt;serverLock);
      } else {
          osi_Log1(afsd_logp,
!                  "cm_Lock Rejecting lock (code = %d)", code);
      }
  
      return code;
--- 3744,3768 ----
              *lockpp = fileLock;
          }
  
!         if (IS_LOCK_CLIENTONLY(fileLock)) {
!             scp-&gt;clientLocks++;
!         } else if (IS_LOCK_ACCEPTED(fileLock)) {
              if (Which == LockRead)
                  scp-&gt;sharedLocks++;
              else
                  scp-&gt;exclusiveLocks++;
          }
  
!         osi_Log3(afsd_logp,
!                  "cm_Lock Lock added 0x%p flags 0x%x to scp [0x%p]",
!                  fileLock, fileLock-&gt;flags, scp);
          osi_Log4(afsd_logp,
!                  "   exclusives[%d] shared[%d] client[%d] serverLock[%d]",
!                  scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, scp-&gt;clientLocks,
                   (int)(signed char) scp-&gt;serverLock);
      } else {
          osi_Log1(afsd_logp,
!                  "cm_Lock Rejecting lock (code = 0x%x)", code);
      }
  
      return code;
***************
*** 3710,3716 ****
                  scp-&gt;fileLocksT = osi_QPrev(q);
              osi_QRemove(&amp;scp-&gt;fileLocksH,q);
  
!             if (IS_LOCK_ACCEPTED(fileLock)) {
                  if (fileLock-&gt;lockType == LockRead)
                      scp-&gt;sharedLocks--;
                  else
--- 3834,3842 ----
                  scp-&gt;fileLocksT = osi_QPrev(q);
              osi_QRemove(&amp;scp-&gt;fileLocksH,q);
  
!             if (IS_LOCK_CLIENTONLY(fileLock)) {
!                 scp-&gt;clientLocks--;
!             } else if (IS_LOCK_ACCEPTED(fileLock)) {
                  if (fileLock-&gt;lockType == LockRead)
                      scp-&gt;sharedLocks--;
                  else
***************
*** 3743,3748 ****
--- 3869,3875 ----
  
      osi_assertx(scp-&gt;sharedLocks &gt;= 0, "scp-&gt;sharedLocks &lt; 0");
      osi_assertx(scp-&gt;exclusiveLocks &gt;= 0, "scp-&gt;exclusiveLocks &lt; 0");
+     osi_assertx(scp-&gt;clientLocks &gt;= 0, "scp-&gt;clientLocks &lt; 0");
  
      if (!SERVERLOCKS_ENABLED(scp)) {
          osi_Log0(afsd_logp, "  Skipping server lock for scp");
***************
*** 3823,3830 ****
   done:
  
      osi_Log1(afsd_logp, "cm_UnlockByKey code 0x%x", code);
!     osi_Log3(afsd_logp, "   Leaving scp with exclusives[%d], shared[%d], serverLock[%d]",
!              scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, (int)(signed char) scp-&gt;serverLock);
  
      return code;
  }
--- 3950,3958 ----
   done:
  
      osi_Log1(afsd_logp, "cm_UnlockByKey code 0x%x", code);
!     osi_Log4(afsd_logp, "   Leaving scp with excl[%d], shared[%d], client[%d], serverLock[%d]",
!              scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, scp-&gt;clientLocks,
!              (int)(signed char) scp-&gt;serverLock);
  
      return code;
  }
***************
*** 3899,3905 ****
       * the daemon's traversal of the list.
       */
  
!     if (IS_LOCK_ACCEPTED(fileLock)) {
          if (fileLock-&gt;lockType == LockRead)
              scp-&gt;sharedLocks--;
          else
--- 4027,4035 ----
       * the daemon's traversal of the list.
       */
  
!     if (IS_LOCK_CLIENTONLY(fileLock)) {
!         scp-&gt;clientLocks--;
!     } else if (IS_LOCK_ACCEPTED(fileLock)) {
          if (fileLock-&gt;lockType == LockRead)
              scp-&gt;sharedLocks--;
          else
***************
*** 4002,4009 ****
  
   done:
  
!     osi_Log4(afsd_logp, "cm_Unlock code 0x%x leaving scp with exclusives[%d], shared[%d], serverLock[%d]",
!              code, scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, (int)(signed char) scp-&gt;serverLock);
  
      return code;
  }
--- 4132,4141 ----
  
   done:
  
!     osi_Log1(afsd_logp, "cm_Unlock code 0x%x", code);
!     osi_Log4(afsd_logp, "  leaving scp with excl[%d], shared[%d], client[%d], serverLock[%d]",
!              scp-&gt;exclusiveLocks, scp-&gt;sharedLocks, scp-&gt;clientLocks,
!              (int)(signed char) scp-&gt;serverLock);
  
      return code;
  }
***************
*** 4028,4034 ****
          fileLock = 
              (cm_file_lock_t *)((char *) q - offsetof(cm_file_lock_t, fileq));
  
!         if (IS_LOCK_ACTIVE(fileLock)) {
              if (fileLock-&gt;lockType == LockRead)
                  scp-&gt;sharedLocks--;
              else
--- 4160,4167 ----
          fileLock = 
              (cm_file_lock_t *)((char *) q - offsetof(cm_file_lock_t, fileq));
  
!         if (IS_LOCK_ACTIVE(fileLock) &amp;&amp;
!             !IS_LOCK_CLIENTONLY(fileLock)) {
              if (fileLock-&gt;lockType == LockRead)
                  scp-&gt;sharedLocks--;
              else
***************
*** 4263,4268 ****
--- 4396,4402 ----
      osi_queue_t *q;
      cm_req_t req;
      int newLock = -1;
+     int force_client_lock = FALSE;
  
      cm_InitReq(&amp;req);
  
***************
*** 4305,4314 ****
  
      lock_ReleaseRead(&amp;cm_scacheLock);
      lock_ObtainMutex(&amp;scp-&gt;mx);
      lock_ObtainWrite(&amp;cm_scacheLock);
  
      /* Check if we already have a sufficient server lock to allow this
!        lock to go through */
      if (IS_LOCK_WAITLOCK(oldFileLock) &amp;&amp;
         (!SERVERLOCKS_ENABLED(scp) ||
          scp-&gt;serverLock == oldFileLock-&gt;lockType ||
--- 4439,4461 ----
  
      lock_ReleaseRead(&amp;cm_scacheLock);
      lock_ObtainMutex(&amp;scp-&gt;mx);
+ 
+     code = cm_LockCheckPerms(scp, oldFileLock-&gt;lockType,
+                              oldFileLock-&gt;userp,
+                              &amp;req);
+ 
+     if (code == CM_ERROR_NOACCESS &amp;&amp; oldFileLock-&gt;lockType == LockRead) {
+         force_client_lock = TRUE;
+         code = 0;
+     } else if (code) {
+         lock_ReleaseMutex(&amp;scp-&gt;mx);
+         return code;
+     }
+ 
      lock_ObtainWrite(&amp;cm_scacheLock);
  
      /* Check if we already have a sufficient server lock to allow this
!        lock to go through. */
      if (IS_LOCK_WAITLOCK(oldFileLock) &amp;&amp;
         (!SERVERLOCKS_ENABLED(scp) ||
          scp-&gt;serverLock == oldFileLock-&gt;lockType ||
***************
*** 4392,4404 ****
          oldFileLock-&gt;flags |= CM_FILELOCK_FLAG_WAITLOCK;
      }
  
!     if (!SERVERLOCKS_ENABLED(scp) ||
          scp-&gt;serverLock == oldFileLock-&gt;lockType ||
          (oldFileLock-&gt;lockType == LockRead &amp;&amp;
           scp-&gt;serverLock == LockWrite)) {
  
          oldFileLock-&gt;flags &amp;= ~CM_FILELOCK_FLAG_WAITLOCK;
  
          lock_ReleaseWrite(&amp;cm_scacheLock);
          lock_ReleaseMutex(&amp;scp-&gt;mx);
  
--- 4539,4566 ----
          oldFileLock-&gt;flags |= CM_FILELOCK_FLAG_WAITLOCK;
      }
  
!     if (force_client_lock ||
!         !SERVERLOCKS_ENABLED(scp) ||
          scp-&gt;serverLock == oldFileLock-&gt;lockType ||
          (oldFileLock-&gt;lockType == LockRead &amp;&amp;
           scp-&gt;serverLock == LockWrite)) {
  
          oldFileLock-&gt;flags &amp;= ~CM_FILELOCK_FLAG_WAITLOCK;
  
+         if ((force_client_lock ||
+              !SERVERLOCKS_ENABLED(scp)) &amp;&amp;
+             !IS_LOCK_CLIENTONLY(oldFileLock)) {
+ 
+             oldFileLock-&gt;flags |= CM_FILELOCK_FLAG_CLIENTONLY;
+ 
+             if (oldFileLock-&gt;lockType == LockRead)
+                 scp-&gt;sharedLocks--;
+             else
+                 scp-&gt;exclusiveLocks--;
+ 
+             scp-&gt;clientLocks++;
+         }
+ 
          lock_ReleaseWrite(&amp;cm_scacheLock);
          lock_ReleaseMutex(&amp;scp-&gt;mx);
  
***************
*** 4498,4504 ****
      cm_user_t *userp;
      cm_key_t   key;
      cm_file_lock_t *fileLock;
!     int i;
  
      for (i = 0; i &lt; cm_data.hashTableSize; i++)
      {
--- 4660,4666 ----
      cm_user_t *userp;
      cm_key_t   key;
      cm_file_lock_t *fileLock;
!     unsigned int i;
  
      for (i = 0; i &lt; cm_data.hashTableSize; i++)
      {
Index: openafs/src/WINNT/afsd/fs_utils.c
diff -c openafs/src/WINNT/afsd/fs_utils.c:1.9 openafs/src/WINNT/afsd/fs_utils.c:1.10
*** openafs/src/WINNT/afsd/fs_utils.c:1.9	Fri Mar 11 00:33:23 2005
--- openafs/src/WINNT/afsd/fs_utils.c	Sat Mar  4 16:39:25 2006
***************
*** 121,157 ****
      return 0;
  }
  
- #ifdef COMMENT
- struct hostent *hostutil_GetHostByName(char *namep)
- {
- 	struct hostent *thp;
-         
-         thp = gethostbyname(namep);
-         return thp;
- }
- 
- /* get hostname or addr, given addr in network byte order */
- char *hostutil_GetNameByINet(afs_uint32 addr)
- {
- 	static char hostNameBuffer[256];
-         struct hostent *thp;
-         
-         thp = gethostbyaddr((char *) &amp;addr, sizeof(afs_uint32), AF_INET);
-         if (thp)
-         	strcpy(hostNameBuffer, thp-&gt;h_name);
- 	else {
- 		sprintf(hostNameBuffer, "%d.%d.%d.%d",
-                 	addr &amp; 0xff,
-                         (addr &gt;&gt; 8) &amp; 0xff,
-                         (addr &gt;&gt; 16) &amp; 0xff,
-                         (addr &gt;&gt; 24) &amp; 0xff);
-         }
- 
- 	/* return static buffer */
-         return hostNameBuffer;
- }
- #endif
- 
  /* is this a digit or a digit-like thing? */
  static int ismeta(ac, abase)
  register int abase;
--- 121,126 ----
Index: openafs/src/WINNT/afsd/lanahelper.cpp
diff -c openafs/src/WINNT/afsd/lanahelper.cpp:1.11 openafs/src/WINNT/afsd/lanahelper.cpp:1.12
*** openafs/src/WINNT/afsd/lanahelper.cpp:1.11	Fri Mar 11 13:16:47 2005
--- openafs/src/WINNT/afsd/lanahelper.cpp	Fri Apr 21 23:45:47 2006
***************
*** 435,440 ****
--- 435,441 ----
          NAME_BUFFER names[MAX_LANA+1];
      } astat;
      unsigned char kWLA_MAC[6] = { 0x02, 0x00, 0x4c, 0x4f, 0x4f, 0x50 };
+     unsigned char kVista_WLA_MAC[6] = { 0x7F, 0x00, 0x00, 0x01, 0x4f, 0x50 };
      int status;
      HKEY hkConfig;
      LONG rv;
***************
*** 483,489 ****
  #endif
          return FALSE;
      }
!     return (memcmp(astat.status.adapter_address, kWLA_MAC, 6) == 0);
  }
  
  // Get the netbios named used/to-be-used by the AFS SMB server.
--- 484,491 ----
  #endif
          return FALSE;
      }
!     return (memcmp(astat.status.adapter_address, kWLA_MAC, 6) == 0 ||
! 	    memcmp(astat.status.adapter_address, kVista_WLA_MAC, 6) == 0);
  }
  
  // Get the netbios named used/to-be-used by the AFS SMB server.
Index: openafs/src/WINNT/afsd/smb.c
diff -c openafs/src/WINNT/afsd/smb.c:1.112 openafs/src/WINNT/afsd/smb.c:1.118
*** openafs/src/WINNT/afsd/smb.c:1.112	Thu Feb 16 17:06:02 2006
--- openafs/src/WINNT/afsd/smb.c	Thu Apr 27 11:49:55 2006
***************
*** 38,45 ****
  static char *illegalChars = "\\/:*?\"&lt;&gt;|";
  BOOL isWindows2000 = FALSE;
  
- smb_vc_t *active_vcp = NULL;
- 
  int smbShutdownFlag = 0;
  
  int smb_LogoffTokenTransfer;
--- 38,43 ----
***************
*** 795,801 ****
      struct tm localJunk;
      time_t t = unixTime;
  
!     ltp = localtime((time_t*) &amp;t);
  
      /* if we fail, make up something */
      if (!ltp) {
--- 793,799 ----
      struct tm localJunk;
      time_t t = unixTime;
  
!     ltp = localtime(&amp;t);
  
      /* if we fail, make up something */
      if (!ltp) {
***************
*** 858,863 ****
--- 856,865 ----
  
      lock_ObtainWrite(&amp;smb_rctLock);
      for (vcp = smb_allVCsp; vcp; vcp=vcp-&gt;nextp) {
+ 	if (vcp-&gt;magic != SMB_VC_MAGIC)
+ 	    osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp", 
+ 		       __FILE__, __LINE__);
+ 
          if (lsn == vcp-&gt;lsn &amp;&amp; lana == vcp-&gt;lana) {
              smb_HoldVCNoLock(vcp);
              break;
***************
*** 869,874 ****
--- 871,877 ----
  	lock_ObtainWrite(&amp;smb_globalLock);
          vcp-&gt;vcID = ++numVCs;
  	lock_ReleaseWrite(&amp;smb_globalLock);
+ 	vcp-&gt;magic = SMB_VC_MAGIC;
          vcp-&gt;refCount = 2; 	/* smb_allVCsp and caller */
          vcp-&gt;tidCounter = 1;
          vcp-&gt;fidCounter = 1;
***************
*** 936,959 ****
  void smb_ReleaseVCInternal(smb_vc_t *vcp)
  {
      smb_vc_t **vcpp;
  
- #ifdef DEBUG
-     osi_assert(vcp-&gt;refCount-- != 0);
- #else
      vcp-&gt;refCount--;
- #endif
  
      if (vcp-&gt;refCount == 0) {
  	/* remove VCP from smb_deadVCsp */
  	for (vcpp = &amp;smb_deadVCsp; *vcpp; vcpp = &amp;((*vcpp)-&gt;nextp)) {
! 	    if (*vcpp == vcp) {
! 		*vcpp = vcp-&gt;nextp;
! 		break;
! 	    }
  	} 
  	lock_FinalizeMutex(&amp;vcp-&gt;mx);
  	memset(vcp,0,sizeof(smb_vc_t));
  	free(vcp);
      }
  }
  
--- 939,978 ----
  void smb_ReleaseVCInternal(smb_vc_t *vcp)
  {
      smb_vc_t **vcpp;
+     smb_vc_t * avcp;
  
      vcp-&gt;refCount--;
  
      if (vcp-&gt;refCount == 0) {
+       if (vcp-&gt;flags &amp; SMB_VCFLAG_ALREADYDEAD) {
  	/* remove VCP from smb_deadVCsp */
  	for (vcpp = &amp;smb_deadVCsp; *vcpp; vcpp = &amp;((*vcpp)-&gt;nextp)) {
! 	  if (*vcpp == vcp) {
! 	    *vcpp = vcp-&gt;nextp;
! 	    break;
! 	  }
  	} 
  	lock_FinalizeMutex(&amp;vcp-&gt;mx);
  	memset(vcp,0,sizeof(smb_vc_t));
  	free(vcp);
+       } else {
+ 	for (avcp = smb_allVCsp; avcp; avcp = avcp-&gt;nextp) {
+ 	  if (avcp == vcp)
+ 	    break;
+ 	}
+ 	osi_Log3(smb_logp,"VCP not dead and %sin smb_allVCsp vcp %x ref %d",
+ 		 avcp?"not ":"",vcp, vcp-&gt;refCount);
+ #ifdef DEBUG
+ 	GenerateMiniDump(NULL);
+ #endif
+ 	/* This is a wrong.  However, I suspect that there is an undercount
+ 	 * and I don't want to release 1.4.1 in a state that will allow
+ 	 * smb_vc_t objects to be deallocated while still in the
+ 	 * smb_allVCsp list.  The list is supposed to keep a reference
+ 	 * to the smb_vc_t.  Put it back.
+ 	 */
+ 	vcp-&gt;refCount++;
+       }
      }
  }
  
***************
*** 997,1005 ****
--- 1016,1047 ----
      smb_user_t *uidpNext;
      smb_vc_t **vcpp;
  
+ 
+     lock_ObtainMutex(&amp;vcp-&gt;mx);
+     if (vcp-&gt;flags &amp; SMB_VCFLAG_CLEAN_IN_PROGRESS) {
+ 	lock_ReleaseMutex(&amp;vcp-&gt;mx);
+ 	osi_Log1(smb_logp, "Clean of dead vcp 0x%x in progress", vcp);
+ 	return;
+     }
+     vcp-&gt;flags |= SMB_VCFLAG_CLEAN_IN_PROGRESS;
+     lock_ReleaseMutex(&amp;vcp-&gt;mx);
      osi_Log1(smb_logp, "Cleaning up dead vcp 0x%x", vcp);
  
      lock_ObtainWrite(&amp;smb_rctLock);
+     /* remove VCP from smb_allVCsp */
+     for (vcpp = &amp;smb_allVCsp; *vcpp; vcpp = &amp;((*vcpp)-&gt;nextp)) {
+ 	if ((*vcpp)-&gt;magic != SMB_VC_MAGIC)
+ 	    osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp", 
+ 		       __FILE__, __LINE__);
+         if (*vcpp == vcp) {
+             *vcpp = vcp-&gt;nextp;
+             vcp-&gt;nextp = smb_deadVCsp;
+             smb_deadVCsp = vcp;
+ 	    /* Hold onto the reference until we are done with this function */
+             break;
+         }
+     }
+ 
      for (fidpIter = vcp-&gt;fidsp; fidpIter; fidpIter = fidpNext) {
          fidpNext = (smb_fid_t *) osi_QNext(&amp;fidpIter-&gt;q);
  
***************
*** 1053,1073 ****
  	uidpNext = vcp-&gt;usersp;
      }
  
!     /* remove VCP from smb_allVCsp */
!     for (vcpp = &amp;smb_allVCsp; *vcpp; vcpp = &amp;((*vcpp)-&gt;nextp)) {
! 	if (*vcpp == vcp) {
! 	    *vcpp = vcp-&gt;nextp;
! 	    vcp-&gt;nextp = smb_deadVCsp;
! 	    smb_deadVCsp = vcp;
! 	    /* We intentionally do not keep a reference to the 
! 	     * vcp once it is placed on the deadVCsp list.  This
! 	     * allows the refcount to reach 0 so we can delete
! 	     * it. */
! 	    smb_ReleaseVCNoLock(vcp);
! 	    break;
! 	}
!     } 
      lock_ReleaseWrite(&amp;smb_rctLock);
      osi_Log1(smb_logp, "Finished cleaning up dead vcp 0x%x", vcp);
  }
  
--- 1095,1109 ----
  	uidpNext = vcp-&gt;usersp;
      }
  
! 
!     /* The vcp is now on the deadVCsp list.  We intentionally drop the
!      * reference so that the refcount can reach 0 and we can delete it */
!     smb_ReleaseVCNoLock(vcp);
!     
      lock_ReleaseWrite(&amp;smb_rctLock);
+     lock_ObtainMutex(&amp;vcp-&gt;mx);
+     vcp-&gt;flags &amp;= ~SMB_VCFLAG_CLEAN_IN_PROGRESS;
+     lock_ReleaseMutex(&amp;vcp-&gt;mx);
      osi_Log1(smb_logp, "Finished cleaning up dead vcp 0x%x", vcp);
  }
  
***************
*** 3255,3260 ****
--- 3291,3300 ----
      lock_ObtainWrite(&amp;smb_rctLock);
      for ( vcp=smb_allVCsp, nextp=NULL; vcp; vcp = nextp ) 
      {
+ 	if (vcp-&gt;magic != SMB_VC_MAGIC)
+ 	    osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp", 
+ 		       __FILE__, __LINE__);
+ 
  	nextp = vcp-&gt;nextp;
  
  	if (vcp-&gt;flags &amp; SMB_VCFLAG_ALREADYDEAD)
***************
*** 5409,5415 ****
      /* now create the hardlink */
      osi_Log1(smb_logp,"  Attempting to create new link [%s]", osi_LogSaveString(smb_logp, newLastNamep));
      code = cm_Link(newDscp, newLastNamep, sscp, 0, userp, &amp;req);
!     osi_Log1(smb_logp,"  Link returns %d", code);
  
      /* Handle Change Notification */
      if (code == 0) {
--- 5449,5455 ----
      /* now create the hardlink */
      osi_Log1(smb_logp,"  Attempting to create new link [%s]", osi_LogSaveString(smb_logp, newLastNamep));
      code = cm_Link(newDscp, newLastNamep, sscp, 0, userp, &amp;req);
!     osi_Log1(smb_logp,"  Link returns 0x%x", code);
  
      /* Handle Change Notification */
      if (code == 0) {
***************
*** 5789,5794 ****
--- 5829,5844 ----
  	fidp-&gt;flags &amp;= ~SMB_FID_DELONCLOSE;
      }
  
+     /* if this was a newly created file, then clear the creator
+      * in the stat cache entry. */
+     if (fidp-&gt;flags &amp; SMB_FID_CREATED) {
+         lock_ObtainMutex(&amp;fidp-&gt;scp-&gt;mx);
+ 	if (fidp-&gt;scp-&gt;creator == userp)
+ 	    fidp-&gt;scp-&gt;creator = NULL;
+ 	lock_ReleaseMutex(&amp;fidp-&gt;scp-&gt;mx);
+ 	fidp-&gt;flags &amp;= ~SMB_FID_CREATED;
+     }
+ 
      if (fidp-&gt;flags &amp; SMB_FID_NTOPEN) {
  	fidp-&gt;NTopen_dscp = NULL;
          fidp-&gt;NTopen_pathp = NULL;
***************
*** 6044,6050 ****
          
      /* make sure we have a writable FD */
      if (!(fidp-&gt;flags &amp; SMB_FID_OPENWRITE)) {
! 	lock_ReleaseMutex(&amp;fidp-&gt;mx);
          code = CM_ERROR_BADFDOP;
          goto done;
      }
--- 6094,6101 ----
          
      /* make sure we have a writable FD */
      if (!(fidp-&gt;flags &amp; SMB_FID_OPENWRITE)) {
! 	osi_Log2(smb_logp, "smb_WriteData fid %d not OPENWRITE flags 0x%x",
! 		  fidp-&gt;fid, fidp-&gt;flags);
          code = CM_ERROR_BADFDOP;
          goto done;
      }
***************
*** 6229,6242 ****
          osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE",
                    fidp-&gt;fid);
          code2 = cm_SyncOp(scp, NULL, userp, &amp;req, 0, CM_SCACHESYNC_ASYNCSTORE);
!         osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns %d",
!                   fidp-&gt;fid,code2);
          lock_ReleaseMutex(&amp;scp-&gt;mx);
          cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
                              writeBackOffset.HighPart, cm_chunkSize, 0, userp);
      }
  
!     osi_Log3(smb_logp, "smb_WriteData fid %d returns %d written %d",
                fidp-&gt;fid, code, *writtenp);
      return code;
  }
--- 6280,6293 ----
          osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE",
                    fidp-&gt;fid);
          code2 = cm_SyncOp(scp, NULL, userp, &amp;req, 0, CM_SCACHESYNC_ASYNCSTORE);
!         osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x",
!                   fidp-&gt;fid, code2);
          lock_ReleaseMutex(&amp;scp-&gt;mx);
          cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
                              writeBackOffset.HighPart, cm_chunkSize, 0, userp);
      }
  
!     osi_Log3(smb_logp, "smb_WriteData fid %d returns 0x%x written %d bytes",
                fidp-&gt;fid, code, *writtenp);
      return code;
  }
***************
*** 6818,6823 ****
--- 6869,6875 ----
      afs_uint32 dosTime;
      char *tidPathp;
      cm_req_t req;
+     int created = 0;			/* the file was new */
  
      cm_InitReq(&amp;req);
  
***************
*** 6917,6927 ****
          smb_UnixTimeFromDosUTime(&amp;setAttr.clientModTime, dosTime);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp,
                           &amp;req);
!         if (code == 0 &amp;&amp; (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH))
!             smb_NotifyChange(FILE_ACTION_ADDED,
!                              FILE_NOTIFY_CHANGE_FILE_NAME,
!                              dscp, lastNamep, NULL, TRUE);
!         if (!excl &amp;&amp; code == CM_ERROR_EXISTS) {
              /* not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
--- 6969,6981 ----
          smb_UnixTimeFromDosUTime(&amp;setAttr.clientModTime, dosTime);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp,
                           &amp;req);
!         if (code == 0) {
! 	    created = 1;
! 	    if (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH)
! 		smb_NotifyChange(FILE_ACTION_ADDED,	
! 				 FILE_NOTIFY_CHANGE_FILE_NAME,
! 				 dscp, lastNamep, NULL, TRUE);
! 	} else if (!excl &amp;&amp; code == CM_ERROR_EXISTS) {
              /* not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
***************
*** 6966,6971 ****
--- 7020,7029 ----
      /* always create it open for read/write */
      fidp-&gt;flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
  
+     /* remember that the file was newly created */
+     if (created)
+ 	fidp-&gt;flags |= SMB_FID_CREATED;
+ 
      /* save a pointer to the vnode */
      fidp-&gt;scp = scp;
      /* and the user */
***************
*** 7296,7320 ****
          smb_SendPacket(vcp, outp);
      thrd_Decrement(&amp;ongoingOps);
  
-     if (!(vcp-&gt;flags &amp; SMB_VCFLAG_ALREADYDEAD)) {
-         if (active_vcp != vcp) {
-             if (active_vcp) {
-                 osi_Log2(smb_logp,
-                       "Replacing active_vcp %x with %x", active_vcp, vcp);
-                 smb_ReleaseVC(active_vcp);
-             }
-             smb_HoldVC(vcp);
- 	    lock_ObtainWrite(&amp;smb_globalLock);
-             active_vcp = vcp;
- 	    lock_ReleaseWrite(&amp;smb_globalLock);
-         }
-         last_msg_time = GetTickCount();
-     } else if (active_vcp == vcp) { 	/* the vcp is dead */
-         smb_ReleaseVC(active_vcp);
- 	lock_ObtainWrite(&amp;smb_globalLock);
-         active_vcp = NULL;
- 	lock_ReleaseWrite(&amp;smb_globalLock);
-     }
      return;
  }
  
--- 7354,7359 ----
***************
*** 8804,8810 ****
          smb_fid_t *fidp;
          smb_tid_t *tidp;
       
!         for (fidp = vcp-&gt;fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&amp;fidp-&gt;q))
          {
              if (fidp-&gt;scp != NULL) {
                  cm_scache_t * scp;
--- 8843,8853 ----
          smb_fid_t *fidp;
          smb_tid_t *tidp;
       
! 	if (vcp-&gt;magic != SMB_VC_MAGIC)
! 	    osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp", 
! 		       __FILE__, __LINE__);
! 
! 	for (fidp = vcp-&gt;fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&amp;fidp-&gt;q))
          {
              if (fidp-&gt;scp != NULL) {
                  cm_scache_t * scp;
***************
*** 8907,8913 ****
  
          *cp = 0;
  
!         osi_Log0( smb_logp, osi_LogSaveString(smb_logp, buf));
      }
  
      osi_Log0(smb_logp, "*** End SMB packet dump ***");
--- 8950,8956 ----
  
          *cp = 0;
  
!         osi_Log1( smb_logp, "%s", osi_LogSaveString(smb_logp, buf));
      }
  
      osi_Log0(smb_logp, "*** End SMB packet dump ***");
Index: openafs/src/WINNT/afsd/smb.h
diff -c openafs/src/WINNT/afsd/smb.h:1.38 openafs/src/WINNT/afsd/smb.h:1.41
*** openafs/src/WINNT/afsd/smb.h:1.38	Thu Feb 16 17:06:02 2006
--- openafs/src/WINNT/afsd/smb.h	Thu Apr 27 11:49:56 2006
***************
*** 192,197 ****
--- 192,198 ----
  /* one per virtual circuit */
  typedef struct smb_vc {
      struct smb_vc *nextp;		/* not used */
+     afs_uint32 magic;			/* a magic value to detect bad entries */
      unsigned long refCount;		/* the reference count */
      long flags;			        /* the flags, if any; locked by mx */
      osi_mutex_t mx;			/* the mutex */
***************
*** 213,218 ****
--- 214,220 ----
      unsigned short session;		/* This is the Session Index associated with the NCBs */
  } smb_vc_t;
  
+ #define SMB_VC_MAGIC ('S' | 'C'&lt;&lt;8 | 'A'&lt;&lt;16 | 'C'&lt;&lt;24)
  					/* have we negotiated ... */
  #define SMB_VCFLAG_USEV3	1	/* ... version 3 of the protocol */
  #define SMB_VCFLAG_USECORE	2	/* ... the core protocol */
***************
*** 222,227 ****
--- 224,230 ----
  #define SMB_VCFLAG_ALREADYDEAD	0x20	/* do not get tokens from this vc */
  #define SMB_VCFLAG_SESSX_RCVD	0x40	/* we received at least one session setups on this vc */
  #define SMB_VCFLAG_AUTH_IN_PROGRESS 0x80 /* a SMB NT extended authentication is in progress */
+ #define SMB_VCFLAG_CLEAN_IN_PROGRESS 0x100
  
  /* one per user session */
  typedef struct smb_user {
***************
*** 356,362 ****
  
  #define SMB_FID_OPENREAD		1	/* open for reading */
  #define SMB_FID_OPENWRITE		2	/* open for writing */
! #define SMB_FID_UNUSED                  4       /* free for use */
  #define SMB_FID_IOCTL			8	/* a file descriptor for the
  						 * magic ioctl file */
  #define SMB_FID_OPENDELETE		0x10	/* open for deletion (NT) */
--- 359,365 ----
  
  #define SMB_FID_OPENREAD		1	/* open for reading */
  #define SMB_FID_OPENWRITE		2	/* open for writing */
! #define SMB_FID_CREATED                 4       /* a new file */
  #define SMB_FID_IOCTL			8	/* a file descriptor for the
  						 * magic ioctl file */
  #define SMB_FID_OPENDELETE		0x10	/* open for deletion (NT) */
Index: openafs/src/WINNT/afsd/smb3.c
diff -c openafs/src/WINNT/afsd/smb3.c:1.91 openafs/src/WINNT/afsd/smb3.c:1.94
*** openafs/src/WINNT/afsd/smb3.c:1.91	Thu Feb 16 17:06:02 2006
--- openafs/src/WINNT/afsd/smb3.c	Thu Apr 27 11:49:56 2006
***************
*** 1481,1490 ****
      int outDataTotal;	/* total data bytes */
      int code = 0;
      DWORD rv;
!     DWORD allSubmount;
!     USHORT nShares;
!     DWORD nRegShares;
!     DWORD nSharesRet;
      HKEY hkParam;
      HKEY hkSubmount = NULL;
      smb_rap_share_info_1_t * shares;
--- 1481,1490 ----
      int outDataTotal;	/* total data bytes */
      int code = 0;
      DWORD rv;
!     DWORD allSubmount = 0;
!     USHORT nShares = 0;
!     DWORD nRegShares = 0;
!     DWORD nSharesRet = 0;
      HKEY hkParam;
      HKEY hkSubmount = NULL;
      smb_rap_share_info_1_t * shares;
***************
*** 2062,2067 ****
--- 2062,2068 ----
      long returnEALength;
      char *tidPathp;
      cm_req_t req;
+     int created = 0;
  
      cm_InitReq(&amp;req);
  
***************
*** 2280,2290 ****
          smb_UnixTimeFromSearchTime(&amp;setAttr.clientModTime, dosTime);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp,
                            &amp;req);
!         if (code == 0 &amp;&amp; (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH))
!             smb_NotifyChange(FILE_ACTION_ADDED,
!                              FILE_NOTIFY_CHANGE_FILE_NAME,  
!                              dscp, lastNamep, NULL, TRUE);
!         if (!excl &amp;&amp; code == CM_ERROR_EXISTS) {
              /* not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
--- 2281,2293 ----
          smb_UnixTimeFromSearchTime(&amp;setAttr.clientModTime, dosTime);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp,
                            &amp;req);
!         if (code == 0) {
! 	    created = 1;
! 	    if (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH)
! 		smb_NotifyChange(FILE_ACTION_ADDED,
! 				 FILE_NOTIFY_CHANGE_FILE_NAME,  
! 				  dscp, lastNamep, NULL, TRUE);
! 	} else if (!excl &amp;&amp; code == CM_ERROR_EXISTS) {
              /* not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
***************
*** 2359,2364 ****
--- 2362,2372 ----
  	fidp-&gt;flags |= SMB_FID_OPENREAD;
      if (openMode == 1 || openMode == 2)
          fidp-&gt;flags |= SMB_FID_OPENWRITE;
+ 
+     /* remember that the file was newly created */
+     if (created)
+ 	fidp-&gt;flags |= SMB_FID_CREATED;
+ 
      lock_ReleaseMutex(&amp;fidp-&gt;mx);
  
      smb_ReleaseFID(fidp);
***************
*** 2428,2440 ****
      switch (p-&gt;parmsp[0]) {
      case 1: responseSize = sizeof(qi.u.allocInfo); break;
      case 2: responseSize = sizeof(qi.u.volumeInfo); break;
      case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break;
      case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break;
      case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break;
      case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break;
      case 0x200: /* CIFS Unix Info */
      case 0x301: /* Mac FS Info */
!     default: return CM_ERROR_INVAL;
      }
  
      outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize);
--- 2436,2450 ----
      switch (p-&gt;parmsp[0]) {
      case 1: responseSize = sizeof(qi.u.allocInfo); break;
      case 2: responseSize = sizeof(qi.u.volumeInfo); break;
+     	break;
      case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break;
      case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break;
      case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break;
      case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break;
      case 0x200: /* CIFS Unix Info */
      case 0x301: /* Mac FS Info */
!     default: 
! 	return CM_ERROR_INVAL;
      }
  
      outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize);
***************
*** 2899,2904 ****
--- 2909,2915 ----
      	goto done;
      }   
  
+     lock_ObtainMutex(&amp;fidp-&gt;mx);
      scp = fidp-&gt;scp;
      lock_ObtainMutex(&amp;scp-&gt;mx);
      code = cm_SyncOp(scp, NULL, userp, &amp;req, 0,
***************
*** 2924,2932 ****
          *((LARGE_INTEGER *)op) = scp-&gt;length; op += 8;	/* alloc size */
          *((LARGE_INTEGER *)op) = scp-&gt;length; op += 8;	/* EOF */
          *((u_long *)op) = scp-&gt;linkCount; op += 4;
- 	lock_ObtainMutex(&amp;fidp-&gt;mx);
          *op++ = ((fidp-&gt;flags &amp; SMB_FID_DELONCLOSE) ? 1 : 0);
- 	lock_ReleaseMutex(&amp;fidp-&gt;mx);
          *op++ = (scp-&gt;fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0);
          *op++ = 0;
          *op++ = 0;
--- 2935,2941 ----
***************
*** 2951,2956 ****
--- 2960,2966 ----
      /* send and free the packets */
    done:
      lock_ReleaseMutex(&amp;scp-&gt;mx);
+     lock_ReleaseMutex(&amp;fidp-&gt;mx);
      cm_ReleaseUser(userp);
      smb_ReleaseFID(fidp);
      if (code == 0) 
***************
*** 2984,2990 ****
      }
  
      infoLevel = p-&gt;parmsp[1];
!     osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type=[%x] fid=[%x]", infoLevel, fid);
      if (infoLevel &gt; 0x104 || infoLevel &lt; 0x101) {
          osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
                    p-&gt;opcode, infoLevel);
--- 2994,3000 ----
      }
  
      infoLevel = p-&gt;parmsp[1];
!     osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type 0x%x fid %d", infoLevel, fid);
      if (infoLevel &gt; 0x104 || infoLevel &lt; 0x101) {
          osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
                    p-&gt;opcode, infoLevel);
***************
*** 3033,3038 ****
--- 3043,3049 ----
          /* lock the vnode with a callback; we need the current status
           * to determine what the new status is, in some cases.
           */
+ 	lock_ObtainMutex(&amp;fidp-&gt;mx);
          lock_ObtainMutex(&amp;scp-&gt;mx);
          code = cm_SyncOp(scp, NULL, userp, &amp;req, 0,
                            CM_SCACHESYNC_GETSTATUS
***************
*** 3054,3062 ****
               lastMod.dwLowDateTime != -1 &amp;&amp; lastMod.dwHighDateTime != -1) {
              attr.mask |= CM_ATTRMASK_CLIENTMODTIME;
              smb_UnixTimeFromLargeSearchTime(&amp;attr.clientModTime, &amp;lastMod);
- 	    lock_ObtainMutex(&amp;fidp-&gt;mx);
              fidp-&gt;flags |= SMB_FID_MTIMESETDONE;
- 	    lock_ReleaseMutex(&amp;fidp-&gt;mx);
          }
  		
          attribute = *((u_long *)(p-&gt;datap + 32));
--- 3065,3071 ----
***************
*** 3075,3080 ****
--- 3084,3090 ----
              }
          }
          lock_ReleaseMutex(&amp;scp-&gt;mx);
+ 	lock_ReleaseMutex(&amp;fidp-&gt;mx);
  
          /* call setattr */
          if (attr.mask)
***************
*** 4515,4520 ****
--- 4525,4531 ----
      int parmSlot;			/* which parm we're dealing with */
      char *tidPathp;
      cm_req_t req;
+     int created = 0;
  
      cm_InitReq(&amp;req);
  
***************
*** 4697,4707 ****
          smb_UnixTimeFromDosUTime(&amp;setAttr.clientModTime, dosTime);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp,
                           &amp;req);
!         if (code == 0 &amp;&amp; (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH))
!             smb_NotifyChange(FILE_ACTION_ADDED,
!                              FILE_NOTIFY_CHANGE_FILE_NAME,
!                              dscp, lastNamep, NULL, TRUE);
!         if (!excl &amp;&amp; code == CM_ERROR_EXISTS) {
              /* not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
--- 4708,4720 ----
          smb_UnixTimeFromDosUTime(&amp;setAttr.clientModTime, dosTime);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp,
                           &amp;req);
!         if (code == 0) {
! 	    created = 1;
! 	    if (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH)
! 		smb_NotifyChange(FILE_ACTION_ADDED,
! 				 FILE_NOTIFY_CHANGE_FILE_NAME,
! 				 dscp, lastNamep, NULL, TRUE);
! 	} else if (!excl &amp;&amp; code == CM_ERROR_EXISTS) {
              /* not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
***************
*** 4757,4762 ****
--- 4770,4779 ----
      if (openMode == 1 || openMode == 2)
          fidp-&gt;flags |= SMB_FID_OPENWRITE;
  
+     /* remember if the file was newly created */
+     if (created)
+ 	fidp-&gt;flags |= SMB_FID_CREATED;
+ 
      lock_ReleaseMutex(&amp;fidp-&gt;mx);
      smb_ReleaseFID(fidp);
          
***************
*** 5366,5371 ****
--- 5383,5389 ----
      char *tidPathp;
      BOOL foundscp;
      cm_req_t req;
+     int created = 0;
  
      cm_InitReq(&amp;req);
  
***************
*** 5539,5544 ****
--- 5557,5563 ----
      if (shareAccess &amp; FILE_SHARE_WRITE)
          fidflags |= SMB_FID_SHARE_WRITE;
  
+     osi_Log1(smb_logp, "NTCreateX fidflags 0x%x", fidflags);
      code = 0;
  
      /* For an exclusive create, we want to do a case sensitive match for the last component. */
***************
*** 5798,5808 ****
          setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
          setAttr.clientModTime = time(NULL);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp, &amp;req);
!         if (code == 0 &amp;&amp; (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH))
!             smb_NotifyChange(FILE_ACTION_ADDED,
!                               FILE_NOTIFY_CHANGE_FILE_NAME,
!                               dscp, lastNamep, NULL, TRUE);
!         if (code == CM_ERROR_EXISTS &amp;&amp; createDisp != FILE_CREATE) {
              /* Not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
--- 5817,5829 ----
          setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
          setAttr.clientModTime = time(NULL);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp, &amp;req);
!         if (code == 0) {
! 	    created = 1;
! 	    if (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH)
! 		smb_NotifyChange(FILE_ACTION_ADDED,
! 				 FILE_NOTIFY_CHANGE_FILE_NAME,
! 				 dscp, lastNamep, NULL, TRUE);
! 	} else if (code == CM_ERROR_EXISTS &amp;&amp; createDisp != FILE_CREATE) {
              /* Not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
***************
*** 6027,6032 ****
--- 6048,6057 ----
  
      fidp-&gt;flags = fidflags;
  
+     /* remember if the file was newly created */
+     if (created)
+ 	fidp-&gt;flags |= SMB_FID_CREATED;
+ 
      /* save parent dir and pathname for delete or change notification */
      if (fidflags &amp; (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
          fidp-&gt;flags |= SMB_FID_NTOPEN;
***************
*** 6133,6138 ****
--- 6158,6164 ----
      ULONG *lparmp;
      char *outData;
      cm_req_t req;
+     int created = 0;
  
      cm_InitReq(&amp;req);
  
***************
*** 6466,6476 ****
          setAttr.clientModTime = time(NULL);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp,
                            &amp;req);
!         if (code == 0 &amp;&amp; (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH))
!             smb_NotifyChange(FILE_ACTION_ADDED,
!                               FILE_NOTIFY_CHANGE_FILE_NAME,
!                               dscp, lastNamep, NULL, TRUE);
!         if (code == CM_ERROR_EXISTS &amp;&amp; createDisp != FILE_CREATE) {
              /* Not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
--- 6492,6504 ----
          setAttr.clientModTime = time(NULL);
          code = cm_Create(dscp, lastNamep, 0, &amp;setAttr, &amp;scp, userp,
                            &amp;req);
!         if (code == 0) {
! 	    created = 1;
! 	    if (dscp-&gt;flags &amp; CM_SCACHEFLAG_ANYWATCH)
! 		smb_NotifyChange(FILE_ACTION_ADDED,
! 				 FILE_NOTIFY_CHANGE_FILE_NAME,
! 				 dscp, lastNamep, NULL, TRUE);
! 	} else if (code == CM_ERROR_EXISTS &amp;&amp; createDisp != FILE_CREATE) {
              /* Not an exclusive create, and someone else tried
               * creating it already, then we open it anyway.  We
               * don't bother retrying after this, since if this next
***************
*** 6627,6632 ****
--- 6655,6664 ----
  
      fidp-&gt;flags = fidflags;
  
+     /* remember if the file was newly created */
+     if (created)
+ 	fidp-&gt;flags |= SMB_FID_CREATED;
+ 
      /* save parent dir and pathname for deletion or change notification */
      if (fidflags &amp; (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
          fidp-&gt;flags |= SMB_FID_NTOPEN;
Index: openafs/src/WINNT/afsd/smb3.h
diff -c openafs/src/WINNT/afsd/smb3.h:1.11 openafs/src/WINNT/afsd/smb3.h:1.12
*** openafs/src/WINNT/afsd/smb3.h:1.11	Thu Jan 19 18:07:51 2006
--- openafs/src/WINNT/afsd/smb3.h	Thu Apr 27 11:49:56 2006
***************
*** 44,83 ****
      union {
  #pragma pack(push, 2)
          struct {
!             long FSID;			/* file system ID */
!             long sectorsPerAllocUnit;
!             long totalAllocUnits;		/* on the disk */
!             long availAllocUnits;		/* free blocks */
              unsigned short bytesPerSector;	/* bytes per sector */
          } allocInfo;
  #pragma pack(pop)
          struct {
!             long vsn;	        /* volume serial number */
              char vnCount;	/* count of chars in label, incl null */
              char label[12];	/* pad out with nulls */
          } volumeInfo;
          struct {
!             FILETIME vct;	/* volume creation time */
!             long vsn;	        /* volume serial number */
!             long vnCount;	/* length of volume label in bytes */
!             char res[2];	/* reserved */
!             char label[10];	/* volume label */
          } FSvolumeInfo;
          struct {
              osi_hyper_t totalAllocUnits;	/* on the disk */
              osi_hyper_t availAllocUnits;	/* free blocks */
!             long sectorsPerAllocUnit;
!             long bytesPerSector;		/* bytes per sector */
          } FSsizeInfo;
          struct {
!             long devType;	/* device type */
!             long characteristics;
          } FSdeviceInfo;
          struct {
!             long attributes;
!             long maxCompLength;	/* max path component length */
!             long FSnameLength;	/* length of file system name */
!             char FSname[12];
          } FSattributeInfo;
      } u;
  } smb_tran2QFSInfo_t;
--- 44,83 ----
      union {
  #pragma pack(push, 2)
          struct {
!             unsigned long FSID;			/* file system ID */
!             unsigned long sectorsPerAllocUnit;
!             unsigned long totalAllocUnits;	/* on the disk */
!             unsigned long availAllocUnits;	/* free blocks */
              unsigned short bytesPerSector;	/* bytes per sector */
          } allocInfo;
  #pragma pack(pop)
          struct {
!             unsigned long vsn;	/* volume serial number */
              char vnCount;	/* count of chars in label, incl null */
              char label[12];	/* pad out with nulls */
          } volumeInfo;
          struct {
!             FILETIME vct;		/* volume creation time */
!             unsigned long vsn;	        /* volume serial number */
!             unsigned long vnCount;	/* length of volume label in bytes */
!             char res[2];		/* reserved */
!             char label[10];		/* volume label */
          } FSvolumeInfo;
          struct {
              osi_hyper_t totalAllocUnits;	/* on the disk */
              osi_hyper_t availAllocUnits;	/* free blocks */
!             unsigned long sectorsPerAllocUnit;
!             unsigned long bytesPerSector;	/* bytes per sector */
          } FSsizeInfo;
          struct {
!             unsigned long devType;		/* device type */
!             unsigned long characteristics;
          } FSdeviceInfo;
          struct {
!             unsigned long attributes;
!             unsigned long maxCompLength;	/* max path component length */
!             unsigned long FSnameLength;		/* length of file system name */
!             unsigned char FSname[12];
          } FSattributeInfo;
      } u;
  } smb_tran2QFSInfo_t;
Index: openafs/src/WINNT/afsd/smb_ioctl.c
diff -c openafs/src/WINNT/afsd/smb_ioctl.c:1.23 openafs/src/WINNT/afsd/smb_ioctl.c:1.25
*** openafs/src/WINNT/afsd/smb_ioctl.c:1.23	Thu Feb 16 17:06:02 2006
--- openafs/src/WINNT/afsd/smb_ioctl.c	Sun Apr  9 03:28:58 2006
***************
*** 116,122 ****
  smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
  {
      long opcode;
!     smb_ioctlProc_t *procp;
      long code;
  
      if (ioctlp-&gt;flags &amp; SMB_IOCTLFLAG_DATAIN) {
--- 116,122 ----
  smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
  {
      long opcode;
!     smb_ioctlProc_t *procp = NULL;
      long code;
  
      if (ioctlp-&gt;flags &amp; SMB_IOCTLFLAG_DATAIN) {
***************
*** 137,143 ****
              return CM_ERROR_TOOBIG;
  
          /* check for no such proc */
!         procp = smb_ioctlProcsp[opcode];
          if (procp == NULL) 
              return CM_ERROR_BADOP;
  
--- 137,147 ----
              return CM_ERROR_TOOBIG;
  
          /* check for no such proc */
! 	if (fidp-&gt;flags &amp; SMB_FID_IOCTL)
! 	    procp = smb_ioctlProcsp[opcode];
! 	else
! 	    procp = NULL;
! 
          if (procp == NULL) 
              return CM_ERROR_BADOP;
  
Index: openafs/src/WINNT/install/wix/NTMakefile
diff -c openafs/src/WINNT/install/wix/NTMakefile:1.8 openafs/src/WINNT/install/wix/NTMakefile:1.9
*** openafs/src/WINNT/install/wix/NTMakefile:1.8	Wed Oct  5 09:32:29 2005
--- openafs/src/WINNT/install/wix/NTMakefile	Mon Mar 20 12:20:01 2006
***************
*** 13,18 ****
--- 13,19 ----
  MEDIABINDIR = $(MEDIADIR)\Dll
  
  MSIFILE = $(MEDIADIR)\openafs-$(LANG).msi
+ BINMSIFILE = $(MEDIADIR)\openafs-32bit-tools-$(LANG).msi
  
  WIXINCLUDES = \
  	config.wxi \
***************
*** 24,29 ****
--- 25,31 ----
  	lang\$(LANG)\ui.wxi
  
  WIXOBJ = $(OUT)\openafs-$(LANG).wixobj
+ BINWIXOBJ  = $(OUT)\openafs-32bit-tools-$(LANG).wixobj
  
  LANGUAGES=en_US de_DE es_ES ja_JP ko_KR pt_BR zh_CN zh_TW
  
***************
*** 36,43 ****
  #	$(MAKE) /f NTMakefile /nologo LANG=%l lang
  #	)
  	$(MAKE) /f NTMakefile /nologo LANG=en_US lang
  
! lang:: lang_clean $(MSIFILE)
  
  uninst: 
          $(CD) uninstall
--- 38,46 ----
  #	$(MAKE) /f NTMakefile /nologo LANG=%l lang
  #	)
  	$(MAKE) /f NTMakefile /nologo LANG=en_US lang
+ 	
  
! lang:: lang_clean $(MSIFILE) $(BINMSIFILE)
  
  uninst: 
          $(CD) uninstall
***************
*** 49,55 ****
  	$(MAKE) /f NTMakefile /nologo install
  	$(CD) ..
  
! install: uninst customactions languages 
  
  $(MSIFILE): $(WIXOBJ)
  	light -nologo -out $(MSIFILE) \
--- 52,58 ----
  	$(MAKE) /f NTMakefile /nologo install
  	$(CD) ..
  
! install: uninst customactions languages
  
  $(MSIFILE): $(WIXOBJ)
  	light -nologo -out $(MSIFILE) \
***************
*** 71,76 ****
--- 74,99 ----
  		-w0 \
          $(AFSDEV_AUXWIXDEFINES)	openafs.wxs
  
+ $(BINWIXOBJ): oafwbins.wxs $(WIXINCLUDES)
+ 	candle -nologo -out $@	\
+ 		"-dCellName=$(CELLNAME_DEFAULT)" \
+ 		-dLanguage=$(LANG) \
+ 		-dNumericVersion=$(AFSPRODUCT_VERSION)	\
+ 		-dVersionMajor=$(AFSPRODUCT_VER_MAJOR)	\
+ 		-dVersionMinor=$(AFSPRODUCT_VER_MINOR)	\
+ 		-dVersionPatch=$(AFSPRODUCT_VER_PATCH)	\
+ 		"-dDestDir=$(DESTDIR)\\" \
+ 		-dCellDbFile=CellServDB \
+ 		-v0 \
+ 		-w0 \
+         $(AFSDEV_AUXWIXDEFINES)	oafwbins.wxs
+ 
+ $(BINMSIFILE): $(BINWIXOBJ)
+ 	light -nologo -out $(BINMSIFILE) \
+ 		-loc lang\en_US\strings.wxl \
+ 		$(BINWIXOBJ)
+ 	dir $(BINMSIFILE)
+ 
  # Cleanup
  clean::
  	for %l in ( $(LANGUAGES) ) do \
***************
*** 81,87 ****
  	$(CD) uninstall
  	$(MAKE) /f NTMakefile /nologo clean
  	$(CD) ..
! 	
  lang_clean:
  	-$(DEL) $(WIXOBJ)
  	-$(DEL) $(MSIFILE)
--- 104,112 ----
  	$(CD) uninstall
  	$(MAKE) /f NTMakefile /nologo clean
  	$(CD) ..
! 
  lang_clean:
  	-$(DEL) $(WIXOBJ)
  	-$(DEL) $(MSIFILE)
+ 	-$(DEL) $(BINWIXOBJ)
+ 	-$(DEL) $(BINMSIFILE)
Index: openafs/src/WINNT/install/wix/config.wxi
diff -c openafs/src/WINNT/install/wix/config.wxi:1.10 openafs/src/WINNT/install/wix/config.wxi:1.11
*** openafs/src/WINNT/install/wix/config.wxi:1.10	Sun Nov 20 20:56:27 2005
--- openafs/src/WINNT/install/wix/config.wxi	Mon Mar 20 12:20:01 2006
***************
*** 132,138 ****
      &lt;?else?&gt;
          &lt;?error Unknown build type?&gt;
      &lt;?endif?&gt;
!     
      &lt;!-- Use the afsloopback.dll instead of instloop.exe --&gt;
      &lt;?define UseDllLoopbackInstaller?&gt;
  
--- 132,138 ----
      &lt;?else?&gt;
          &lt;?error Unknown build type?&gt;
      &lt;?endif?&gt;
! 
      &lt;!-- Use the afsloopback.dll instead of instloop.exe --&gt;
      &lt;?define UseDllLoopbackInstaller?&gt;
  
Index: openafs/src/WINNT/install/wix/feature.wxi
diff -c openafs/src/WINNT/install/wix/feature.wxi:1.13 openafs/src/WINNT/install/wix/feature.wxi:1.14
*** openafs/src/WINNT/install/wix/feature.wxi:1.13	Sun Nov 20 20:56:27 2005
--- openafs/src/WINNT/install/wix/feature.wxi	Mon Mar 20 12:20:01 2006
***************
*** 1,9 ****
! ï»¿&lt;?xml version="1.0" ?&gt;
  &lt;Include&gt;
          &lt;Feature Id="feaOpenAFS" AllowAdvertise="no" Absent="disallow" ConfigurableDirectory="AFSDIR"
              Description="$(loc.StrAFSProdDesc)" Display="expand" InstallDefault="local" Level="30"
              Title="OpenAFS"&gt;
             &lt;ComponentRef Id="efl_desktop_INI" /&gt;
             &lt;ComponentRef Id="efl_replace_afs_CMD" /&gt;
             &lt;ComponentRef Id="efl_uninstall_EXE" /&gt;
  
--- 1,11 ----
! &lt;?xml version="1.0" ?&gt;
  &lt;Include&gt;
          &lt;Feature Id="feaOpenAFS" AllowAdvertise="no" Absent="disallow" ConfigurableDirectory="AFSDIR"
              Description="$(loc.StrAFSProdDesc)" Display="expand" InstallDefault="local" Level="30"
              Title="OpenAFS"&gt;
             &lt;ComponentRef Id="efl_desktop_INI" /&gt;
+ 
+   &lt;?ifndef BinsOnly ?&gt;
             &lt;ComponentRef Id="efl_replace_afs_CMD" /&gt;
             &lt;ComponentRef Id="efl_uninstall_EXE" /&gt;
  
***************
*** 12,18 ****
--- 14,22 ----
             &lt;ComponentRef Id="cmf_index2_HTM_en_US" /&gt;
             &lt;ComponentRef Id="cmp_index_files_en_US" /&gt;
             &lt;ComponentRef Id="cmp_logo_files_en_US" /&gt;
+   &lt;?endif?&gt;
  
+   &lt;?ifndef BinsOnly ?&gt;
              &lt;Feature Id="feaClient" AllowAdvertise="no" Description="$(loc.StrAFSClientLongDesc)" Display="expand"
                  InstallDefault="followParent" Level="30" Title="$(loc.StrAFSClientDesc)"&gt;
                  
***************
*** 256,260 ****
--- 260,315 ----
                  &lt;ComponentRef Id="cmp_Lang_en_US" /&gt;
  		
              &lt;/Feature&gt;
+   &lt;?else?&gt;
+             &lt;Feature Id="feaBinaries" AllowAdvertise="no" Description="$(loc.StrBinsOnlyLongDesc)"
+                 Display="expand" InstallDefault="followParent" Level="100" Title="$(loc.StrBinsOnlyDesc)"&gt;
+ 
+ 			&lt;?ifdef DebugSyms?&gt;
+ 				&lt;Feature Id="feaClientDebug" AllowAdvertise="no" Description="$(loc.StrAFSClientDebugLongDesc)" Display="expand"
+ 					InstallDefault="$(var.DebugSymInstallDefault)" Level="$(var.DebugSymLowLevel)" Title="$(loc.StrAFSClientDebugDesc)"&gt;
+                     &lt;ComponentRef Id="cmp_ClientProgramDebug" /&gt;
+                     &lt;ComponentRef Id="cmp_CommonCommonDebug" /&gt;
+                     &lt;?include runtime_debug.wxi?&gt;
+ 				&lt;/Feature&gt;
+ 			&lt;?endif?&gt;
+ 
+ 				&lt;ComponentRef Id="cmp_CommonDir" /&gt;
+ 
+                 &lt;ComponentRef Id="cmf_afsrpc_DLL" /&gt;
+                 &lt;ComponentRef Id="cmf_afsauthent2_DLL" /&gt;
+                 &lt;ComponentRef Id="cmf_afspthread_DLL" /&gt;
+                 &lt;ComponentRef Id="cmf_TaAfsAppLib_DLL" /&gt;
+                 &lt;ComponentRef Id="cmf_afsprocmgmt_DLL" /&gt;
+ 
+                 &lt;ComponentRef Id="cmf_afsshare_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_libosi_DLL" /&gt;
+                 &lt;ComponentRef Id="cmf_libafsconf_DLL" /&gt;
+                 &lt;ComponentRef Id="cmf_klog_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_tokens_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_unlog_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_fs_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_afsdacl_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_symlink_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_kpasswd_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_pts_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_bos_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_kas_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_vos_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_udebug_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_translate_et_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_rxdebug_EXE" /&gt;
+                 &lt;ComponentRef Id="cmf_backup_EXE" /&gt;
+ 
+                 &lt;ComponentRef Id="rcm_BinsOnly_Parm" /&gt;
+                 &lt;?if $(env.CPU) = "i386"?&gt;
+             	    &lt;ComponentRef Id="cmf_aklog_EXE" /&gt;
+ 	 	&lt;?endif?&gt;
+                 &lt;ComponentRef Id="cmf_cmdebug_EXE" /&gt;
+                 
+                 &lt;!-- Runtime --&gt;
+                 &lt;?include runtime.wxi?&gt;
+ 
+             &lt;/Feature&gt;
+   &lt;?endif?&gt;
          &lt;/Feature&gt;
  &lt;/Include&gt;
Index: openafs/src/WINNT/install/wix/files.wxi
diff -c openafs/src/WINNT/install/wix/files.wxi:1.20 openafs/src/WINNT/install/wix/files.wxi:1.22
*** openafs/src/WINNT/install/wix/files.wxi:1.20	Sun Nov 20 20:56:27 2005
--- openafs/src/WINNT/install/wix/files.wxi	Fri Apr 21 09:52:02 2006
***************
*** 1,5 ****
--- 1,6 ----
  &lt;?xml version="1.0"?&gt;
  &lt;Include&gt;
+   &lt;?ifndef BinsOnly?&gt;
      &lt;Directory Id="$(var.PISystemFolder)" SourceName="System"&gt;
          &lt;Component Win64="$(var.Win64)" Id="cmf_afslogon_DLL" Guid="$(var.cmf_afslogon_DLL_guid)"&gt;
              &lt;File Id="fileafslogon_DLL" Name="afslogon.dll" LongName="afslogon.dll" KeyPath="yes" DiskId="1" src="$(var.ClientDir)afslogon.dll" /&gt;
***************
*** 26,36 ****
--- 27,39 ----
          &lt;/Component&gt;
      &lt;?endif?&gt;
      &lt;/Directory&gt;
+   &lt;?endif?&gt;
      &lt;Directory Id="$(var.PIProgramFilesFolder)"&gt;
          &lt;Directory Id="AFSDIR" Name="OpenAFS" SourceName="."&gt;
  	    &lt;Component Id="efl_desktop_INI" Guid="0ADB427F-3648-4BE0-983B-C454AA51895C"&gt;
  		&lt;File Id="fildesktop_INI" Name="desktop.ini" KeyPath="yes" DiskId="1" src="$(var.SrcDir)WINNT\install\wix\afsdesktop.ini" Hidden="yes" System="yes" /&gt;
  	    &lt;/Component&gt;
+   &lt;?ifndef BinsOnly?&gt;
              &lt;Component Id="efl_replace_afs_CMD" Guid="C9C93F3E-EEBA-4056-9669-5EF78D748D50"&gt;
                 &lt;File Id="filreplace_afs_CMD" Name="replafs.cmd" LongName="replace_afs.cmd" KeyPath="yes" DiskId="1" src="$(var.SrcDir)\WINNT\install\wix\replace_afs.cmd" /&gt;
              &lt;/Component&gt;
***************
*** 39,49 ****
--- 42,55 ----
  			&lt;Shortcut Id="scUninstall" Directory="dirShortCut" Name="Uninst.lnk" LongName="Uninstall OpenAFS.lnk" Description="$(loc.StrUninstallDesc)" Icon="ico_OpenAFS" IconIndex="0" Show="normal" /&gt;
                  &lt;/File&gt;
  	    &lt;/Component&gt;
+   &lt;?endif?&gt;
              &lt;Directory Id="dirCommon" Name="Common"&gt;
                  &lt;Component Id="cmp_CommonDir" Guid="C86B03A1-AE97-48B1-A77B-1B2395F1E117" KeyPath="yes"&gt;
                      &lt;Environment Id="envCommon" Name="PATH" Action="create" System="yes" Permanent="no" Part="last" Separator=";" Value="[AFSDIR]Common" /&gt;
                      &lt;CreateFolder /&gt;
                  &lt;/Component&gt;
+ 
+   &lt;?ifndef BinsOnly?&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmf_afsbosadmin_DLL" Guid="$(var.cmf_afsbosadmin_DLL_guid)"&gt;
                      &lt;File Id="fileafsbosadmin_DLL" Name="afsbosad.dll" LongName="afsbosadmin.dll" KeyPath="yes" DiskId="1" src="$(var.ServerDir)\afsbosadmin.dll"/&gt;
                  &lt;/Component&gt;
***************
*** 65,70 ****
--- 71,78 ----
                  &lt;Component Win64="$(var.Win64)" Id="cmf_afsadminutil_DLL" Guid="$(var.cmf_afsadminutil_DLL_guid)"&gt;
                      &lt;File Id="fileafsadminutil_DLL" Name="afsadmut.dll" LongName="afsadminutil.dll" KeyPath="yes" DiskId="1" src="$(var.ServerDir)\afsadminutil.dll"/&gt;
                  &lt;/Component&gt;
+   &lt;?endif?&gt;
+ 
                  &lt;Component Win64="$(var.Win64)" Id="cmf_afsrpc_DLL" Guid="$(var.cmf_afsrpc_DLL_guid)"&gt;
                      &lt;File Id="fileafsrpc_DLL" Name="afsrpc.dll" LongName="afsrpc.dll" KeyPath="yes" DiskId="1" src="$(var.LibDir)\afsrpc.dll"/&gt;
                  &lt;/Component&gt;
***************
*** 80,90 ****
                  &lt;Component Win64="$(var.Win64)" Id="cmf_afsprocmgmt_DLL" Guid="$(var.cmf_afsprocmgmt_DLL_guid)"&gt;
                      &lt;File Id="fileafsprocmgmt_DLL" Name="afsprcmg.dll" LongName="afsprocmgmt.dll" KeyPath="yes" DiskId="1" src="$(var.ServerDir)\afsprocmgmt.dll"/&gt;
                  &lt;/Component&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmf_afs_config_EXE" Guid="$(var.cmf_afs_config_EXE_guid)"&gt;
                      &lt;File Id="fileafs_config_EXE" Name="afs_cfg.exe" LongName="afs_config.exe" KeyPath="yes" DiskId="1" src="$(var.ClientDir)\afs_config.exe"/&gt;
                  &lt;/Component&gt;
!                 
              &lt;?ifdef DebugSyms?&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmp_ServerCommonDebug" Guid="$(var.cmp_ServerCommonDebug_guid)"&gt;
                      &lt;File Id="fileafsbosadmin_PDB" Name="afsbosad.pdb" LongName="afsbosadmin.pdb" KeyPath="yes" DiskId="1" src="$(var.ServerDir)\afsbosadmin.pdb"/&gt;
                      &lt;File Id="fileafscfgadmin_PDB" Name="afscfgad.pdb" LongName="afscfgadmin.pdb" DiskId="1" src="$(var.ServerDir)\afscfgadmin.pdb"/&gt;
--- 88,101 ----
                  &lt;Component Win64="$(var.Win64)" Id="cmf_afsprocmgmt_DLL" Guid="$(var.cmf_afsprocmgmt_DLL_guid)"&gt;
                      &lt;File Id="fileafsprocmgmt_DLL" Name="afsprcmg.dll" LongName="afsprocmgmt.dll" KeyPath="yes" DiskId="1" src="$(var.ServerDir)\afsprocmgmt.dll"/&gt;
                  &lt;/Component&gt;
+   &lt;?ifndef BinsOnly ?&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmf_afs_config_EXE" Guid="$(var.cmf_afs_config_EXE_guid)"&gt;
                      &lt;File Id="fileafs_config_EXE" Name="afs_cfg.exe" LongName="afs_config.exe" KeyPath="yes" DiskId="1" src="$(var.ClientDir)\afs_config.exe"/&gt;
                  &lt;/Component&gt;
!   &lt;?endif?&gt;
! 
              &lt;?ifdef DebugSyms?&gt;
+               &lt;?ifndef BinsOnly?&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmp_ServerCommonDebug" Guid="$(var.cmp_ServerCommonDebug_guid)"&gt;
                      &lt;File Id="fileafsbosadmin_PDB" Name="afsbosad.pdb" LongName="afsbosadmin.pdb" KeyPath="yes" DiskId="1" src="$(var.ServerDir)\afsbosadmin.pdb"/&gt;
                      &lt;File Id="fileafscfgadmin_PDB" Name="afscfgad.pdb" LongName="afscfgadmin.pdb" DiskId="1" src="$(var.ServerDir)\afscfgadmin.pdb"/&gt;
***************
*** 94,99 ****
--- 105,111 ----
                      &lt;File Id="fileafsvosadmin_PDB" Name="afsvosad.pdb" LongName="afsvosadmin.pdb" DiskId="1" src="$(var.ServerDir)\afsvosadmin.pdb"/&gt;
                      &lt;File Id="fileafsadminutil_PDB" Name="afsadmut.pdb" LongName="afsadminutil.pdb" DiskId="1" src="$(var.ServerDir)\afsadminutil.pdb"/&gt;
                  &lt;/Component&gt;
+               &lt;?endif?&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmp_CommonCommonDebug" Guid="$(var.cmp_CommonCommonDebug_guid)"&gt;
                      &lt;File Id="fileafsrpc_PDB" Name="afsrpc.pdb" LongName="afsrpc.pdb" KeyPath="yes" DiskId="1" src="$(var.LibDir)\afsrpc.pdb"/&gt;
                      &lt;File Id="fileafsauthent_PDB" Name="afsauth.pdb" LongName="afsauthent.pdb" DiskId="1" src="$(var.LibDir)\afsauthent.pdb"/&gt;
***************
*** 101,111 ****
--- 113,126 ----
                      &lt;File Id="fileTaAfsAppLib_PDB" Name="TaAfsApL.pdb" LongName="TaAfsAppLib.pdb" DiskId="1" src="$(var.ServerDir)\TaAfsAppLib.pdb"/&gt;
                      &lt;File Id="fileafsprocmgmt_PDB" Name="afsprcmg.pdb" LongName="afsprocmgmt.pdb" DiskId="1" src="$(var.ServerDir)\afsprocmgmt.pdb"/&gt;
                  &lt;/Component&gt;
+               &lt;?ifndef BinsOnly ?&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmp_ClientCommonDebug" Guid="$(var.cmp_ClientCommonDebug_guid)"&gt;
                      &lt;File Id="fileafs_config_PDB" Name="afs_cfg.pdb" LongName="afs_config.pdb" KeyPath="yes" DiskId="1" src="$(var.ClientDir)\afs_config.pdb"/&gt;
                  &lt;/Component&gt;
+               &lt;?endif?&gt;
              &lt;?endif?&gt;
  
+   &lt;?ifndef BinsOnly ?&gt;
                  &lt;!-- &lt;&lt;LanguageSpecific:1033/en_US&gt;&gt; --&gt;
              &lt;?if $(var.Language) ="en_US"?&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmf_afseventmsg_1033_DLL" Guid="$(var.cmf_afseventmsg_1033_DLL_guid)"&gt;
***************
*** 162,167 ****
--- 177,183 ----
                  &lt;/Directory&gt;
              &lt;?endif?&gt;
                  &lt;!-- &lt;&lt;/LanguageSpecific:1033/en_US&gt;&gt; --&gt;
+   &lt;?endif?&gt; &lt;!-- /ifndef BinsOnly --&gt;
  
                  &lt;!-- Runtime libraries --&gt;
            &lt;?ifndef Debug?&gt;
***************
*** 310,316 ****
            &lt;?endif?&gt;
            &lt;?endif?&gt;
              &lt;/Directory&gt; &lt;!-- /common --&gt;
!             
              &lt;Directory Id="dirControl_Center" Name="Contr" LongName="Control Center" SourceName="ControlC" LongSource="Control Center"&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmf_TaAfsServerManager_EXE" Guid="$(var.cmf_TaAfsServerManager_EXE_guid)"&gt;
                      &lt;File Id="fileTaAfsServerManager_EXE" Name="TaAfsSvM.exe" LongName="TaAfsServerManager.exe" KeyPath="yes" DiskId="1" src="$(var.ServerDir)\TaAfsServerManager.exe"&gt;
--- 326,333 ----
            &lt;?endif?&gt;
            &lt;?endif?&gt;
              &lt;/Directory&gt; &lt;!-- /common --&gt;
! 
!   &lt;?ifndef BinsOnly ?&gt;            
              &lt;Directory Id="dirControl_Center" Name="Contr" LongName="Control Center" SourceName="ControlC" LongSource="Control Center"&gt;
                  &lt;Component Win64="$(var.Win64)" Id="cmf_TaAfsServerManager_EXE" Guid="$(var.cmf_TaAfsServerManager_EXE_guid)"&gt;
                      &lt;File Id="fileTaAfsServerManager_EXE" Name="TaAfsSvM.exe" LongName="TaAfsServerManager.exe" KeyPath="yes" DiskId="1" src="$(var.ServerDir)\TaAfsServerManager.exe"&gt;
***************
*** 333,339 ****
--- 350,358 ----
                  &lt;/Component&gt;
              &lt;?endif?&gt;
              &lt;/Directory&gt; &lt;!-- /Control center --&gt;
+   &lt;?endif?&gt;
  
+   &lt;?ifndef BinsOnly?&gt;
           &lt;?if $(var.Language) = "en_US"?&gt;
              &lt;Component Id="efl_Readme_TXT_en_US" Guid="959DC63A-6C67-4B51-9F7D-2CDEE91F0099"&gt;
                  &lt;File Id="fileREADME_TXT_en_US" Name="README.txt" LongName="README.txt" DiskId="1" src="$(var.SrcDir)\WINNT\doc\install\Documentation\en_US\README.txt"/&gt;
***************
*** 381,387 ****
--- 400,408 ----
                  &lt;File Id="fileREADME_TXT_zh_CN" Name="README.txt" LongName="README.txt" DiskId="1" src="$(var.SrcDir)\WINNT\doc\install\Documentation\zh_CN\README.txt"/&gt;
              &lt;/Component&gt;
           &lt;?endif?&gt;
+   &lt;?endif?&gt;
  
+   &lt;?ifndef BinsOnly?&gt;
              &lt;Directory Id="dirDocumentation" Name="Docum" LongName="Documentation" SourceName="Docs"&gt;
  				&lt;!-- The following directory and everything below it is language dependent. --&gt;
                      &lt;Directory Id="dirHtml_$(var.Language)" Name="Html" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\"&gt;
***************
*** 774,781 ****
--- 795,804 ----
                          &lt;/Directory&gt; &lt;!-- Release Notes --&gt;
                      &lt;/Directory&gt; &lt;!-- Html --&gt;
              &lt;/Directory&gt; &lt;!-- Documentation --&gt;
+   &lt;?endif?&gt;
  
              &lt;Directory Id="dirClient" Name="Client"&gt;
+   &lt;?ifndef BinsOnly ?&gt;
                  &lt;Component Id="efl_CellServDB" Guid="8E69FDAB-08C5-4927-B1AA-57FCEEB065F2" NeverOverwrite="yes" Permanent="yes"&gt;
                      &lt;File Id="file_CellServDB" Name="CelSrvDB" LongName="CellServDB" KeyPath="yes" DiskId="1" src="$(var.CellDbFile)"/&gt;
                      &lt;Condition&gt;OLDCELLSERVDB = ""&lt;/Condition&gt;
***************
*** 785,790 ****
--- 808,814 ----
                      &lt;CopyFile Id="copy_CellServDB" Delete="yes" DestinationDirectory="dirClient" DestinationName="CellServ|CellServDB" SourceDirectory="WindowsFolder" SourceName="afsdcell.ini" /&gt;
                      &lt;Condition&gt;OLDCELLSERVDB &amp;lt;&amp;gt; ""&lt;/Condition&gt;
                  &lt;/Component&gt;
+   &lt;?endif?&gt;
                  &lt;Directory Id="dirProgram" Name="Program" src="$(var.ClientDir)"&gt;
                      &lt;Component Win64="$(var.Win64)" Id="cmf_afsshare_EXE" Guid="$(var.cmf_afsshare_EXE_guid)"&gt;
                          &lt;File Id="fileafsshare_EXE" Name="afsshare.exe" LongName="afsshare.exe" KeyPath="yes" DiskId="1" /&gt;
***************
*** 810,815 ****
--- 834,840 ----
                      &lt;Component Win64="$(var.Win64)" Id="cmf_afsdacl_EXE" Guid="$(var.cmf_afsdacl_EXE_guid)"&gt;
                          &lt;File Id="fileafsdacl_EXE" Name="afsdacl.exe" KeyPath="yes" DiskId="1" /&gt;
                      &lt;/Component&gt;
+   &lt;?ifndef BinsOnly ?&gt;
                      &lt;Component Win64="$(var.Win64)" Id="cmf_afscreds_EXE" Guid="$(var.cmf_afscreds_EXE_guid)"&gt;
                          &lt;File Id="fileafscreds_EXE" Name="afscreds.exe" LongName="afscreds.exe" KeyPath="yes" DiskId="1"&gt;
  							&lt;Shortcut Id="scAfsCreds" Directory="dirShortCut" Name="Auth.lnk" LongName="Authentication.lnk" Description="$(loc.StrAfsCredsDesc)" Arguments="[CREDSAUTOINIT] [CREDSRENEWDRMAP] [CREDSIPCHDET] [CREDSQUIET] [CREDSSHOW]" Icon="ico_afscreds" IconIndex="0" Show="normal" WorkingDirectory="dirCommon" /&gt;
***************
*** 844,849 ****
--- 869,875 ----
                          &lt;Environment Id="envClient" Name="PATH" Action="create" System="yes" Permanent="no" Part="last" Separator=";" Value="[AFSDIR]Client\Program" /&gt;
                          &lt;RemoveFile Id="removeCache" Directory="WindowsVolume" LongName="AFSCache" Name="AFSCache" On="uninstall" /&gt;
                      &lt;/Component&gt;
+   &lt;?endif?&gt;
                       &lt;Component Win64="$(var.Win64)" Id="cmf_symlink_EXE" Guid="$(var.cmf_symlink_EXE_guid)"&gt;
                          &lt;File Id="filesymlink_EXE" Name="symlink.exe" LongName="symlink.exe" KeyPath="yes" DiskId="1" /&gt;
                      &lt;/Component&gt;
***************
*** 882,891 ****
--- 908,919 ----
                       &lt;Component Win64="$(var.Win64)" Id="cmf_cmdebug_EXE" Guid="$(var.cmf_cmdebug_EXE_guid)"&gt;
                          &lt;File Id="filecmdebug_EXE" Name="cmdebug.exe" LongName="cmdebug.exe" KeyPath="yes" DiskId="1" /&gt;
                      &lt;/Component&gt;
+   &lt;?ifndef BinsOnly?&gt;
   		    &lt;Component Win64="$(var.Win64)" Id="cmf_afs_cpa_CPL" Guid="$(var.cmf_afs_cpa_CPL_guid)"&gt;
  		    	&lt;File Id="fileafs_cpa_CPL" Name="afs_cpa.cpl" LongName="afs_cpa.cpl" KeyPath="yes" DiskId="1"/&gt;
  		    &lt;Registry Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Control Panel\Cpls" Name="AFS Client CPL" Type="string" Value="[#fileafs_cpa_CPL]" Id="reg_Full_Client11" /&gt;
  		    &lt;/Component&gt;
+   &lt;?endif?&gt;
                  &lt;?ifdef DebugSyms?&gt;
                       &lt;Component Win64="$(var.Win64)" Id="cmp_ClientProgramDebug" Guid="$(var.cmp_ClientProgramDebug_guid)"&gt;
                          &lt;File Id="fileafsshare_PDB" Name="afsshare.pdb" LongName="afsshare.pdb" DiskId="1" /&gt;
***************
*** 895,903 ****
                          &lt;File Id="filetokens_PDB" Name="tokens.pdb" LongName="tokens.pdb" DiskId="1" /&gt;
                          &lt;File Id="fileunlog_PDB" Name="unlog.pdb" LongName="unlog.pdb" DiskId="1" /&gt;
                          &lt;File Id="filefs_PDB" Name="fs.pdb" LongName="fs.pdb" DiskId="1" /&gt;
-                         &lt;File Id="fileafscreds_PDB" Name="afscreds.pdb" LongName="afscreds.pdb" DiskId="1" /&gt;
-                         &lt;File Id="fileafs_shl_ext_PDB" Name="afsshext.pdb" LongName="afs_shl_ext.pdb" DiskId="1" /&gt;
-                         &lt;File Id="fileafsd_service_PDB" Name="afsd_svc.pdb" LongName="afsd_service.pdb" DiskId="1" /&gt;
                          &lt;File Id="filesymlink_PDB" Name="symlink.pdb" LongName="symlink.pdb" DiskId="1" /&gt;
                          &lt;File Id="filekpasswd_PDB" Name="kpasswd.pdb" LongName="kpasswd.pdb" DiskId="1" src="$(var.BinDir)kpasswd.pdb" /&gt;
                          &lt;File Id="filepts_PDB" Name="pts.pdb" LongName="pts.pdb" DiskId="1" src="$(var.BinDir)pts.pdb" /&gt;
--- 923,928 ----
***************
*** 912,921 ****
                          	&lt;File Id="fileaklog_PDB" Name="aklog.pdb" LongName="aklog.pdb" DiskId="1" /&gt;
  			&lt;?endif?&gt;
                          &lt;File Id="filecmdebug_PDB" Name="cmdebug.pdb" LongName="cmdebug.pdb" DiskId="1" /&gt;
  			&lt;File Id="fileafs_cpa_PDB" Name="afs_cpa.pdb" LongName="afs_cpa.pdb" KeyPath="yes" DiskId="1"/&gt;
                      &lt;/Component&gt;
                  &lt;?endif?&gt;
!                     
                      &lt;Directory Id="dirSample" Name="Sample"&gt;
                          &lt;Component Id="cmp_SDK_Sample" Guid="F9373E95-F410-4AA5-AA79-07C11EE00334"&gt;
                              &lt;File Id="filetoken_C" Name="token.c" LongName="token.c" KeyPath="yes" DiskId="1" src="$(var.SrcDir)WINNT\afsd\sample\token.c"/&gt;
--- 937,951 ----
                          	&lt;File Id="fileaklog_PDB" Name="aklog.pdb" LongName="aklog.pdb" DiskId="1" /&gt;
  			&lt;?endif?&gt;
                          &lt;File Id="filecmdebug_PDB" Name="cmdebug.pdb" LongName="cmdebug.pdb" DiskId="1" /&gt;
+   &lt;?ifndef BinsOnly ?&gt;
  			&lt;File Id="fileafs_cpa_PDB" Name="afs_cpa.pdb" LongName="afs_cpa.pdb" KeyPath="yes" DiskId="1"/&gt;
+                         &lt;File Id="fileafscreds_PDB" Name="afscreds.pdb" LongName="afscreds.pdb" DiskId="1" /&gt;
+                         &lt;File Id="fileafs_shl_ext_PDB" Name="afsshext.pdb" LongName="afs_shl_ext.pdb" DiskId="1" /&gt;
+                         &lt;File Id="fileafsd_service_PDB" Name="afsd_svc.pdb" LongName="afsd_service.pdb" DiskId="1" /&gt;
+   &lt;?endif?&gt;
                      &lt;/Component&gt;
                  &lt;?endif?&gt;
!   &lt;?ifndef BinsOnly?&gt;                  
                      &lt;Directory Id="dirSample" Name="Sample"&gt;
                          &lt;Component Id="cmp_SDK_Sample" Guid="F9373E95-F410-4AA5-AA79-07C11EE00334"&gt;
                              &lt;File Id="filetoken_C" Name="token.c" LongName="token.c" KeyPath="yes" DiskId="1" src="$(var.SrcDir)WINNT\afsd\sample\token.c"/&gt;
***************
*** 1232,1239 ****
--- 1262,1271 ----
                              &lt;/Component&gt;
                          &lt;/Directory&gt;
                      &lt;/Directory&gt;
+   &lt;?endif?&gt;
                  &lt;/Directory&gt; &lt;!-- /Program --&gt;
              &lt;/Directory&gt; &lt;!-- /Client --&gt;
+   &lt;?ifndef BinsOnly ?&gt;
              &lt;Directory Id="dirServer" Name="Server"&gt;
                  &lt;Directory Id="dirusr" Name="usr"&gt;
                      &lt;Directory Id="dirafs" Name="afs"&gt;
***************
*** 1343,1351 ****
--- 1375,1386 ----
                      &lt;/Directory&gt;
                  &lt;/Directory&gt;
              &lt;/Directory&gt; &lt;!-- Server --&gt;
+   &lt;?endif?&gt;
  
          &lt;/Directory&gt; &lt;!-- AFS --&gt;
      &lt;/Directory&gt; &lt;!-- program files --&gt;
+ 
+   &lt;?ifndef BinsOnly ?&gt;
      &lt;!-- References --&gt;
      &lt;Directory Id="ProgramMenuFolder" Name="."&gt;
          &lt;Directory Id="dirShortCut" Name="OpenAFS"/&gt;
***************
*** 1353,1365 ****
      &lt;Directory Id="StartupFolder" Name="." /&gt;
      &lt;Directory Id="WindowsVolume" Name="." /&gt;
      &lt;Directory Id="WindowsFolder" Name="." /&gt;
  
  	&lt;!-- Shared assembly runtime for VS 2005 --&gt;
  	&lt;?if $(env.AFSVER_CL) = "1400"?&gt;
  		&lt;?ifdef env.CommonProgramFiles6432?&gt;
  		  &lt;?define CPF="$(env.CommonProgramFiles)"?&gt;
  		&lt;?else?&gt;
! 		  &lt;?define CPF="$(env.CommonProgramFiles(x86)"?&gt;
  		&lt;?endif?&gt;
  		&lt;?if $(var.Platform) = "x64" ?&gt;
  			&lt;?ifndef Debug?&gt;
--- 1388,1401 ----
      &lt;Directory Id="StartupFolder" Name="." /&gt;
      &lt;Directory Id="WindowsVolume" Name="." /&gt;
      &lt;Directory Id="WindowsFolder" Name="." /&gt;
+   &lt;?endif?&gt;
  
  	&lt;!-- Shared assembly runtime for VS 2005 --&gt;
  	&lt;?if $(env.AFSVER_CL) = "1400"?&gt;
  		&lt;?ifdef env.CommonProgramFiles6432?&gt;
  		  &lt;?define CPF="$(env.CommonProgramFiles)"?&gt;
  		&lt;?else?&gt;
! 		  &lt;?define CPF="$(env.CommonProgramFiles(x86))"?&gt;
  		&lt;?endif?&gt;
  		&lt;?if $(var.Platform) = "x64" ?&gt;
  			&lt;?ifndef Debug?&gt;
Index: openafs/src/WINNT/install/wix/language_config.wxi
diff -c openafs/src/WINNT/install/wix/language_config.wxi:1.4 openafs/src/WINNT/install/wix/language_config.wxi:1.5
*** openafs/src/WINNT/install/wix/language_config.wxi:1.4	Sun Nov 20 20:56:27 2005
--- openafs/src/WINNT/install/wix/language_config.wxi	Mon Mar 20 12:20:01 2006
***************
*** 1,4 ****
! ï»¿&lt;?xml version="1.0"?&gt; 
  &lt;Include&gt;
      &lt;!-- This file defines localized strings and language configuration for the
           installer.  Please do not insert any localizable strings directly in any
--- 1,4 ----
! &lt;?xml version="1.0"?&gt; 
  &lt;Include&gt;
      &lt;!-- This file defines localized strings and language configuration for the
           installer.  Please do not insert any localizable strings directly in any
***************
*** 16,33 ****
      &lt;?define LanguageCode="1033"?&gt;
  
      &lt;?define Manufacturer="OpenAFS.org"?&gt;
! &lt;?ifdef Debug?&gt;
      &lt;?define PackageComments="OpenAFS for Windows $(var.NumericVersion) CHECKED"?&gt;
      &lt;?define ProductComments="OpenAFS for Windows. CHECKED build." ?&gt;
! &lt;?else?&gt;
      &lt;?define PackageComments="OpenAFS for Windows $(var.NumericVersion)"?&gt;
      &lt;?define ProductComments="OpenAFS for Windows. Client and server components for using AFS."?&gt;
  &lt;?endif?&gt;
      &lt;?define Languages="$(var.LanguageCode)"?&gt;
! &lt;?if $(var.Platform) = "x64" ?&gt;
!     &lt;?define ProductName="OpenAFS for Windows (64-bit)"?&gt;
  &lt;?else?&gt;
      &lt;?define ProductName="OpenAFS for Windows"?&gt;
  &lt;?endif?&gt;
      
      &lt;!-- Localized packages should have different product codes --&gt;
--- 16,53 ----
      &lt;?define LanguageCode="1033"?&gt;
  
      &lt;?define Manufacturer="OpenAFS.org"?&gt;
! &lt;?ifdef BinsOnly?&gt;
!   &lt;?ifdef Debug?&gt;
!     &lt;?define PackageComments="OpenAFS for Windows (Tools and libraries) $(var.NumericVersion) CHECKED"?&gt;
!     &lt;?define ProductComments="OpenAFS for Windows (Tools and libraries) CHECKED build." ?&gt;
!   &lt;?else?&gt;
!     &lt;?define PackageComments="OpenAFS for Windows (Tools and libraries) $(var.NumericVersion)"?&gt;
!     &lt;?define ProductComments="OpenAFS for Windows. Tools and libraries."?&gt;
!   &lt;?endif?&gt;
! &lt;?else?&gt;
!   &lt;?ifdef Debug?&gt;
      &lt;?define PackageComments="OpenAFS for Windows $(var.NumericVersion) CHECKED"?&gt;
      &lt;?define ProductComments="OpenAFS for Windows. CHECKED build." ?&gt;
!   &lt;?else?&gt;
      &lt;?define PackageComments="OpenAFS for Windows $(var.NumericVersion)"?&gt;
      &lt;?define ProductComments="OpenAFS for Windows. Client and server components for using AFS."?&gt;
+   &lt;?endif?&gt;
  &lt;?endif?&gt;
+ 
      &lt;?define Languages="$(var.LanguageCode)"?&gt;
! 
! &lt;?ifdef BinsOnly?&gt;
!   &lt;?if $(var.Platform) = "x64" ?&gt;
!     &lt;?define ProductName="OpenAFS for Windows (64-bit binaries)"?&gt;
!   &lt;?else?&gt;
!     &lt;?define ProductName="OpenAFS for Windows (32-bit binaries)"?&gt;
!   &lt;?endif?&gt;
  &lt;?else?&gt;
+   &lt;?if $(var.Platform) = "x64" ?&gt;
+     &lt;?define ProductName="OpenAFS for Windows (64-bit)"?&gt;
+   &lt;?else?&gt;
      &lt;?define ProductName="OpenAFS for Windows"?&gt;
+   &lt;?endif?&gt;
  &lt;?endif?&gt;
      
      &lt;!-- Localized packages should have different product codes --&gt;
***************
*** 35,41 ****
      &lt;?ifndef ProductCode?&gt;
          &lt;?define ProductCode="????????-????-????-????-????????????"?&gt;
      &lt;?endif?&gt;
!     
      &lt;!-- Same goes for localized components --&gt;
      &lt;?define DocHtmlIndexGuid="B656CA5A-5179-42D8-8972-2F128AEDE751"?&gt;
      &lt;?define DocHtmlGuid="C9595172-72DF-4F30-8C43-C16583CFB8B1"?&gt;
--- 55,62 ----
      &lt;?ifndef ProductCode?&gt;
          &lt;?define ProductCode="????????-????-????-????-????????????"?&gt;
      &lt;?endif?&gt;
! 
! &lt;?ifndef BinsOnly?&gt;    
      &lt;!-- Same goes for localized components --&gt;
      &lt;?define DocHtmlIndexGuid="B656CA5A-5179-42D8-8972-2F128AEDE751"?&gt;
      &lt;?define DocHtmlGuid="C9595172-72DF-4F30-8C43-C16583CFB8B1"?&gt;
***************
*** 46,52 ****
      &lt;?define DocHtmlRelnotesFilesGuid="D39E1662-F475-4D33-A6B5-CBC7B77891D0"?&gt;
      &lt;?define DocHtmlLogoFilesGuid="24E7F4AF-5D41-4D7B-B9DF-FA5787BAC787"?&gt;
      &lt;?define DocHtmlIndexFilesGuid="EEEA73B6-36CD-4471-BF5C-9317B90CA3CC"?&gt;
! 
  	&lt;!-- other language specific strings are defined in the strings.wxl file --&gt;	
  
      &lt;!-- /(( en_US )) --&gt;
--- 67,73 ----
      &lt;?define DocHtmlRelnotesFilesGuid="D39E1662-F475-4D33-A6B5-CBC7B77891D0"?&gt;
      &lt;?define DocHtmlLogoFilesGuid="24E7F4AF-5D41-4D7B-B9DF-FA5787BAC787"?&gt;
      &lt;?define DocHtmlIndexFilesGuid="EEEA73B6-36CD-4471-BF5C-9317B90CA3CC"?&gt;
! &lt;?endif?&gt;
  	&lt;!-- other language specific strings are defined in the strings.wxl file --&gt;	
  
      &lt;!-- /(( en_US )) --&gt;
Index: openafs/src/WINNT/install/wix/oafwbins.wxs
diff -c /dev/null openafs/src/WINNT/install/wix/oafwbins.wxs:1.1
*** /dev/null	Thu Apr 27 12:42:28 2006
--- openafs/src/WINNT/install/wix/oafwbins.wxs	Fri Apr 21 00:57:55 2006
***************
*** 0 ****
--- 1,84 ----
+ &lt;?xml version="1.0" ?&gt;
+ &lt;Wix xmlns='http://schemas.microsoft.com/wix/2003/01/wi'&gt;
+ 
+     &lt;?define BinsOnly?&gt;
+ 
+     &lt;!-- See config.wxi for the symbols that it defines/asserts --&gt;
+     &lt;?include config.wxi?&gt;
+ 
+     &lt;!-- See language_config for localization options. --&gt;
+     &lt;?include language_config.wxi?&gt;
+ 
+     &lt;!--
+       We autogenerate a new product code for each build.  According to MSDN we have
+       to change the product code whenever we change the name of the MSI file.  Each
+       version of OpenAFS has a different MSI name.  Thus, each version needs a
+       unique product code.
+       --&gt;
+     &lt;Product 
+         Id="????????-????-????-????-????????????"
+         Codepage="$(var.Codepage)"
+         Language="$(var.LanguageCode)"
+         Manufacturer="$(var.Manufacturer)"
+         Name="$(var.ProductName)"
+         UpgradeCode="A94D03E9-EF11-4B87-9B42-409016BD4B7C"
+         Version="$(var.NumericVersion)"&gt;
+ 
+ 		&lt;!--
+ 		Note that we are not specifying an explicit Package Code below.  That way WiX will
+ 		generate a new one for each build.  If an explicit one needs to be specified, use :
+ 		         Id="$(var.PackageCode)"
+ 		--&gt;
+         &lt;Package
+          Id="????????-????-????-????-????????????"
+          AdminImage="no"
+          Comments="$(var.PackageComments)"
+          Compressed="yes"
+          Description="$(var.ProductName)"
+          InstallerVersion="$(var.InstallerVersion)"
+          Keywords="Installer,OpenAFS,$(var.Manufacturer)"
+          Languages="$(var.Languages)"
+          Manufacturer="$(var.Manufacturer)"
+          Platforms="$(var.Platform)"
+          ShortNames="no"
+          SummaryCodepage="1252"
+          /&gt;
+         
+         &lt;!-- Launch conditions --&gt;
+         &lt;Condition Message="$(loc.StrLaunchCond)"&gt;
+          &lt;![CDATA[VersionNT &gt;= 500]]&gt;
+         &lt;/Condition&gt;
+ 
+         &lt;!-- Global Properties --&gt;
+         &lt;?include property.wxi?&gt;
+ 
+         &lt;!-- File system and registry settings --&gt;
+         &lt;Directory Id="TARGETDIR" Name="SourceDir"&gt;
+             &lt;?include platform.wxi?&gt;
+             &lt;?include registry.wxi?&gt;
+             &lt;?include files.wxi?&gt;
+         &lt;/Directory&gt;
+ 
+         &lt;!-- Features --&gt;
+         &lt;?include feature.wxi?&gt;
+         
+         &lt;!-- User interface --&gt;
+         &lt;?include lang\$(var.Language)\ui.wxi?&gt;
+         
+         &lt;!-- Installation Sequences --&gt;
+         &lt;AdvertiseExecuteSequence /&gt;
+         &lt;AdminExecuteSequence /&gt;
+         &lt;InstallExecuteSequence&gt;
+             &lt;RemoveExistingProducts After="InstallValidate"&gt;OPENAFSBIN_UPGRADE&lt;/RemoveExistingProducts&gt;
+         &lt;/InstallExecuteSequence&gt;
+ 
+         &lt;!-- Related producs --&gt;
+         &lt;!-- MIT's OpenAFS MSI installer --&gt;
+         &lt;Upgrade Id="A94D03E9-EF11-4B87-9B42-409016BD4B7C"&gt;
+             &lt;UpgradeVersion IgnoreRemoveFailure="no" IncludeMaximum="no" Maximum="$(var.NumericVersion)" MigrateFeatures="yes" Property="OPENAFSBIN_UPGRADE" /&gt;
+         &lt;/Upgrade&gt;
+         
+         &lt;!-- Media --&gt;
+         &lt;Media Id="1" Cabinet="disk1.cab" CompressionLevel="high" EmbedCab="yes" /&gt;
+     &lt;/Product&gt;
+ &lt;/Wix&gt;
Index: openafs/src/WINNT/install/wix/platform.wxi
diff -c openafs/src/WINNT/install/wix/platform.wxi:1.1 openafs/src/WINNT/install/wix/platform.wxi:1.2
*** openafs/src/WINNT/install/wix/platform.wxi:1.1	Tue Nov 29 19:30:50 2005
--- openafs/src/WINNT/install/wix/platform.wxi	Mon Mar 20 12:20:01 2006
***************
*** 97,102 ****
--- 97,103 ----
  	&lt;?define cmf_upserver_EXE_guid="4201E9FE-56BC-4852-992A-18E5D75C3B39"?&gt;
  	&lt;?define cmf_afsserver_CPL_guid="7B0D1145-DB1B-47BA-A874-3AB26F86FFB6"?&gt;
  	&lt;?define cmp_Server_Program_Debug_guid="1EDCDA16-216B-434E-A06E-AD1A9D40F5A2"?&gt;
+         &lt;?define rcm_binsonly_parm_guid="A4969933-E01B-476C-B923-4F2EFBA2B78C"?&gt;
  
  &lt;?elseif $(var.Platform) = "Intel"?&gt;
  	&lt;?define PISystemFolder="SystemFolder"?&gt;
***************
*** 194,199 ****
--- 195,201 ----
  	&lt;?define cmf_upserver_EXE_guid="3CBD2EF5-43BC-4CA2-B367-87E82DED1406"?&gt;
  	&lt;?define cmf_afsserver_CPL_guid="E270281E-9DB2-40A8-A418-55B4EC4A3FE7"?&gt;
  	&lt;?define cmp_Server_Program_Debug_guid="5F7BA9F7-E9BD-4AC3-9232-5EFBF6B740F8"?&gt;
+         &lt;?define rcm_binsonly_parm_guid="4DFE834A-F129-4FDD-91AD-8A31A849AF0B"?&gt;
  
  &lt;?else?&gt;
  	&lt;?error Unknown platform?&gt;
Index: openafs/src/WINNT/install/wix/property.wxi
diff -c openafs/src/WINNT/install/wix/property.wxi:1.9 openafs/src/WINNT/install/wix/property.wxi:1.10
*** openafs/src/WINNT/install/wix/property.wxi:1.9	Sun Nov 20 20:56:27 2005
--- openafs/src/WINNT/install/wix/property.wxi	Mon Mar 20 12:20:01 2006
***************
*** 1,34 ****
! ï»¿&lt;?xml version="1.0"?&gt;
  &lt;Include&gt;
  
      &lt;Property Id="AFSCELLNAME"&gt;$(var.CellName)&lt;/Property&gt;
      &lt;Property Id="LOGONOPTIONS"&gt;$(var.LogonOptions)&lt;/Property&gt;
      &lt;Property Id="FREELANCEMODE"&gt;$(var.FreelanceMode)&lt;/Property&gt;
!     &lt;Property Id="USEDNS"&gt;$(var.UseDNS)&lt;/Property&gt;
! 	&lt;Property Id="NOFINDLANABYNAME"&gt;$(var.NoFindLanaByName)&lt;/Property&gt;
! 	&lt;Property Id="MOUNTROOT"&gt;$(var.MountRoot)&lt;/Property&gt;
! 	&lt;Property Id="NETBIOSNAME"&gt;$(var.NetbiosName)&lt;/Property&gt;
! 	&lt;Property Id="RXMAXMTU"&gt;$(var.RxMaxMTU)&lt;/Property&gt;
! 	&lt;Property Id="HIDEDOTFILES"&gt;$(var.HideDotFiles)&lt;/Property&gt;
! 	&lt;Property Id="SECURITYLEVEL"&gt;$(var.SecurityLevel)&lt;/Property&gt;
! 	&lt;Property Id="CREDSSTARTUP"&gt;1&lt;/Property&gt;
! 	&lt;Property Id="CREDSAUTOINIT"&gt;-a&lt;/Property&gt;
! 	&lt;Property Id="CREDSRENEWDRMAP"&gt;-m&lt;/Property&gt;
! 	&lt;Property Id="CREDSIPCHDET"&gt;-n&lt;/Property&gt;
! 	&lt;Property Id="CREDSQUIET"&gt;-q&lt;/Property&gt;
! 	&lt;Property Id="SMBAUTHTYPE"&gt;$(var.SMBAuthType)&lt;/Property&gt;
! 	&lt;!-- empty property 
! 	&lt;Property Id="CREDSSHOW"&gt;&lt;/Property&gt;
! 	--&gt;
! 	&lt;!-- empty property
! 	&lt;Property Id="AFSCACHEPATH"&gt;&lt;/Property&gt;
! 	--&gt;
! 	&lt;!-- empty property
! 	&lt;Property Id="AFSCACHESIZE"&gt;&lt;/Property&gt;
! 	--&gt;
! 	&lt;!-- empty property
! 	&lt;Property Id="STOREANSIFILENAMES"&gt;&lt;/Property&gt;
! 	--&gt;
  
      &lt;!-- Add/remove programs --&gt;
      &lt;Property Id="ARPCOMMENTS"&gt;$(var.ProductComments)&lt;/Property&gt;
--- 1,37 ----
! &lt;?xml version="1.0"?&gt;
  &lt;Include&gt;
  
+     &lt;Property Id="NETBIOSNAME"&gt;$(var.NetbiosName)&lt;/Property&gt;
+     &lt;Property Id="USEDNS"&gt;$(var.UseDNS)&lt;/Property&gt;
      &lt;Property Id="AFSCELLNAME"&gt;$(var.CellName)&lt;/Property&gt;
+ 
+ &lt;?ifndef BinsOnly ?&gt;
      &lt;Property Id="LOGONOPTIONS"&gt;$(var.LogonOptions)&lt;/Property&gt;
      &lt;Property Id="FREELANCEMODE"&gt;$(var.FreelanceMode)&lt;/Property&gt;
!     &lt;Property Id="NOFINDLANABYNAME"&gt;$(var.NoFindLanaByName)&lt;/Property&gt;
!     &lt;Property Id="MOUNTROOT"&gt;$(var.MountRoot)&lt;/Property&gt;
!     &lt;Property Id="RXMAXMTU"&gt;$(var.RxMaxMTU)&lt;/Property&gt;
!     &lt;Property Id="HIDEDOTFILES"&gt;$(var.HideDotFiles)&lt;/Property&gt;
!     &lt;Property Id="SECURITYLEVEL"&gt;$(var.SecurityLevel)&lt;/Property&gt;
!     &lt;Property Id="CREDSSTARTUP"&gt;1&lt;/Property&gt;
!     &lt;Property Id="CREDSAUTOINIT"&gt;-a&lt;/Property&gt;
!     &lt;Property Id="CREDSRENEWDRMAP"&gt;-m&lt;/Property&gt;
!     &lt;Property Id="CREDSIPCHDET"&gt;-n&lt;/Property&gt;
!     &lt;Property Id="CREDSQUIET"&gt;-q&lt;/Property&gt;
!     &lt;Property Id="SMBAUTHTYPE"&gt;$(var.SMBAuthType)&lt;/Property&gt;
!     &lt;!-- empty property 
!     &lt;Property Id="CREDSSHOW"&gt;&lt;/Property&gt;
!     --&gt;
!     &lt;!-- empty property
!     &lt;Property Id="AFSCACHEPATH"&gt;&lt;/Property&gt;
!     --&gt;
!     &lt;!-- empty property
!     &lt;Property Id="AFSCACHESIZE"&gt;&lt;/Property&gt;
!     --&gt;
!     &lt;!-- empty property
!     &lt;Property Id="STOREANSIFILENAMES"&gt;&lt;/Property&gt;
!     --&gt;
! &lt;?endif?&gt;
  
      &lt;!-- Add/remove programs --&gt;
      &lt;Property Id="ARPCOMMENTS"&gt;$(var.ProductComments)&lt;/Property&gt;
***************
*** 44,49 ****
--- 47,53 ----
      
      &lt;Property Id="InstallMode"&gt;Typical&lt;/Property&gt;
  
+ &lt;?ifndef BinsOnly?&gt;
      &lt;Property Id="AFSCCPATCH"&gt;
        &lt;RegistrySearch Win64="$(var.Win64)" Id="rl_AFSCC_patch" Root="HKLM" Key="Software\TransarcCorporation\AFS Control Center\CurrentVersion" Name="PatchLevel" Type="registry" /&gt;
      &lt;/Property&gt;
***************
*** 116,127 ****
  	  &lt;RegistrySearch Win64="$(var.Win64)" Id="rl_NSIS_Uninst" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenAFS" Name="UninstallString" Type="registry" /&gt;
      &lt;/Property&gt;
      
-     &lt;Property Id="ABORTREASON"&gt;$(loc.StrNsisAbortReason)&lt;/Property&gt;
-     
      &lt;Property Id="OLDCELLSERVDB"&gt;
        &lt;DirectorySearch Id="dsOldCellServDB" Path="[WindowsFolder]" &gt;
          &lt;FileSearch Id="fsOldCellServDB" Name="afsdcell.ini" /&gt;
        &lt;/DirectorySearch&gt;
      &lt;/Property&gt;
  
  &lt;/Include&gt;
--- 120,133 ----
  	  &lt;RegistrySearch Win64="$(var.Win64)" Id="rl_NSIS_Uninst" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenAFS" Name="UninstallString" Type="registry" /&gt;
      &lt;/Property&gt;
      
      &lt;Property Id="OLDCELLSERVDB"&gt;
        &lt;DirectorySearch Id="dsOldCellServDB" Path="[WindowsFolder]" &gt;
          &lt;FileSearch Id="fsOldCellServDB" Name="afsdcell.ini" /&gt;
        &lt;/DirectorySearch&gt;
      &lt;/Property&gt;
  
+ &lt;?endif?&gt;
+ 
+     &lt;Property Id="ABORTREASON"&gt;$(loc.StrNsisAbortReason)&lt;/Property&gt;
+     
  &lt;/Include&gt;
Index: openafs/src/WINNT/install/wix/registry.wxi
diff -c openafs/src/WINNT/install/wix/registry.wxi:1.9 openafs/src/WINNT/install/wix/registry.wxi:1.10
*** openafs/src/WINNT/install/wix/registry.wxi:1.9	Sun Nov 20 20:56:27 2005
--- openafs/src/WINNT/install/wix/registry.wxi	Mon Mar 20 12:20:01 2006
***************
*** 3,8 ****
--- 3,9 ----
      &lt;!--
      This file will be included as a child of the root Directory tag.
      --&gt;
+ &lt;?ifndef BinsOnly ?&gt;
      &lt;Component Id="rcm_Server" Guid="$(var.rcm_server_guid)" Win64="$(var.Win64)"&gt;
          &lt;Registry Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\EventLog\Application\AFS Service" Action="createKeyAndRemoveKeyOnUninstall" Id="reg_Server"/&gt;
          &lt;Registry Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\EventLog\Application\AFS Service" Id="reg_Server3"/&gt;
***************
*** 204,208 ****
      &lt;Component Id="rcm_Loopback" Guid="$(var.rcm_loopback_guid)" Win64="$(var.Win64)"&gt;
          &lt;Registry Root="HKLM" Key="SOFTWARE\OpenAFS\Client" Name="LoopbackInstalled" Type="integer" Value="1" Id="reg_Loopback1" KeyPath="yes" /&gt;
      &lt;/Component&gt;
!     
  &lt;/Include&gt;
--- 205,236 ----
      &lt;Component Id="rcm_Loopback" Guid="$(var.rcm_loopback_guid)" Win64="$(var.Win64)"&gt;
          &lt;Registry Root="HKLM" Key="SOFTWARE\OpenAFS\Client" Name="LoopbackInstalled" Type="integer" Value="1" Id="reg_Loopback1" KeyPath="yes" /&gt;
      &lt;/Component&gt;
! &lt;?else?&gt;
!     &lt;Component Id="rcm_BinsOnly_Parm" Guid="$(var.rcm_client_guid)" Win64="$(var.Win64)"&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries" KeyPath="yes" Id="reg_Control_Center2" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries" Action="createKeyAndRemoveKeyOnUninstall" Id="reg_Control_Center" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Action="createKeyAndRemoveKeyOnUninstall" Id="reg_Control_Center3" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="MinorVersion" Type="integer" Value="$(var.VersionMinor)" Id="reg_Control_Center4" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Id="reg_Control_Center5" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="PatchLevel" Type="integer" Value="$(var.VersionPatch)" Id="reg_Control_Center6" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="MajorVersion" Type="integer" Value="$(var.VersionMajor)" Id="reg_Control_Center7" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="ReleaseType" Type="string" Value="$(var.ReleaseType)" Id="reg_Control_Center8" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="Software Type" Type="string" Value="File System" Id="reg_Control_Center9" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="PathName" Type="string" Value="[AFSDIR]Control Center" Id="reg_Control_Center10" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="VersionString" Type="string" Value="$(var.NumericVersion)" Id="reg_Control_Center11" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="InstallDateString" Type="string" Value="$(var.InstallTimestamp)" Id="reg_Control_Center13" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\CurrentVersion" Name="Description" Type="string" Value="$(loc.StrAFSCCDesc)" Id="reg_Control_Center14" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Action="createKeyAndRemoveKeyOnUninstall" Id="reg_Control_Center16" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="MinorVersion" Type="integer" Value="$(var.VersionMinor)" Id="reg_Control_Center17" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Id="reg_Control_Center18" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="PatchLevel" Type="integer" Value="$(var.VersionPatch)" Id="reg_Control_Center19" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="MajorVersion" Type="integer" Value="$(var.VersionMajor)" Id="reg_Control_Center20" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="ReleaseType" Type="string" Value="$(var.ReleaseType)" Id="reg_Control_Center21" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="Software Type" Type="string" Value="File System" Id="reg_Control_Center22" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="PathName" Type="string" Value="[AFSDIR]Control Center" Id="reg_Control_Center23" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="VersionString" Type="string" Value="$(var.NumericVersion)" Id="reg_Control_Center24" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="InstallDateString" Type="string" Value="$(var.InstallTimestamp)" Id="reg_Control_Center26" /&gt;
!         &lt;Registry Root="HKLM" Key="SOFTWARE\TransarcCorporation\AFS Client 32-Bit Binaries\$(var.NumericVersion)" Name="Description" Type="string" Value="$(loc.StrAFSCCDesc)" Id="reg_Control_Center27" /&gt;
!     &lt;/Component&gt;
! &lt;?endif?&gt;
  &lt;/Include&gt;
Index: openafs/src/WINNT/install/wix/lang/en_US/strings.wxl
diff -c openafs/src/WINNT/install/wix/lang/en_US/strings.wxl:1.5 openafs/src/WINNT/install/wix/lang/en_US/strings.wxl:1.6
*** openafs/src/WINNT/install/wix/lang/en_US/strings.wxl:1.5	Sun Nov 20 20:56:29 2005
--- openafs/src/WINNT/install/wix/lang/en_US/strings.wxl	Mon Mar 20 12:20:06 2006
***************
*** 25,30 ****
--- 25,32 ----
      &lt;String Id="StrAFSOptDesc"&gt;Optional components&lt;/String&gt;
      &lt;String Id="StrLoopbackDesc"&gt;Loopback adapter&lt;/String&gt;
      &lt;String Id="StrLoopbackLongDesc"&gt;Loopback adapter for AFS.  It is recommended that you install the loopback adapter if you are installing the client components.&lt;/String&gt;
+     &lt;String Id="StrBinsOnlyLongDesc"&gt;OpenAFS command-line utilities and libraries.&lt;/String&gt;
+     &lt;String Id="StrBinsOnlyDesc"&gt;Tools and libraries&lt;/String&gt;
  
      &lt;String Id="StrShlExtDesc"&gt;AFS Context Menu Shell Extension&lt;/String&gt;
      &lt;String Id="StrAfsCredsDesc"&gt;Authentication for AFS&lt;/String&gt;
Index: openafs/src/WINNT/pthread/pthread.c
diff -c openafs/src/WINNT/pthread/pthread.c:1.10 openafs/src/WINNT/pthread/pthread.c:1.11
*** openafs/src/WINNT/pthread/pthread.c:1.10	Sun Nov  6 04:29:41 2005
--- openafs/src/WINNT/pthread/pthread.c	Mon Apr 24 10:25:12 2006
***************
*** 260,265 ****
--- 260,283 ----
      pthread_cache_done = 1;
  }
  
+ static void cleanup_pthread_cache(void) {
+     thread_p cur = NULL, next = NULL;
+ 
+     if (pthread_cache_done) {
+ 	for(queue_Scan(&amp;active_Q, cur, next, thread)) {
+ 	    queue_Remove(cur);
+ 	}
+ 	for(queue_Scan(&amp;cache_Q, cur, next, thread)) {
+ 	    queue_Remove(cur);
+ 	}
+ 
+ 	pthread_mutex_destroy(&amp;active_Q_mutex);
+ 	pthread_mutex_destroy(&amp;cache_Q_mutex);
+ 
+ 	pthread_cache_done = 0;
+     }
+ }	
+ 
  static void put_thread(thread_p old) {
   
      CloseHandle(old-&gt;t_handle);
***************
*** 360,365 ****
--- 378,400 ----
      } while(call_more_destructors);
  }
  
+ static void cleanup_global_tsd(void)
+ {
+     thread_p cur = NULL, next = NULL;
+ 
+     if (tsd_done) {
+ 	for(queue_Scan(&amp;active_Q, cur, next, thread)) {
+ 	    tsd_free_all(cur-&gt;tsd);
+ 	}
+ 
+ 	TlsFree(tsd_pthread_index);
+ 	tsd_pthread_index = 0xFFFFFFFF;
+ 	TlsFree(tsd_index);
+ 	tsd_index = 0xFFFFFFFF;
+ 	tsd_done = 0;
+     }
+ }
+ 
  static DWORD WINAPI afs_pthread_create_stub(LPVOID param) {
      pthread_create_t *t = (pthread_create_t *) param;
      void *rc;
***************
*** 700,709 ****
   
  static void init_waiter_cache(void) {
      InitializeCriticalSection(&amp;waiter_cache_cs);
-     waiter_cache_init = 1;
      queue_Init(&amp;waiter_cache);
  }
   
  static cond_waiters_t *get_waiter() {
      cond_waiters_t *new = NULL;
   
--- 735,761 ----
   
  static void init_waiter_cache(void) {
      InitializeCriticalSection(&amp;waiter_cache_cs);
      queue_Init(&amp;waiter_cache);
+     waiter_cache_init = 1;
  }
   
+ static void cleanup_waiter_cache(void)
+ {
+     cond_waiters_t * cur = NULL, * next = NULL;
+ 
+     if (waiter_cache_init) {
+ 	for(queue_Scan(&amp;waiter_cache, cur, next, cond_waiter)) {
+ 	    queue_Remove(cur);
+ 
+ 	    CloseHandle(cur-&gt;event);
+ 	    free(cur);
+ 	}
+ 
+ 	DeleteCriticalSection(&amp;waiter_cache_cs);
+ 	waiter_cache_init = 0;
+     }
+ }
+ 
  static cond_waiters_t *get_waiter() {
      cond_waiters_t *new = NULL;
   
***************
*** 1257,1259 ****
--- 1309,1345 ----
      RaiseException(PTHREAD_EXIT_EXCEPTION, 0, 0, NULL);
  
  }
+ 
+ /*
+  * DllMain() -- Entry-point function called by the DllMainCRTStartup()
+  *     function in the MSVC runtime DLL (msvcrt.dll).
+  *
+  *     Note: the system serializes calls to this function.
+  */
+ BOOL WINAPI
+ DllMain(HINSTANCE dllInstHandle,/* instance handle for this DLL module */
+         DWORD reason,           /* reason function is being called */
+         LPVOID reserved)
+ {                               /* reserved for future use */
+     switch (reason) {
+     case DLL_PROCESS_ATTACH:
+         /* library is being attached to a process */
+         /* disable thread attach/detach notifications */
+         (void)DisableThreadLibraryCalls(dllInstHandle);
+ 
+ 	pthread_once(&amp;pthread_cache_once, create_once);
+ 	pthread_once(&amp;global_tsd_once, tsd_once);
+ 	pthread_once(&amp;waiter_cache_once, init_waiter_cache);
+ 	return TRUE;
+ 
+     case DLL_PROCESS_DETACH:
+ 	cleanup_waiter_cache();
+ 	cleanup_global_tsd();
+ 	cleanup_pthread_cache();
+         return TRUE;
+ 
+     default:
+         return FALSE;
+     }
+ }
+ 
Index: openafs/src/WINNT/pthread/pthread.def
diff -c openafs/src/WINNT/pthread/pthread.def:1.1 openafs/src/WINNT/pthread/pthread.def:1.2
*** openafs/src/WINNT/pthread/pthread.def:1.1	Fri Nov  3 21:21:36 2000
--- openafs/src/WINNT/pthread/pthread.def	Mon Apr 24 10:25:12 2006
***************
*** 25,27 ****
--- 25,28 ----
  	pthread_attr_getdetachstate			@23
  	pthread_attr_setdetachstate			@24
  	pthread_exit					@25
+ 	DllMain						@26
Index: openafs/src/afs/NTMakefile
diff -c openafs/src/afs/NTMakefile:1.3 openafs/src/afs/NTMakefile:1.4
*** openafs/src/afs/NTMakefile:1.3	Fri Nov 21 03:00:16 2003
--- openafs/src/afs/NTMakefile	Sat Mar  4 16:41:33 2006
***************
*** 12,21 ****
  ################################################
  # compile_et to get unified_afs.h
  
! $(DESTDIR)\include\afs\unified_afs.c $(DESTDIR)\include\afs\unified_afs.h:   unified_afs.et  unified_afs.p.h
     $(DEL) unified_afs.c unified_afs.h
     $(COMPILE_ET) unified_afs -h unified_afs
     $(COPY) unified_afs.h $(DESTDIR)\include\afs
  
! install: $(DESTDIR)\include\afs\unified_afs.c 
  
--- 12,23 ----
  ################################################
  # compile_et to get unified_afs.h
  
! INCDIR=$(DESTDIR)\include\
! 
! $(INCDIR)\afs\unified_afs.c $(INCDIR)\afs\unified_afs.h:   unified_afs.et  unified_afs.p.h
     $(DEL) unified_afs.c unified_afs.h
     $(COMPILE_ET) unified_afs -h unified_afs
     $(COPY) unified_afs.h $(DESTDIR)\include\afs
  
! install: $(INCDIR)\afs\unified_afs.c $(INCDIR)\afs\afs_stats.h
  
Index: openafs/src/afs/afs_callback.c
diff -c openafs/src/afs/afs_callback.c:1.37 openafs/src/afs/afs_callback.c:1.39
*** openafs/src/afs/afs_callback.c:1.37	Tue Jan 24 12:32:43 2006
--- openafs/src/afs/afs_callback.c	Fri Mar 17 14:44:06 2006
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_callback.c,v 1.37 2006/01/24 17:32:43 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_callback.c,v 1.39 2006/03/17 19:44:06 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 384,389 ****
--- 384,392 ----
      register int i;
      struct VenusFid localFid;
      struct volume *tv;
+ #ifdef AFS_DARWIN80_ENV
+     vnode_t vp;
+ #endif
  
      AFS_STATCNT(ClearCallBack);
  
***************
*** 407,412 ****
--- 410,417 ----
  	     * Clear callback for the whole volume.  Zip through the
  	     * hash chain, nullifying entries whose volume ID matches.
  	     */
+ loop1:
+ 		ObtainReadLock(&amp;afs_xvcache);
  		i = VCHashV(&amp;localFid);
  		for (tq = afs_vhashTV[i].prev; tq != &amp;afs_vhashTV[i]; tq = uq) {
  		    uq = QPrev(tq);
***************
*** 416,421 ****
--- 421,460 ----
  			if (!localFid.Cell)
  			    localFid.Cell = tvc-&gt;fid.Cell;
  			tvc-&gt;dchint = NULL;	/* invalidate hints */
+ 			if (tvc-&gt;states &amp; CVInit) {
+ 			    ReleaseReadLock(&amp;afs_xvcache);
+ 			    afs_osi_Sleep(&amp;tvc-&gt;states);
+ 			    goto loop1;
+ 			}
+ #ifdef AFS_DARWIN80_ENV
+ 			if (tvc-&gt;states &amp; CDeadVnode) {
+ 			    ReleaseReadLock(&amp;afs_xvcache);
+ 			    afs_osi_Sleep(&amp;tvc-&gt;states);
+ 			    goto loop1;
+ 			}
+ #endif
+ #if     defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV)  || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
+ 			VN_HOLD(AFSTOV(tvc));
+ #else
+ #ifdef AFS_DARWIN80_ENV
+ 			vp = AFSTOV(tvc);
+ 			if (vnode_get(vp))
+ 			    continue;
+ 			if (vnode_ref(vp)) {
+ 			    AFS_GUNLOCK();
+ 			    vnode_put(vp);
+ 			    AFS_GLOCK();
+ 			    continue;
+ 			}
+ #else
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+ 			osi_vnhold(tvc, 0);
+ #else
+ 			VREFCOUNT_INC(tvc); /* AIX, apparently */
+ #endif
+ #endif
+ #endif
+ 			ReleaseReadLock(&amp;afs_xvcache);
  			ObtainWriteLock(&amp;afs_xcbhash, 449);
  			afs_DequeueCallback(tvc);
  			tvc-&gt;states &amp;= ~(CStatd | CUnique | CBulkFetching);
***************
*** 425,437 ****
  			else
  			    afs_evenCBs++;
  			ReleaseWriteLock(&amp;afs_xcbhash);
! 			if (!(tvc-&gt;states &amp; CVInit) &amp;&amp;
! 			    (tvc-&gt;fid.Fid.Vnode &amp; 1 || (vType(tvc) == VDIR)))
  			    osi_dnlc_purgedp(tvc);
  			afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
  				   ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
  				   tvc-&gt;states, ICL_TYPE_INT32,
  				   a_fid-&gt;Volume);
  		    } else if ((tvc-&gt;states &amp; CMValid)
  			       &amp;&amp; (tvc-&gt;mvid-&gt;Fid.Volume == a_fid-&gt;Volume)) {
  			tvc-&gt;states &amp;= ~CMValid;
--- 464,481 ----
  			else
  			    afs_evenCBs++;
  			ReleaseWriteLock(&amp;afs_xcbhash);
! 			if ((tvc-&gt;fid.Fid.Vnode &amp; 1 || (vType(tvc) == VDIR)))
  			    osi_dnlc_purgedp(tvc);
  			afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
  				   ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
  				   tvc-&gt;states, ICL_TYPE_INT32,
  				   a_fid-&gt;Volume);
+ #ifdef AFS_DARWIN80_ENV
+ 			vnode_put(AFSTOV(tvc));
+ #endif
+ 			ObtainReadLock(&amp;afs_xvcache);
+ 			uq = QPrev(tq);
+ 			AFS_FAST_RELE(tvc);
  		    } else if ((tvc-&gt;states &amp; CMValid)
  			       &amp;&amp; (tvc-&gt;mvid-&gt;Fid.Volume == a_fid-&gt;Volume)) {
  			tvc-&gt;states &amp;= ~CMValid;
***************
*** 439,444 ****
--- 483,489 ----
  			    localFid.Cell = tvc-&gt;mvid-&gt;Cell;
  		    }
  		}
+ 		ReleaseReadLock(&amp;afs_xvcache);
  
  	    /*
  	     * XXXX Don't hold any locks here XXXX
***************
*** 454,477 ****
  	    /*
  	     * Clear callbacks just for the one file.
  	     */
  	    afs_allCBs++;
  	    if (a_fid-&gt;Vnode &amp; 1)
  		afs_oddCBs++;	/*Could do this on volume basis, too */
  	    else
  		afs_evenCBs++;	/*A particular fid was specified */
  	    i = VCHash(&amp;localFid);
! 	    for (tvc = afs_vhashT[i]; tvc; tvc = tvc-&gt;hnext) {
  		if (tvc-&gt;fid.Fid.Vnode == a_fid-&gt;Vnode
  		    &amp;&amp; tvc-&gt;fid.Fid.Volume == a_fid-&gt;Volume
  		    &amp;&amp; tvc-&gt;fid.Fid.Unique == a_fid-&gt;Unique) {
  		    tvc-&gt;callback = NULL;
  		    tvc-&gt;dchint = NULL;	/* invalidate hints */
  		    ObtainWriteLock(&amp;afs_xcbhash, 450);
  		    afs_DequeueCallback(tvc);
  		    tvc-&gt;states &amp;= ~(CStatd | CUnique | CBulkFetching);
  		    ReleaseWriteLock(&amp;afs_xcbhash);
! 		    if (!(tvc-&gt;states &amp; CVInit) &amp;&amp;
! 		        (tvc-&gt;fid.Fid.Vnode &amp; 1 || (vType(tvc) == VDIR)))
  			osi_dnlc_purgedp(tvc);
  		    afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
  			       ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
--- 499,559 ----
  	    /*
  	     * Clear callbacks just for the one file.
  	     */
+ 	    struct vcache *uvc;
  	    afs_allCBs++;
  	    if (a_fid-&gt;Vnode &amp; 1)
  		afs_oddCBs++;	/*Could do this on volume basis, too */
  	    else
  		afs_evenCBs++;	/*A particular fid was specified */
+ loop2:
+ 	    ObtainReadLock(&amp;afs_xvcache);
  	    i = VCHash(&amp;localFid);
! 	    for (tvc = afs_vhashT[i]; tvc; tvc = uvc) {
! 		uvc = tvc-&gt;hnext;
  		if (tvc-&gt;fid.Fid.Vnode == a_fid-&gt;Vnode
  		    &amp;&amp; tvc-&gt;fid.Fid.Volume == a_fid-&gt;Volume
  		    &amp;&amp; tvc-&gt;fid.Fid.Unique == a_fid-&gt;Unique) {
  		    tvc-&gt;callback = NULL;
  		    tvc-&gt;dchint = NULL;	/* invalidate hints */
+ 		    if (tvc-&gt;states &amp; CVInit) {
+ 			ReleaseReadLock(&amp;afs_xvcache);
+ 			afs_osi_Sleep(&amp;tvc-&gt;states);
+ 			goto loop2;
+ 		    }
+ #ifdef AFS_DARWIN80_ENV
+ 		    if (tvc-&gt;states &amp; CDeadVnode) {
+ 			ReleaseReadLock(&amp;afs_xvcache);
+ 			afs_osi_Sleep(&amp;tvc-&gt;states);
+ 			goto loop2;
+ 		    }
+ #endif
+ #if     defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV)  || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
+ 		    VN_HOLD(AFSTOV(tvc));
+ #else
+ #ifdef AFS_DARWIN80_ENV
+ 		    vp = AFSTOV(tvc);
+ 		    if (vnode_get(vp))
+ 			continue;
+ 		    if (vnode_ref(vp)) {
+ 			AFS_GUNLOCK();
+ 			vnode_put(vp);
+ 			AFS_GLOCK();
+ 			continue;
+ 		    }
+ #else
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+ 		    osi_vnhold(tvc, 0);
+ #else
+ 		    VREFCOUNT_INC(tvc); /* AIX, apparently */
+ #endif
+ #endif
+ #endif
+ 		    ReleaseReadLock(&amp;afs_xvcache);
  		    ObtainWriteLock(&amp;afs_xcbhash, 450);
  		    afs_DequeueCallback(tvc);
  		    tvc-&gt;states &amp;= ~(CStatd | CUnique | CBulkFetching);
  		    ReleaseWriteLock(&amp;afs_xcbhash);
! 		    if ((tvc-&gt;fid.Fid.Vnode &amp; 1 || (vType(tvc) == VDIR)))
  			osi_dnlc_purgedp(tvc);
  		    afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
  			       ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
***************
*** 481,488 ****
--- 563,577 ----
  		    lastCallBack_dv = tvc-&gt;mstat.DataVersion.low;
  		    osi_GetuTime(&amp;lastCallBack_time);
  #endif /* CBDEBUG */
+ #ifdef AFS_DARWIN80_ENV
+ 		    vnode_put(AFSTOV(tvc));
+ #endif
+ 		    ObtainReadLock(&amp;afs_xvcache);
+ 		    uvc = tvc-&gt;hnext;
+ 		    AFS_FAST_RELE(tvc);
  		}
  	    }			/*Walk through hash table */
+ 	    ReleaseReadLock(&amp;afs_xvcache);
  	}			/*Clear callbacks for one file */
      }
  
***************
*** 1544,1550 ****
  }
  
  
! #ifdef AFS_LINUX24_ENV
  extern struct vcache *afs_globalVp;
  
  int recurse_dcache_parent(parent, a_index, addr, inode, flags, time, fileName)
--- 1633,1639 ----
  }
  
  
! #if 0 &amp;&amp; defined(AFS_LINUX24_ENV)
  extern struct vcache *afs_globalVp;
  
  int recurse_dcache_parent(parent, a_index, addr, inode, flags, time, fileName)
***************
*** 1616,1622 ****
      char ** fileName;
  { /*SRXAFSCB_GetDE*/
      int code = 0;				/*Return code*/
! #ifdef AFS_LINUX24_ENV
      register int i;			/*Loop variable*/
      register struct vcache *tvc = afs_globalVp;
      struct dentry *dentry;
--- 1705,1711 ----
      char ** fileName;
  { /*SRXAFSCB_GetDE*/
      int code = 0;				/*Return code*/
! #if 0 &amp;&amp; defined(AFS_LINUX24_ENV)
      register int i;			/*Loop variable*/
      register struct vcache *tvc = afs_globalVp;
      struct dentry *dentry;
Index: openafs/src/afs/afs_cbqueue.c
diff -c openafs/src/afs/afs_cbqueue.c:1.12 openafs/src/afs/afs_cbqueue.c:1.13
*** openafs/src/afs/afs_cbqueue.c:1.12	Fri Feb 17 16:57:12 2006
--- openafs/src/afs/afs_cbqueue.c	Thu Mar  2 01:42:47 2006
***************
*** 75,81 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_cbqueue.c,v 1.12 2006/02/17 21:57:12 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 75,81 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_cbqueue.c,v 1.13 2006/03/02 06:42:47 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 220,226 ****
  			     * write locking tvc? */
  			    QRemove(tq);
  			    tvc-&gt;states &amp;= ~(CStatd | CMValid | CUnique);
!                             if (!(tvc-&gt;states &amp; CVInit) &amp;&amp;
                                  (tvc-&gt;fid.Fid.Vnode &amp; 1 ||
                                   (vType(tvc) == VDIR)))
  				osi_dnlc_purgedp(tvc);
--- 220,226 ----
  			     * write locking tvc? */
  			    QRemove(tq);
  			    tvc-&gt;states &amp;= ~(CStatd | CMValid | CUnique);
!                             if (!(tvc-&gt;states &amp; (CVInit|CVFlushed)) &amp;&amp;
                                  (tvc-&gt;fid.Fid.Vnode &amp; 1 ||
                                   (vType(tvc) == VDIR)))
  				osi_dnlc_purgedp(tvc);
***************
*** 237,243 ****
  		 */
  		QRemove(tq);
  		tvc-&gt;states &amp;= ~(CStatd | CMValid | CUnique);
!                 if (!(tvc-&gt;states &amp; CVInit) &amp;&amp;
                      (tvc-&gt;fid.Fid.Vnode &amp; 1 || (vType(tvc) == VDIR)))
  		    osi_dnlc_purgedp(tvc);
  	    }
--- 237,243 ----
  		 */
  		QRemove(tq);
  		tvc-&gt;states &amp;= ~(CStatd | CMValid | CUnique);
!                 if (!(tvc-&gt;states &amp; (CVInit|CVFlushed)) &amp;&amp;
                      (tvc-&gt;fid.Fid.Vnode &amp; 1 || (vType(tvc) == VDIR)))
  		    osi_dnlc_purgedp(tvc);
  	    }
***************
*** 310,316 ****
  	    tvc-&gt;states &amp;= ~(CStatd);
  	    if (QPrev(&amp;(tvc-&gt;callsort)))
  		QRemove(&amp;(tvc-&gt;callsort));
! 	    if (!(tvc-&gt;states &amp; CVInit) &amp;&amp;
                  ((tvc-&gt;fid.Fid.Vnode &amp; 1) || (vType(tvc) == VDIR)))
  		osi_dnlc_purgedp(tvc);
  	}
--- 310,316 ----
  	    tvc-&gt;states &amp;= ~(CStatd);
  	    if (QPrev(&amp;(tvc-&gt;callsort)))
  		QRemove(&amp;(tvc-&gt;callsort));
! 	    if (!(tvc-&gt;states &amp; (CVInit|CVFlushed)) &amp;&amp;
                  ((tvc-&gt;fid.Fid.Vnode &amp; 1) || (vType(tvc) == VDIR)))
  		osi_dnlc_purgedp(tvc);
  	}
***************
*** 339,345 ****
  		tvc-&gt;callback = 0;
  		tvc-&gt;dchint = NULL;	/* invalidate hints */
  		tvc-&gt;states &amp;= ~(CStatd);
! 		if (!(tvc-&gt;states &amp; CVInit) &amp;&amp;
                      ((tvc-&gt;fid.Fid.Vnode &amp; 1) || (vType(tvc) == VDIR))) {
  		    osi_dnlc_purgedp(tvc);
  		}
--- 339,345 ----
  		tvc-&gt;callback = 0;
  		tvc-&gt;dchint = NULL;	/* invalidate hints */
  		tvc-&gt;states &amp;= ~(CStatd);
! 		if (!(tvc-&gt;states &amp; (CVInit|CVFlushed)) &amp;&amp;
                      ((tvc-&gt;fid.Fid.Vnode &amp; 1) || (vType(tvc) == VDIR))) {
  		    osi_dnlc_purgedp(tvc);
  		}
Index: openafs/src/afs/afs_chunk.c
diff -c openafs/src/afs/afs_chunk.c:1.7 openafs/src/afs/afs_chunk.c:1.8
*** openafs/src/afs/afs_chunk.c:1.7	Wed Aug 17 12:16:50 2005
--- openafs/src/afs/afs_chunk.c	Mon Feb 20 16:49:17 2006
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_chunk.c,v 1.7 2005/08/17 16:16:50 rees Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_chunk.c,v 1.8 2006/02/20 21:49:17 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 24,29 ****
  
  /* Place the defaults in afsd instead of all around the code, so
   * AFS_SETCHUNKSIZE() needs to be called before doing anything */
! afs_int32 afs_FirstCSize = 0;
! afs_int32 afs_OtherCSize = 0;
! afs_int32 afs_LogChunk = 0;
--- 24,29 ----
  
  /* Place the defaults in afsd instead of all around the code, so
   * AFS_SETCHUNKSIZE() needs to be called before doing anything */
! afs_int32 afs_FirstCSize = AFS_DEFAULTCSIZE;
! afs_int32 afs_OtherCSize = AFS_DEFAULTCSIZE;
! afs_int32 afs_LogChunk = AFS_DEFAULTLSIZE;
Index: openafs/src/afs/afs_daemons.c
diff -c openafs/src/afs/afs_daemons.c:1.41 openafs/src/afs/afs_daemons.c:1.43
*** openafs/src/afs/afs_daemons.c:1.41	Mon Feb 13 13:29:26 2006
--- openafs/src/afs/afs_daemons.c	Thu Mar 30 12:13:39 2006
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_daemons.c,v 1.41 2006/02/13 18:29:26 shadow Exp $");
  
  #ifdef AFS_AIX51_ENV
  #define __FULL_PROTO
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_daemons.c,v 1.43 2006/03/30 17:13:39 rees Exp $");
  
  #ifdef AFS_AIX51_ENV
  #define __FULL_PROTO
***************
*** 46,59 ****
  afs_int32 afs_gcpags_procsize = 0;
  
  afs_int32 afs_CheckServerDaemonStarted = 0;
! #ifdef DEFAULT_PROBE_INTERVAL
! afs_int32 PROBE_INTERVAL = DEFAULT_PROBE_INTERVAL;	/* overridding during compile */
! #else
! afs_int32 PROBE_INTERVAL = 180;	/* default to 3 min */
  #endif
  
! #define PROBE_WAIT() (1000 * (PROBE_INTERVAL - ((afs_random() &amp; 0x7fffffff) \
! 		      % (PROBE_INTERVAL/2))))
  
  void
  afs_CheckServerDaemon(void)
--- 46,79 ----
  afs_int32 afs_gcpags_procsize = 0;
  
  afs_int32 afs_CheckServerDaemonStarted = 0;
! #ifndef DEFAULT_PROBE_INTERVAL
! #define DEFAULT_PROBE_INTERVAL 180	/* default to 3 min */
  #endif
+ afs_int32 afs_probe_interval = DEFAULT_PROBE_INTERVAL;
+ afs_int32 afs_probe_all_interval = 600;
+ afs_int32 afs_nat_probe_interval = 60;
+ 
+ #define PROBE_WAIT() (1000 * (afs_probe_interval - ((afs_random() &amp; 0x7fffffff) \
+ 		      % (afs_probe_interval/2))))
+ 
+ void
+ afs_SetCheckServerNATmode(int isnat)
+ {
+     static afs_int32 old_intvl, old_all_intvl;
+     static int wasnat;
  
!     if (isnat &amp;&amp; !wasnat) {
! 	old_intvl = afs_probe_interval;
! 	old_all_intvl = afs_probe_all_interval;
! 	afs_probe_interval = afs_nat_probe_interval;
! 	afs_probe_all_interval = afs_nat_probe_interval;
! 	afs_osi_CancelWait(&amp;AFS_CSWaitHandler);
!     } else if (!isnat &amp;&amp; wasnat) {
! 	afs_probe_interval = old_intvl;
! 	afs_probe_all_interval = old_all_intvl;
!     }
!     wasnat = isnat;
! }
  
  void
  afs_CheckServerDaemon(void)
***************
*** 75,87 ****
  	}
  
  	now = osi_Time();
! 	if (PROBE_INTERVAL + lastCheck &lt;= now) {
  	    afs_CheckServers(1, NULL);	/* check down servers */
  	    lastCheck = now = osi_Time();
  	}
  
! 	if (600 + last10MinCheck &lt;= now) {
! 	    afs_Trace1(afs_iclSetp, CM_TRACE_PROBEUP, ICL_TYPE_INT32, 600);
  	    afs_CheckServers(0, NULL);
  	    last10MinCheck = now = osi_Time();
  	}
--- 95,107 ----
  	}
  
  	now = osi_Time();
! 	if (afs_probe_interval + lastCheck &lt;= now) {
  	    afs_CheckServers(1, NULL);	/* check down servers */
  	    lastCheck = now = osi_Time();
  	}
  
! 	if (afs_probe_all_interval + last10MinCheck &lt;= now) {
! 	    afs_Trace1(afs_iclSetp, CM_TRACE_PROBEUP, ICL_TYPE_INT32, afs_probe_all_interval);
  	    afs_CheckServers(0, NULL);
  	    last10MinCheck = now = osi_Time();
  	}
***************
*** 93,101 ****
  	}
  
  	/* Compute time to next probe. */
! 	delay = PROBE_INTERVAL + lastCheck;
! 	if (delay &gt; 600 + last10MinCheck)
! 	    delay = 600 + last10MinCheck;
  	delay -= now;
  	if (delay &lt; 1)
  	    delay = 1;
--- 113,121 ----
  	}
  
  	/* Compute time to next probe. */
! 	delay = afs_probe_interval + lastCheck;
! 	if (delay &gt; afs_probe_all_interval + last10MinCheck)
! 	    delay = afs_probe_all_interval + last10MinCheck;
  	delay -= now;
  	if (delay &lt; 1)
  	    delay = 1;
***************
*** 197,203 ****
  		cs_warned = 1;
  		printf("Please install afsd with check server daemon.\n");
  	    }
! 	    if (lastNMinCheck + PROBE_INTERVAL &lt; now) {
  		/* only check down servers */
  		afs_CheckServers(1, NULL);
  		lastNMinCheck = now;
--- 217,223 ----
  		cs_warned = 1;
  		printf("Please install afsd with check server daemon.\n");
  	    }
! 	    if (lastNMinCheck + afs_probe_interval &lt; now) {
  		/* only check down servers */
  		afs_CheckServers(1, NULL);
  		lastNMinCheck = now;
Index: openafs/src/afs/afs_pioctl.c
diff -c openafs/src/afs/afs_pioctl.c:1.108 openafs/src/afs/afs_pioctl.c:1.110
*** openafs/src/afs/afs_pioctl.c:1.108	Fri Feb 17 23:08:04 2006
--- openafs/src/afs/afs_pioctl.c	Thu Mar  2 17:34:27 2006
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.108 2006/02/18 04:08:04 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifdef AFS_OBSD_ENV
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.110 2006/03/02 22:34:27 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifdef AFS_OBSD_ENV
***************
*** 1945,1956 ****
  	pcheck = (struct chservinfo *)ain;
  	if (pcheck-&gt;tinterval &gt;= 0) {
  	    cp = aout;
! 	    memcpy(cp, (char *)&amp;PROBE_INTERVAL, sizeof(afs_int32));
  	    *aoutSize = sizeof(afs_int32);
  	    if (pcheck-&gt;tinterval &gt; 0) {
  		if (!afs_osi_suser(*acred))
  		    return EACCES;
! 		PROBE_INTERVAL = pcheck-&gt;tinterval;
  	    }
  	    return 0;
  	}
--- 1945,1956 ----
  	pcheck = (struct chservinfo *)ain;
  	if (pcheck-&gt;tinterval &gt;= 0) {
  	    cp = aout;
! 	    memcpy(cp, (char *)&amp;afs_probe_interval, sizeof(afs_int32));
  	    *aoutSize = sizeof(afs_int32);
  	    if (pcheck-&gt;tinterval &gt; 0) {
  		if (!afs_osi_suser(*acred))
  		    return EACCES;
! 		afs_probe_interval = pcheck-&gt;tinterval;
  	    }
  	    return 0;
  	}
***************
*** 2570,2575 ****
--- 2570,2576 ----
      ObtainReadLock(&amp;afs_xvcache);
      i = VCHashV(&amp;avc-&gt;fid);
      for (tq = afs_vhashTV[i].prev; tq != &amp;afs_vhashTV[i]; tq = uq) {
+ 	    uq = QPrev(tq);
  	    tvc = QTOVH(tq);
  	    if (tvc-&gt;fid.Fid.Volume == volume &amp;&amp; tvc-&gt;fid.Cell == cell) {
  		if (tvc-&gt;states &amp; CVInit) {
***************
*** 2629,2636 ****
  		uq = QPrev(tq);
  		/* our tvc ptr is still good until now */
  		AFS_FAST_RELE(tvc);
- 	    } else {
- 		uq = QPrev(tq);
  	    }
  	}
      ReleaseReadLock(&amp;afs_xvcache);
--- 2630,2635 ----
Index: openafs/src/afs/afs_prototypes.h
diff -c openafs/src/afs/afs_prototypes.h:1.72 openafs/src/afs/afs_prototypes.h:1.74
*** openafs/src/afs/afs_prototypes.h:1.72	Fri Feb 17 23:58:28 2006
--- openafs/src/afs/afs_prototypes.h	Wed Apr  5 12:04:27 2006
***************
*** 268,274 ****
  extern afs_int32 afs_gcpags;
  extern afs_int32 afs_gcpags_procsize;
  extern afs_int32 afs_CheckServerDaemonStarted;
! extern afs_int32 PROBE_INTERVAL;
  
  extern void afs_Daemon(void);
  extern struct brequest *afs_BQueue(register short aopcode,
--- 268,274 ----
  extern afs_int32 afs_gcpags;
  extern afs_int32 afs_gcpags_procsize;
  extern afs_int32 afs_CheckServerDaemonStarted;
! extern afs_int32 afs_probe_interval;
  
  extern void afs_Daemon(void);
  extern struct brequest *afs_BQueue(register short aopcode,
***************
*** 771,776 ****
--- 771,777 ----
  
  
  /* afs_util.c */
+ extern afs_int32 afs_calc_inum (afs_int32 volume, afs_int32 vnode);
  #ifndef afs_cv2string
  extern char *afs_cv2string(char *ttp, afs_uint32 aval);
  #endif
Index: openafs/src/afs/afs_util.c
diff -c openafs/src/afs/afs_util.c:1.22 openafs/src/afs/afs_util.c:1.28
*** openafs/src/afs/afs_util.c:1.22	Thu Oct 13 11:12:07 2005
--- openafs/src/afs/afs_util.c	Wed Apr 26 11:03:20 2006
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_util.c,v 1.22 2005/10/13 15:12:07 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 16,22 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_util.c,v 1.28 2006/04/26 15:03:20 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 51,56 ****
--- 51,62 ----
  #include &lt;sys/fp_io.h&gt;
  #endif
  
+ #if	defined(AFS_XBSD_ENV)
+ #include &lt;crypto/md5.h&gt;
+ #endif
+ 
+ afs_int32 afs_new_inum = 0;
+ 
  #ifndef afs_cv2string
  char *
  afs_cv2string(char *ttp, afs_uint32 aval)
***************
*** 262,269 ****
      register int i;
  
      afs_warn("Looking for locked data structures.\n");
!     afs_warn("conn %x, volume %x, user %x, cell %x, server %x\n", afs_xconn,
! 	     afs_xvolume, afs_xuser, afs_xcell, afs_xserver);
      {
  	register struct vcache *tvc;
  	AFS_STATCNT(afs_CheckLocks);
--- 268,275 ----
      register int i;
  
      afs_warn("Looking for locked data structures.\n");
!     afs_warn("conn %lx, volume %lx, user %lx, cell %lx, server %lx\n", &amp;afs_xconn,
! 	     &amp;afs_xvolume, &amp;afs_xuser, &amp;afs_xcell, &amp;afs_xserver);
      {
  	register struct vcache *tvc;
  	AFS_STATCNT(afs_CheckLocks);
***************
*** 402,404 ****
--- 408,679 ----
      ip.p = p;
      return ip.i32[i32_sub];
  }
+ 
+ #if	defined(AFS_XBSD_ENV)
+ 
+ #define afs_md5 MD5Context
+ #define AFS_MD5_Init(m) MD5Init((m))
+ #define AFS_MD5_Update(m, p, l) MD5Update((m), (void *)(p), (l))
+ #define AFS_MD5_Final(r, m) MD5Final((r), (m))
+ 
+ #else
+ 
+ struct afs_md5 {
+     unsigned int sz[2];
+     afs_int32 counter[4];
+     unsigned char save[64];
+ };
+ 
+ static void AFS_MD5_Init (struct afs_md5 *m);
+ static void AFS_MD5_Update (struct afs_md5 *m, const void *p, size_t len);
+ static void AFS_MD5_Final (void *res, struct afs_md5 *m); /* u_int32 res[4] */
+ 
+ #define A m-&gt;counter[0]
+ #define B m-&gt;counter[1]
+ #define C m-&gt;counter[2]
+ #define D m-&gt;counter[3]
+ #define X data
+ 
+ static void
+ AFS_MD5_Init (struct afs_md5 *m)
+ {
+     m-&gt;sz[0] = 0;
+     m-&gt;sz[1] = 0;
+     D = 0x10325476;
+     C = 0x98badcfe;
+     B = 0xefcdab89;
+     A = 0x67452301;
+ }
+ 
+ #define F(x,y,z) ((x &amp; y) | (~x &amp; z))
+ #define G(x,y,z) ((x &amp; z) | (y &amp; ~z))
+ #define H(x,y,z) (x ^ y ^ z)
+ #define I(x,y,z) (y ^ (x | ~z))
+ 
+ static inline afs_uint32
+ cshift (afs_uint32 x, unsigned int n)
+ {
+     return ((x &lt;&lt; n) | (x &gt;&gt; (32 - n)));
+ }
+ 
+ #define DOIT(a,b,c,d,k,s,i,OP) \
+ a = b + cshift(a + OP(b,c,d) + X[k] + (i), s)
+ 
+ #define DO1(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,F)
+ #define DO2(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,G)
+ #define DO3(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,H)
+ #define DO4(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,I)
+ 
+ static inline void
+ calc (struct afs_md5 *m, afs_uint32 *data)
+ {
+     afs_uint32 AA, BB, CC, DD;
+     
+     AA = A;
+     BB = B;
+     CC = C;
+     DD = D;
+     
+     /* Round 1 */
+     
+     DO1(A,B,C,D,0,7,0xd76aa478);
+     DO1(D,A,B,C,1,12,0xe8c7b756);
+     DO1(C,D,A,B,2,17,0x242070db);
+     DO1(B,C,D,A,3,22,0xc1bdceee);
+     
+     DO1(A,B,C,D,4,7,0xf57c0faf);
+     DO1(D,A,B,C,5,12,0x4787c62a);
+     DO1(C,D,A,B,6,17,0xa8304613);
+     DO1(B,C,D,A,7,22,0xfd469501);
+     
+     DO1(A,B,C,D,8,7,0x698098d8);
+     DO1(D,A,B,C,9,12,0x8b44f7af);
+     DO1(C,D,A,B,10,17,0xffff5bb1);
+     DO1(B,C,D,A,11,22,0x895cd7be);
+     
+     DO1(A,B,C,D,12,7,0x6b901122);
+     DO1(D,A,B,C,13,12,0xfd987193);
+     DO1(C,D,A,B,14,17,0xa679438e);
+     DO1(B,C,D,A,15,22,0x49b40821);
+     
+     /* Round 2 */
+     
+     DO2(A,B,C,D,1,5,0xf61e2562);
+     DO2(D,A,B,C,6,9,0xc040b340);
+     DO2(C,D,A,B,11,14,0x265e5a51);
+     DO2(B,C,D,A,0,20,0xe9b6c7aa);
+     
+     DO2(A,B,C,D,5,5,0xd62f105d);
+     DO2(D,A,B,C,10,9,0x2441453);
+     DO2(C,D,A,B,15,14,0xd8a1e681);
+     DO2(B,C,D,A,4,20,0xe7d3fbc8);
+     
+     DO2(A,B,C,D,9,5,0x21e1cde6);
+     DO2(D,A,B,C,14,9,0xc33707d6);
+     DO2(C,D,A,B,3,14,0xf4d50d87);
+     DO2(B,C,D,A,8,20,0x455a14ed);
+     
+     DO2(A,B,C,D,13,5,0xa9e3e905);
+     DO2(D,A,B,C,2,9,0xfcefa3f8);
+     DO2(C,D,A,B,7,14,0x676f02d9);
+     DO2(B,C,D,A,12,20,0x8d2a4c8a);
+     
+     /* Round 3 */
+     
+     DO3(A,B,C,D,5,4,0xfffa3942);
+     DO3(D,A,B,C,8,11,0x8771f681);
+     DO3(C,D,A,B,11,16,0x6d9d6122);
+     DO3(B,C,D,A,14,23,0xfde5380c);
+     
+     DO3(A,B,C,D,1,4,0xa4beea44);
+     DO3(D,A,B,C,4,11,0x4bdecfa9);
+     DO3(C,D,A,B,7,16,0xf6bb4b60);
+     DO3(B,C,D,A,10,23,0xbebfbc70);
+     
+     DO3(A,B,C,D,13,4,0x289b7ec6);
+     DO3(D,A,B,C,0,11,0xeaa127fa);
+     DO3(C,D,A,B,3,16,0xd4ef3085);
+     DO3(B,C,D,A,6,23,0x4881d05);
+     
+     DO3(A,B,C,D,9,4,0xd9d4d039);
+     DO3(D,A,B,C,12,11,0xe6db99e5);
+     DO3(C,D,A,B,15,16,0x1fa27cf8);
+     DO3(B,C,D,A,2,23,0xc4ac5665);
+     
+     /* Round 4 */
+     
+     DO4(A,B,C,D,0,6,0xf4292244);
+     DO4(D,A,B,C,7,10,0x432aff97);
+     DO4(C,D,A,B,14,15,0xab9423a7);
+     DO4(B,C,D,A,5,21,0xfc93a039);
+     
+     DO4(A,B,C,D,12,6,0x655b59c3);
+     DO4(D,A,B,C,3,10,0x8f0ccc92);
+     DO4(C,D,A,B,10,15,0xffeff47d);
+     DO4(B,C,D,A,1,21,0x85845dd1);
+     
+     DO4(A,B,C,D,8,6,0x6fa87e4f);
+     DO4(D,A,B,C,15,10,0xfe2ce6e0);
+     DO4(C,D,A,B,6,15,0xa3014314);
+     DO4(B,C,D,A,13,21,0x4e0811a1);
+     
+     DO4(A,B,C,D,4,6,0xf7537e82);
+     DO4(D,A,B,C,11,10,0xbd3af235);
+     DO4(C,D,A,B,2,15,0x2ad7d2bb);
+     DO4(B,C,D,A,9,21,0xeb86d391);
+     
+     A += AA;
+     B += BB;
+     C += CC;
+     D += DD;
+ }
+ 
+ /*
+  * From `Performance analysis of MD5' by Joseph D. Touch &lt;touch@isi.edu&gt;
+  */
+ 
+ #if defined(AFSBIG_ENDIAN)
+ static inline afs_uint32
+ swap_u_int32_t (afs_uint32 t)
+ {
+     afs_uint32 temp1, temp2;
+     
+     temp1   = cshift(t, 16);
+     temp2   = temp1 &gt;&gt; 8;
+     temp1  &amp;= 0x00ff00ff;
+     temp2  &amp;= 0x00ff00ff;
+     temp1 &lt;&lt;= 8;
+     return temp1 | temp2;
+ }
+ #endif
+ 
+ struct x32{
+     unsigned int a:32;
+     unsigned int b:32;
+ };
+ 
+ static void
+ AFS_MD5_Update (struct afs_md5 *m, const void *v, size_t len)
+ {
+     const unsigned char *p = v;
+     size_t old_sz = m-&gt;sz[0];
+     size_t offset;
+     
+     m-&gt;sz[0] += len * 8;
+     if (m-&gt;sz[0] &lt; old_sz)
+ 	++m-&gt;sz[1];
+     offset = (old_sz / 8)  % 64;
+     while(len &gt; 0){
+ 	size_t l = MIN(len, 64 - offset);
+ 	memcpy(m-&gt;save + offset, p, l);
+ 	offset += l;
+ 	p += l;
+ 	len -= l;
+ 	if(offset == 64){
+ #if defined(AFSBIG_ENDIAN)
+ 	    int i;
+ 	    afs_uint32 current[16];
+ 	    struct x32 *us = (struct x32*)m-&gt;save;
+ 	    for(i = 0; i &lt; 8; i++){
+ 		current[2*i+0] = swap_u_int32_t(us[i].a);
+ 		current[2*i+1] = swap_u_int32_t(us[i].b);
+ 	    }
+ 	    calc(m, current);
+ #else
+ 	    calc(m, (afs_uint32*)m-&gt;save);
+ #endif
+ 	    offset = 0;
+ 	}
+     }
+ }
+ 
+ static void
+ AFS_MD5_Final (void *res, struct afs_md5 *m)
+ {
+     unsigned char zeros[72];
+     unsigned offset = (m-&gt;sz[0] / 8) % 64;
+     unsigned int dstart = (120 - offset - 1) % 64 + 1;
+     
+     *zeros = 0x80;
+     memset (zeros + 1, 0, sizeof(zeros) - 1);
+     zeros[dstart+0] = (m-&gt;sz[0] &gt;&gt; 0) &amp; 0xff;
+     zeros[dstart+1] = (m-&gt;sz[0] &gt;&gt; 8) &amp; 0xff;
+     zeros[dstart+2] = (m-&gt;sz[0] &gt;&gt; 16) &amp; 0xff;
+     zeros[dstart+3] = (m-&gt;sz[0] &gt;&gt; 24) &amp; 0xff;
+     zeros[dstart+4] = (m-&gt;sz[1] &gt;&gt; 0) &amp; 0xff;
+     zeros[dstart+5] = (m-&gt;sz[1] &gt;&gt; 8) &amp; 0xff;
+     zeros[dstart+6] = (m-&gt;sz[1] &gt;&gt; 16) &amp; 0xff;
+     zeros[dstart+7] = (m-&gt;sz[1] &gt;&gt; 24) &amp; 0xff;
+     AFS_MD5_Update (m, zeros, dstart + 8);
+     {
+ 	int i;
+ 	unsigned char *r = (unsigned char *)res;
+ 	
+ 	for (i = 0; i &lt; 4; ++i) {
+ 	    r[4*i]   = m-&gt;counter[i] &amp; 0xFF;
+ 	    r[4*i+1] = (m-&gt;counter[i] &gt;&gt; 8) &amp; 0xFF;
+ 	    r[4*i+2] = (m-&gt;counter[i] &gt;&gt; 16) &amp; 0xFF;
+ 	    r[4*i+3] = (m-&gt;counter[i] &gt;&gt; 24) &amp; 0xFF;
+ 	}
+     }
+ }
+ #endif
+ 
+ afs_int32 afs_calc_inum (afs_int32 volume, afs_int32 vnode)
+ { 
+     afs_int32 ino;
+     char digest[16];
+     struct afs_md5 ct;
+     
+     if (afs_new_inum) {
+ 	AFS_MD5_Init(&amp;ct);
+ 	AFS_MD5_Update(&amp;ct, &amp;volume, 4);
+ 	AFS_MD5_Update(&amp;ct, &amp;vnode, 4);
+ 	AFS_MD5_Final(digest, &amp;ct);
+ 	memcpy(&amp;ino, digest, sizeof(ino_t));
+     } else {
+ 	ino = (volume &lt;&lt; 16) + vnode;
+ 	ino &amp;= 0x7fffffff;      /* Assumes 32 bit ino_t ..... */
+     }
+     return ino;
+ }
Index: openafs/src/afs/sysctl.h
diff -c openafs/src/afs/sysctl.h:1.2 openafs/src/afs/sysctl.h:1.3
*** openafs/src/afs/sysctl.h:1.2	Fri Oct 24 02:26:00 2003
--- openafs/src/afs/sysctl.h	Thu Mar  9 01:34:25 2006
***************
*** 38,43 ****
--- 38,45 ----
  #define AFS_SC_DARWIN_14			3
  #define AFS_SC_DARWIN_60			4
  #define AFS_SC_DARWIN_70			5
+ #define AFS_SC_DARWIN_80			6
+ #define AFS_SC_DARWIN_90			7
  
  /* AFS_SC_DARWIN_ALL: darwin version-independent sysctls */
  #define AFS_SC_DARWIN_ALL_REALMODES		1
***************
*** 57,60 ****
--- 59,68 ----
  /* AFS_SC_DARWIN_70: darwin 7.x sysctls */
  	/* nothing defined */
  
+ /* AFS_SC_DARWIN_80: darwin 8.x sysctls */
+ 	/* nothing defined */
+ 
+ /* AFS_SC_DARWIN_90: darwin 9.x sysctls */
+ 	/* nothing defined */
+ 
  #endif /* AFS_SYSCTL_H */
Index: openafs/src/afs/sysincludes.h
diff -c openafs/src/afs/sysincludes.h:1.39 openafs/src/afs/sysincludes.h:1.40
*** openafs/src/afs/sysincludes.h:1.39	Thu Oct 13 11:12:07 2005
--- openafs/src/afs/sysincludes.h	Thu Mar  9 01:05:46 2006
***************
*** 97,102 ****
--- 97,105 ----
  #include &lt;linux/slab.h&gt;
  #include &lt;linux/string.h&gt;
  #include &lt;asm/semaphore.h&gt;
+ #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
+ #include &lt;linux/mutex.h&gt;
+ #endif
  #include &lt;linux/errno.h&gt;
  #ifdef COMPLETION_H_EXISTS
  #include &lt;linux/completion.h&gt;
Index: openafs/src/afs/DARWIN/osi_file.c
diff -c openafs/src/afs/DARWIN/osi_file.c:1.11 openafs/src/afs/DARWIN/osi_file.c:1.12
*** openafs/src/afs/DARWIN/osi_file.c:1.11	Thu Dec  1 02:36:35 2005
--- openafs/src/afs/DARWIN/osi_file.c	Mon Feb 20 23:45:07 2006
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/DARWIN/osi_file.c,v 1.11 2005/12/01 07:36:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/DARWIN/osi_file.c,v 1.12 2006/02/21 04:45:07 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 247,253 ****
  #ifdef AFS_DARWIN80_ENV
      VATTR_INIT(&amp;tvattr);
      VATTR_SET(&amp;tvattr, va_size, asize);
!     code = vnode_getattr(afile-&gt;vnode, &amp;tvattr, afs_osi_ctxtp);
  #else
      VATTR_NULL(&amp;tvattr);
      tvattr.va_size = asize;
--- 247,253 ----
  #ifdef AFS_DARWIN80_ENV
      VATTR_INIT(&amp;tvattr);
      VATTR_SET(&amp;tvattr, va_size, asize);
!     code = vnode_setattr(afile-&gt;vnode, &amp;tvattr, afs_osi_ctxtp);
  #else
      VATTR_NULL(&amp;tvattr);
      tvattr.va_size = asize;
Index: openafs/src/afs/DARWIN/osi_vnodeops.c
diff -c openafs/src/afs/DARWIN/osi_vnodeops.c:1.39 openafs/src/afs/DARWIN/osi_vnodeops.c:1.41
*** openafs/src/afs/DARWIN/osi_vnodeops.c:1.39	Fri Feb 17 23:08:15 2006
--- openafs/src/afs/DARWIN/osi_vnodeops.c	Thu Mar  2 01:35:59 2006
***************
*** 5,11 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/DARWIN/osi_vnodeops.c,v 1.39 2006/02/18 04:08:15 shadow Exp $");
  
  #include &lt;afs/sysincludes.h&gt;	/* Standard vendor system headers */
  #include &lt;afsincludes.h&gt;	/* Afs-based standard headers */
--- 5,11 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/DARWIN/osi_vnodeops.c,v 1.41 2006/03/02 06:35:59 shadow Exp $");
  
  #include &lt;afs/sysincludes.h&gt;	/* Standard vendor system headers */
  #include &lt;afsincludes.h&gt;	/* Afs-based standard headers */
***************
*** 561,566 ****
--- 561,567 ----
      struct afs_fakestat_state fakestate;
      struct vcache * tvc = VTOAFS(ap-&gt;a_vp);
      int bits=0;
+     int cmb = CHECK_MODE_BITS;
      AFS_GLOCK();
      afs_InitFakeStat(&amp;fakestate);
      if ((code = afs_InitReq(&amp;treq, vop_cred)))
***************
*** 611,616 ****
--- 612,623 ----
            bits |= PRSFS_LOOKUP;
         if (ap-&gt;a_action &amp; KAUTH_VNODE_READ_SECURITY) /* mode bits/gid, not afs acl */
            bits |= PRSFS_LOOKUP;
+        if ((ap-&gt;a_action &amp; ((1 &lt;&lt; 25) - 1)) == KAUTH_VNODE_EXECUTE)
+           /* if only exec, don't check for read mode bit */
+           /* high bits of ap-&gt;a_action are not for 'generic rights bits', and
+              so should not be checked (KAUTH_VNODE_ACCESS is often present
+              and needs to be masked off) */
+ 	  cmb |= CMB_ALLOW_EXEC_AS_READ;
      }
      if (ap-&gt;a_action &amp; KAUTH_VNODE_WRITE_ATTRIBUTES)
         bits |= PRSFS_WRITE;
***************
*** 624,630 ****
         bits |= PRSFS_WRITE;
      /* we can't check for KAUTH_VNODE_TAKE_OWNERSHIP, so we always permit it */
      
!     code = afs_AccessOK(tvc, bits, &amp;treq, CHECK_MODE_BITS);
  
      if (code == 1 &amp;&amp; vnode_vtype(ap-&gt;a_vp) == VREG &amp;&amp;
          ap-&gt;a_action &amp; KAUTH_VNODE_EXECUTE &amp;&amp;
--- 631,637 ----
         bits |= PRSFS_WRITE;
      /* we can't check for KAUTH_VNODE_TAKE_OWNERSHIP, so we always permit it */
      
!     code = afs_AccessOK(tvc, bits, &amp;treq, cmb);
  
      if (code == 1 &amp;&amp; vnode_vtype(ap-&gt;a_vp) == VREG &amp;&amp;
          ap-&gt;a_action &amp; KAUTH_VNODE_EXECUTE &amp;&amp;
***************
*** 1743,1749 ****
--- 1750,1759 ----
  {
      int error;
      struct ucred *tcr;
+     int clid;
+     int op;
  #ifdef AFS_DARWIN80_ENV
+     proc_t p;
      tcr=vop_cred;
  #else
      struct proc *p = current_proc();
***************
*** 1753,1763 ****
      pcred_unlock(p);
      tcr=&amp;cr;
  #endif
      AFS_GLOCK();
!     error =
! 	afs_lockctl(VTOAFS(ap-&gt;a_vp), ap-&gt;a_fl,
! 		    ap-&gt;a_op == F_UNLCK ? F_SETLK : ap-&gt;a_op, tcr, 
! 		    (int)ap-&gt;a_id);
      AFS_GUNLOCK();
      return error;
  }
--- 1763,1788 ----
      pcred_unlock(p);
      tcr=&amp;cr;
  #endif
+     if (ap-&gt;a_flags &amp; F_POSIX) {
+ #ifdef AFS_DARWIN80_ENV
+ 	p = (proc_t) ap-&gt;a_id;
+ 	clid = proc_pid(p);
+ #else
+ 	p = (struct proc *) ap-&gt;a_id;
+ 	clid = p-&gt;p_pid;
+ #endif
+     } else {
+ 	clid = (int)ap-&gt;a_id;
+     }
+     if (ap-&gt;a_op == F_UNLCK) {
+ 	op = F_SETLK;
+     } else if (ap-&gt;a_op == F_SETLK &amp;&amp; ap-&gt;a_flags &amp; F_WAIT) {
+ 	op = F_SETLKW;
+     } else {
+ 	op = ap-&gt;a_op;
+     }
      AFS_GLOCK();
!     error = afs_lockctl(VTOAFS(ap-&gt;a_vp), ap-&gt;a_fl, op, tcr, clid);
      AFS_GUNLOCK();
      return error;
  }
Index: openafs/src/afs/IRIX/osi_machdep.h
diff -c openafs/src/afs/IRIX/osi_machdep.h:1.9 openafs/src/afs/IRIX/osi_machdep.h:1.10
*** openafs/src/afs/IRIX/osi_machdep.h:1.9	Wed Apr 13 22:25:08 2005
--- openafs/src/afs/IRIX/osi_machdep.h	Thu Apr 13 17:08:19 2006
***************
*** 43,48 ****
--- 43,49 ----
  #define vfs_data vfs_bh.bh_first-&gt;bd_pdata
  #endif /* AFS_SGI64_ENV */
  
+ #define ifnet_flags(x) (x?(x)-&gt;if_flags:0)
  
  /*
   * Global lock, semaphore, mutex and state vector support.
Index: openafs/src/afs/LINUX/osi_machdep.h
diff -c openafs/src/afs/LINUX/osi_machdep.h:1.33 openafs/src/afs/LINUX/osi_machdep.h:1.34
*** openafs/src/afs/LINUX/osi_machdep.h:1.33	Mon Jul 11 14:45:51 2005
--- openafs/src/afs/LINUX/osi_machdep.h	Thu Mar  9 01:06:34 2006
***************
*** 187,201 ****
  #define afs_linux_page_address(page) (afs_linux_page_offset + PAGE_SIZE * (page - mem_map))
  
  #if defined(__KERNEL__)
! #include "../h/sched.h"
! #include "linux/wait.h"
  
  extern struct semaphore afs_global_lock;
  extern int afs_global_owner;
  
  #define AFS_GLOCK() \
  do { \
! 	 down(&amp;afs_global_lock); \
  	 if (afs_global_owner) \
  	     osi_Panic("afs_global_lock already held by pid %d", \
  		       afs_global_owner); \
--- 187,208 ----
  #define afs_linux_page_address(page) (afs_linux_page_offset + PAGE_SIZE * (page - mem_map))
  
  #if defined(__KERNEL__)
! #include &lt;linux/version.h&gt;
! #include &lt;linux/sched.h&gt;
! #include &lt;linux/wait.h&gt;
  
+ #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
+ extern struct mutex afs_global_lock;
+ #else
  extern struct semaphore afs_global_lock;
+ #define mutex_lock(lock) down(lock)
+ #define mutex_unlock(lock) up(lock)
+ #endif
  extern int afs_global_owner;
  
  #define AFS_GLOCK() \
  do { \
! 	 mutex_lock(&amp;afs_global_lock); \
  	 if (afs_global_owner) \
  	     osi_Panic("afs_global_lock already held by pid %d", \
  		       afs_global_owner); \
***************
*** 209,218 ****
      if (!ISAFS_GLOCK()) \
  	osi_Panic("afs global lock not held at %s:%d", __FILE__, __LINE__); \
      afs_global_owner = 0; \
!     up(&amp;afs_global_lock); \
  } while (0)
- 
- 
  #else
  #define AFS_GLOCK()
  #define AFS_GUNLOCK()
--- 216,223 ----
      if (!ISAFS_GLOCK()) \
  	osi_Panic("afs global lock not held at %s:%d", __FILE__, __LINE__); \
      afs_global_owner = 0; \
!     mutex_unlock(&amp;afs_global_lock); \
  } while (0)
  #else
  #define AFS_GLOCK()
  #define AFS_GUNLOCK()
Index: openafs/src/afs/LINUX/osi_module.c
diff -c openafs/src/afs/LINUX/osi_module.c:1.72 openafs/src/afs/LINUX/osi_module.c:1.74
*** openafs/src/afs/LINUX/osi_module.c:1.72	Sat Jan 14 03:00:01 2006
--- openafs/src/afs/LINUX/osi_module.c	Thu Mar  9 01:06:34 2006
***************
*** 15,21 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_module.c,v 1.72 2006/01/14 08:00:01 rra Exp $");
  
  #include &lt;linux/module.h&gt; /* early to avoid printf-&gt;printk mapping */
  #include "afs/sysincludes.h"
--- 15,21 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_module.c,v 1.74 2006/03/09 06:06:34 shadow Exp $");
  
  #include &lt;linux/module.h&gt; /* early to avoid printf-&gt;printk mapping */
  #include "afs/sysincludes.h"
***************
*** 48,54 ****
  static long get_page_offset(void);
  #endif
  
! #if defined(AFS_LINUX24_ENV)
  DECLARE_MUTEX(afs_global_lock);
  #else
  struct semaphore afs_global_lock = MUTEX;
--- 48,56 ----
  static long get_page_offset(void);
  #endif
  
! #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
! DEFINE_MUTEX(afs_global_lock);
! #elif LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,4,0)
  DECLARE_MUTEX(afs_global_lock);
  #else
  struct semaphore afs_global_lock = MUTEX;
***************
*** 634,639 ****
--- 636,643 ----
  #ifdef AFS_LINUX26_ENV 
  #ifdef AFS_S390X_LINUX26_ENV
      if (test_thread_flag(TIF_31BIT))
+ #elif AFS_AMD64_LINUX20_ENV
+     if (test_thread_flag(TIF_IA32))
  #else
      if (test_thread_flag(TIF_32BIT))
  #endif /* AFS_S390X_LINUX26_ENV */
Index: openafs/src/afs/LINUX/osi_probe.c
diff -c openafs/src/afs/LINUX/osi_probe.c:1.6 openafs/src/afs/LINUX/osi_probe.c:1.11
*** openafs/src/afs/LINUX/osi_probe.c:1.6	Wed Apr  6 00:46:03 2005
--- openafs/src/afs/LINUX/osi_probe.c	Wed Apr 26 11:40:43 2006
***************
*** 64,69 ****
--- 64,72 ----
  #include &lt;linux/init.h&gt;
  #include &lt;linux/unistd.h&gt;
  #include &lt;linux/mm.h&gt;
+ #ifdef AFS_LINUX26_ENV
+ #include &lt;scsi/scsi.h&gt; /* for scsi_command_size */
+ #endif
  
  #if defined(AFS_PPC64_LINUX26_ENV)
  #include &lt;asm/abs_addr.h&gt;
***************
*** 114,129 ****
--- 117,144 ----
  
  /* Allow the user to specify sys_call_table addresses */
  static unsigned long sys_call_table_addr[4] = { 0,0,0,0 };
+ #if defined(module_param_array) &amp;&amp; LINUX_VERSION_CODE &gt; KERNEL_VERSION(2,6,9)
+ module_param_array(sys_call_table_addr, long, NULL, 0);
+ #else
  MODULE_PARM(sys_call_table_addr, "1-4l");
+ #endif
  MODULE_PARM_DESC(sys_call_table_addr, "Location of system call tables");
  
  /* If this is set, we are more careful about avoiding duplicate matches */
  static int probe_carefully = 1;
+ #ifdef module_param
+ module_param(probe_carefully, int, 0);
+ #else
  MODULE_PARM(probe_carefully, "i");
+ #endif
  MODULE_PARM_DESC(probe_carefully, "Probe for system call tables carefully");
  
  static int probe_ignore_syscalls[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+ #if defined(module_param_array) &amp;&amp; LINUX_VERSION_CODE &gt; KERNEL_VERSION(2,6,9)
+ module_param_array(probe_ignore_syscalls, int, NULL, 0);
+ #else
  MODULE_PARM(probe_ignore_syscalls, "1-8i");
+ #endif
  MODULE_PARM_DESC(probe_ignore_syscalls, "Syscalls to ignore in table checks");
  
  #ifdef OSI_PROBE_DEBUG
***************
*** 138,156 ****
--- 153,187 ----
   * 0x0040 - automatically ignore setgroups and afs_syscall
   */
  static int probe_debug = 0x41;
+ #ifdef module_param
+ module_param(probe_debug, int, 0);
+ #else
  MODULE_PARM(probe_debug, "i");
+ #endif
  MODULE_PARM_DESC(probe_debug, "Debugging level");
  
  static unsigned long probe_debug_addr[4] = { 0,0,0,0 };
+ #if defined(module_param_array) &amp;&amp; LINUX_VERSION_CODE &gt; KERNEL_VERSION(2,6,9)
+ module_param_array(probe_debug_addr, long, NULL, 0);
+ #else
  MODULE_PARM(probe_debug_addr, "1-4l");
+ #endif
  MODULE_PARM_DESC(probe_debug_addr, "Debug range starting locations");
  
  static unsigned long probe_debug_range = 0;
+ #ifdef module_param
+ module_param(probe_debug_range, long, 0);
+ #else
  MODULE_PARM(probe_debug_range, "l");
+ #endif
  MODULE_PARM_DESC(probe_debug_range, "Debug range length");
  
  static unsigned long probe_debug_tag = 0;
+ #ifdef module_param
+ module_param(probe_debug_tag, long, 0);
+ #else
  MODULE_PARM(probe_debug_tag, "l");
+ #endif
  MODULE_PARM_DESC(probe_debug_tag, "Debugging output start tag");
  #endif
  
***************
*** 244,249 ****
--- 275,285 ----
      unsigned long try_base_mask;    /* base address bits to force to zero */
      unsigned long try_length;       /* default length for scan */
  
+     unsigned long alt_try_sect_sym;     /* symbol in section to try scanning */
+     unsigned long alt_try_base;         /* default base address for scan */
+     unsigned long alt_try_base_mask;    /* base address bits to force to zero */
+     unsigned long alt_try_length;       /* default length for scan */
+ 
      int n_zapped_syscalls;          /* number of unimplemented system calls */
      int *zapped_syscalls;           /* list of unimplemented system calls */
  
***************
*** 505,510 ****
--- 541,555 ----
      16384,
  #endif
  
+ #ifdef AFS_LINUX26_ENV
+     (unsigned long)scsi_command_size,
+     (unsigned long)scsi_command_size,
+     0x3ffff,
+     0x30000,
+ #else
+     0, 0, 0, 0,
+ #endif
+ 
      /* number and list of unimplemented system calls */
      ((sizeof(main_zapped_syscalls)/sizeof(main_zapped_syscalls[0])) - 1),
      main_zapped_syscalls,
***************
*** 592,597 ****
--- 637,652 ----
      0,
      (0x180000 / sizeof(unsigned long *)),
  
+ #ifdef AFS_LINUX26_ENV
+     (unsigned long)scsi_command_size,
+     (unsigned long)scsi_command_size,
+     0x3ffff,
+     0x30000,
+ #else
+     0, 0, 0, 0,
+ #endif
+ 
+ 
      /* number and list of unimplemented system calls */
      ((sizeof(ia32_zapped_syscalls)/sizeof(ia32_zapped_syscalls[0])) - 1),
      ia32_zapped_syscalls,
***************
*** 721,726 ****
--- 776,790 ----
      16384,
  #endif
  
+ #ifdef AFS_LINUX26_ENV
+     (unsigned long)scsi_command_size,
+     (unsigned long)scsi_command_size,
+     0x3ffff,
+     0x30000,
+ #else
+     0, 0, 0, 0,
+ #endif
+ 
      /* number and list of unimplemented system calls */
      ((sizeof(sct32_zapped_syscalls)/sizeof(sct32_zapped_syscalls[0])) - 1),
      sct32_zapped_syscalls,
***************
*** 807,812 ****
--- 871,885 ----
      0xfffff,
      0x20000,
  
+ #ifdef AFS_LINUX26_ENV
+     (unsigned long)scsi_command_size,
+     (unsigned long)scsi_command_size,
+     0x3ffff,
+     0x30000,
+ #else
+     0, 0, 0, 0,
+ #endif
+ 
      /* number and list of unimplemented system calls */
      ((sizeof(emu_zapped_syscalls)/sizeof(emu_zapped_syscalls[0])) - 1),
      emu_zapped_syscalls,
***************
*** 1091,1096 ****
--- 1164,1229 ----
      }                           \
  } while (0)
  #endif
+ static void *scan_for_syscall_table(probectl *P, PROBETYPE *B, unsigned long L)
+ {
+     tryctl *T;
+     void *answer;
+ #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV)
+     void *answer2;
+ #endif
+ #ifdef OSI_PROBE_DEBUG
+     void *final_answer = 0;
+ #endif
+ #ifdef OSI_PROBE_DEBUG
+     if (probe_debug &amp; 0x0007)
+ 	printk("&lt;7&gt;osi_probe: %s                      base=0x%lx, len=0x%lx\n",
+ 	       P-&gt;symbol, (unsigned long)B, L);
+     if (probe_debug &amp; 0x0009) {
+ 	printk("&lt;7&gt;osi_probe: %s                      ktxt_lower_bound=0x%lx\n",
+ 	       P-&gt;symbol, ktxt_lower_bound);
+ 	printk("&lt;7&gt;osi_probe: %s                      NR_syscalls=%d\n",
+ 	       P-&gt;symbol, NR_syscalls);
+     }
+ #endif
+ 
+     for (T = P-&gt;trylist; T-&gt;name; T++) {
+ 	answer = try(P, T, B, L);
+ #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV)
+ 	answer2 = try(P, T, (PROBETYPE *)(2 + (void *)B), L);
+ #ifdef OSI_PROBE_DEBUG
+ 	if (probe_debug &amp; 0x0003) {
+ 	    printk("&lt;7&gt;osi_probe: %s = 0x%016lx %s (even)\n",
+ 		   P-&gt;symbol, (unsigned long)(answer), T-&gt;name);
+ 	    printk("&lt;7&gt;osi_probe: %s = 0x%016lx %s (odd)\n",
+ 		   P-&gt;symbol, (unsigned long)(answer2), T-&gt;name);
+ 	}
+ #endif
+ 	if (answer &amp;&amp; answer2) answer = 0;
+ 	else if (answer2) answer = answer2;
+ #endif
+ 	if (answer)
+ 	    return answer;
+     }
+ 
+     /* XXX more checks here */
+ 
+     answer = try_harder(P, B, L);
+ #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV)
+     answer2 = try_harder(P, (PROBETYPE *)(2 + (void *)B), L);
+ #ifdef OSI_PROBE_DEBUG
+     if (probe_debug &amp; 0x0005) {
+ 	printk("&lt;7&gt;osi_probe: %s = 0x%016lx pattern scan (even)\n",
+ 	       P-&gt;symbol, (unsigned long)(answer));
+ 	printk("&lt;7&gt;osi_probe: %s = 0x%016lx pattern scan (odd)\n",
+ 	       P-&gt;symbol, (unsigned long)(answer2));
+     }
+ #endif
+     if (answer &amp;&amp; answer2) answer = 0;
+     else if (answer2) answer = answer2;
+ #endif
+     return answer;
+ }
+ 
  static void *do_find_syscall_table(probectl *P, char **method)
  {
  #ifdef OSI_PROBE_KALLSYMS
***************
*** 1103,1113 ****
  #endif
      PROBETYPE *B;
      unsigned long L;
-     tryctl *T;
      void *answer;
- #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV)
-     void *answer2;
- #endif
  #ifdef OSI_PROBE_DEBUG
      void *final_answer = 0;
  #endif
--- 1236,1242 ----
***************
*** 1155,1215 ****
  	}
      }
  #endif
! 
! #ifdef OSI_PROBE_DEBUG
!     if (probe_debug &amp; 0x0007)
! 	printk("&lt;7&gt;osi_probe: %s                      base=0x%lx, len=0x%lx\n",
! 	       P-&gt;symbol, (unsigned long)B, L);
!     if (probe_debug &amp; 0x0009) {
! 	printk("&lt;7&gt;osi_probe: %s                      ktxt_lower_bound=0x%lx\n",
! 	       P-&gt;symbol, ktxt_lower_bound);
! 	printk("&lt;7&gt;osi_probe: %s                      NR_syscalls=%d\n",
! 	       P-&gt;symbol, NR_syscalls);
!     }
! #endif
! 
!     for (T = P-&gt;trylist; T-&gt;name; T++) {
! 	answer = try(P, T, B, L);
! #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV)
! 	answer2 = try(P, T, (PROBETYPE *)(2 + (void *)B), L);
! #ifdef OSI_PROBE_DEBUG
! 	if (probe_debug &amp; 0x0003) {
! 	    printk("&lt;7&gt;osi_probe: %s = 0x%016lx %s (even)\n",
! 		   P-&gt;symbol, (unsigned long)(answer), T-&gt;name);
! 	    printk("&lt;7&gt;osi_probe: %s = 0x%016lx %s (odd)\n",
! 		   P-&gt;symbol, (unsigned long)(answer2), T-&gt;name);
  	}
  #endif
! 	if (answer &amp;&amp; answer2) answer = 0;
! 	else if (answer2) answer = answer2;
! #endif
!         check_result(answer, T-&gt;name);
      }
- 
-     /* XXX more checks here */
- 
-     answer = try_harder(P, B, L);
- #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV)
-     answer2 = try_harder(P, (PROBETYPE *)(2 + (void *)B), L);
  #ifdef OSI_PROBE_DEBUG
!     if (probe_debug &amp; 0x0005) {
! 	printk("&lt;7&gt;osi_probe: %s = 0x%016lx pattern scan (even)\n",
! 	       P-&gt;symbol, (unsigned long)(answer));
! 	printk("&lt;7&gt;osi_probe: %s = 0x%016lx pattern scan (odd)\n",
! 	       P-&gt;symbol, (unsigned long)(answer2));
!     }
  #endif
!     if (answer &amp;&amp; answer2) answer = 0;
!     else if (answer2) answer = answer2;
  #endif
!     check_result(answer, "pattern scan");
  
! #ifdef OSI_PROBE_DEBUG
!     return final_answer;
  #else
!     return 0;
  #endif
  }
  
  void *osi_find_syscall_table(int which)
  {
--- 1284,1349 ----
  	}
      }
  #endif
!    
!     answer = scan_for_syscall_table(P, B, L);
!     check_result(answer, "pattern scan");
!     B = (PROBETYPE *)((P-&gt;alt_try_base) &amp; ~(P-&gt;alt_try_base_mask));
!     L = P-&gt;alt_try_length;
!     /* Now, see if the kernel will tell us something better than the default */
! #ifdef OSI_PROBE_KALLSYMS
!     if (kallsyms_address_to_symbol &amp;&amp; P-&gt;alt_try_sect_sym) {
! 	ret = kallsyms_address_to_symbol(P-&gt;alt_try_sect_sym,
! 					 &amp;mod_name, &amp;mod_start, &amp;mod_end,
! 					 &amp;sec_name, &amp;sec_start, &amp;sec_end,
! 					 &amp;sym_name, &amp;sym_start, &amp;sym_end);
! 	if (ret) {
! 	    B = (PROBETYPE *)sec_start;
! 	    L = (sec_end - sec_start) / sizeof(unsigned long);
  	}
+     }
  #endif
!     if (B &amp;&amp; L) {
! 	answer = scan_for_syscall_table(P, B, L);
! 	check_result(answer, "pattern scan");
      }
  #ifdef OSI_PROBE_DEBUG
!     return final_answer;
! #else
!     return 0;
  #endif
! }
! 
! #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
! static int check_writable(unsigned long address) 
! { 
!     pgd_t *pgd = pgd_offset_k(address);
! #ifdef PUD_SIZE
!     pud_t *pud;
  #endif
!     pmd_t *pmd;
!     pte_t *pte;
  
!     if (pgd_none(*pgd))
! 	return 0;
! #ifdef PUD_SIZE
!     pud = pud_offset(pgd, address);
!     if (pud_none(*pud))
! 	return 0;
!     pmd = pmd_offset(pud, address);
  #else
!     pmd = pmd_offset(pgd, address);
  #endif
+     if (pmd_none(*pmd))
+ 	return 0;
+     if (pmd_large(*pmd))
+ 	pte = (pte_t *)pmd;
+     else
+ 	pte = pte_offset_kernel(pmd, address);
+     if (pte_none(*pte) || !pte_present(*pte) || !pte_write(*pte))
+ 	return 0;
+     return 1;
  }
+ #endif
  
  void *osi_find_syscall_table(int which)
  {
***************
*** 1235,1240 ****
--- 1369,1381 ----
  	return 0;
      }
      printk("Found %s at 0x%lx (%s)\n", P-&gt;desc, (unsigned long)answer, method);
+ #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
+     if (!check_writable((unsigned long)answer)) {
+ 	printk("Address 0x%lx is not writable.\n", (unsigned long)answer);
+ 	printk("System call hooks will not be installed; proceeding anyway\n");
+ 	return 0;
+     }
+ #endif
      return answer;
  }
  
Index: openafs/src/afs/LINUX/osi_sysctl.c
diff -c openafs/src/afs/LINUX/osi_sysctl.c:1.8 openafs/src/afs/LINUX/osi_sysctl.c:1.9
*** openafs/src/afs/LINUX/osi_sysctl.c:1.8	Wed Apr 27 08:37:56 2005
--- openafs/src/afs/LINUX/osi_sysctl.c	Wed Apr  5 12:04:34 2006
***************
*** 1,7 ****
  /*
   * osi_sysctl.c: Linux sysctl interface to OpenAFS
   *
!  * $Id: osi_sysctl.c,v 1.8 2005/04/27 12:37:56 shadow Exp $
   *
   * Written Jan 30, 2002 by Kris Van Hees (Sine Nomine Associates)
   */
--- 1,7 ----
  /*
   * osi_sysctl.c: Linux sysctl interface to OpenAFS
   *
!  * $Id: osi_sysctl.c,v 1.9 2006/04/05 16:04:34 shadow Exp $
   *
   * Written Jan 30, 2002 by Kris Van Hees (Sine Nomine Associates)
   */
***************
*** 16,21 ****
--- 16,24 ----
  #include &lt;linux/sysctl.h&gt;
  #include &lt;linux/config.h&gt;
  
+ /* From afs_util.c */
+ extern afs_int32 afs_new_inum;
+ 
  /* From afs_analyze.c */
  extern afs_int32 hm_retry_RO;
  extern afs_int32 hm_retry_RW;
***************
*** 82,87 ****
--- 85,94 ----
       &amp;afs_cacheBlocks, sizeof(afs_int32), 0644, NULL,
       &amp;proc_dointvec}
      ,
+     {7, "md5inum",
+      &amp;afs_new_inum, sizeof(afs_int32), 0644, NULL,
+      &amp;proc_dointvec}
+     ,
      {0}
  };
  
Index: openafs/src/afs/LINUX/osi_vnodeops.c
diff -c openafs/src/afs/LINUX/osi_vnodeops.c:1.124 openafs/src/afs/LINUX/osi_vnodeops.c:1.126
*** openafs/src/afs/LINUX/osi_vnodeops.c:1.124	Wed Jan 11 16:37:06 2006
--- openafs/src/afs/LINUX/osi_vnodeops.c	Wed Apr  5 12:04:34 2006
***************
*** 22,28 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.124 2006/01/11 21:37:06 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
--- 22,28 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.126 2006/04/05 16:04:34 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afsincludes.h"
***************
*** 50,57 ****
  #endif
  
  extern struct vcache *afs_globalVp;
- 
- 
  static ssize_t
  afs_linux_read(struct file *fp, char *buf, size_t count, loff_t * offp)
  {
--- 50,55 ----
***************
*** 229,236 ****
  	if (!de)
  	    break;
  
! 	ino = (avc-&gt;fid.Fid.Volume &lt;&lt; 16) + ntohl(de-&gt;fid.vnode);
! 	ino &amp;= 0x7fffffff;	/* Assumes 32 bit ino_t ..... */
  	if (de-&gt;name)
  	    len = strlen(de-&gt;name);
  	else {
--- 227,234 ----
  	if (!de)
  	    break;
  
! 	ino = afs_calc_inum (avc-&gt;fid.Fid.Volume, ntohl(de-&gt;fid.vnode));
! 
  	if (de-&gt;name)
  	    len = strlen(de-&gt;name);
  	else {
***************
*** 463,468 ****
--- 461,485 ----
      code = afs_lockctl(vcp, &amp;flock, cmd, credp);
      AFS_GUNLOCK();
  
+ #ifdef AFS_LINUX24_ENV
+     if (code == 0 &amp;&amp; (cmd == F_SETLK || cmd == F_SETLKW)) {
+        struct file_lock flp2;
+        flp2 = *flp;
+ #ifdef AFS_LINUX26_ENV
+        flp2.fl_flags &amp;=~ FL_SLEEP;
+ #endif
+        code = posix_lock_file(fp, &amp;flp2);
+        osi_Assert(code != -EAGAIN); /* there should be no conflicts */
+        if (code) {
+            struct AFS_FLOCK flock2;
+            flock2 = flock;
+            flock2.l_type = F_UNLCK;
+            AFS_GLOCK();
+            afs_lockctl(vcp, &amp;flock2, F_SETLK, credp);
+            AFS_GUNLOCK();
+        }
+     }
+ #endif
      /* Convert flock back to Linux's file_lock */
      flp-&gt;fl_type = flock.l_type;
      flp-&gt;fl_pid = flock.l_pid;
Index: openafs/src/afs/OBSD/osi_file.c
diff -c openafs/src/afs/OBSD/osi_file.c:1.10 openafs/src/afs/OBSD/osi_file.c:1.11
*** openafs/src/afs/OBSD/osi_file.c:1.10	Wed Mar 10 18:01:52 2004
--- openafs/src/afs/OBSD/osi_file.c	Thu Mar  9 10:27:17 2006
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_file.c,v 1.10 2004/03/10 23:01:52 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afs/afsincludes.h"	/* Afs-based standard headers */
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_file.c,v 1.11 2006/03/09 15:27:17 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 48,54 ****
--- 48,58 ----
      }
      VOP_UNLOCK(vp, 0, curproc);
      afile-&gt;vnode = vp;
+ #ifdef AFS_OBSD39_ENV
+     afile-&gt;size = VTOI(vp)-&gt;i_ffs1_size;
+ #else
      afile-&gt;size = VTOI(vp)-&gt;i_ffs_size;
+ #endif
      afile-&gt;offset = 0;
      afile-&gt;proc = NULL;
      afile-&gt;inum = ainode;	/* for hint validity checking */
Index: openafs/src/afs/OBSD/osi_groups.c
diff -c openafs/src/afs/OBSD/osi_groups.c:1.5 openafs/src/afs/OBSD/osi_groups.c:1.6
*** openafs/src/afs/OBSD/osi_groups.c:1.5	Tue Jul 15 19:14:25 2003
--- openafs/src/afs/OBSD/osi_groups.c	Mon Mar 13 11:26:27 2006
***************
*** 19,25 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_groups.c,v 1.5 2003/07/15 23:14:25 shadow Exp $");
  
  #include "afs/sysincludes.h"
  #include "afs/afsincludes.h"
--- 19,25 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_groups.c,v 1.6 2006/03/13 16:26:27 rees Exp $");
  
  #include "afs/sysincludes.h"
  #include "afs/afsincludes.h"
***************
*** 47,56 ****
      struct vrequest treq;
  
      AFS_STATCNT(afs_xsetgroups);
!     AFS_GLOCK();
  
      code = afs_InitReq(&amp;treq, p-&gt;p_rcred);
!     AFS_GUNLOCK();
      if (code)
  	return code;
  
--- 47,56 ----
      struct vrequest treq;
  
      AFS_STATCNT(afs_xsetgroups);
!     AFS_GLOCKP(p);
  
      code = afs_InitReq(&amp;treq, p-&gt;p_rcred);
!     AFS_GUNLOCKP(p);
      if (code)
  	return code;
  
***************
*** 61,70 ****
       */
      if (PagInCred(p-&gt;p_rcred) == NOPAG) {
  	if (((treq.uid &gt;&gt; 24) &amp; 0xff) == 'A') {
! 	    AFS_GLOCK();
  	    /* we've already done a setpag, so now we redo it */
  	    AddPag(p, treq.uid, &amp;p-&gt;p_rcred);
! 	    AFS_GUNLOCK();
  	}
      }
      return code;
--- 61,70 ----
       */
      if (PagInCred(p-&gt;p_rcred) == NOPAG) {
  	if (((treq.uid &gt;&gt; 24) &amp; 0xff) == 'A') {
! 	    AFS_GLOCKP(p);
  	    /* we've already done a setpag, so now we redo it */
  	    AddPag(p, treq.uid, &amp;p-&gt;p_rcred);
! 	    AFS_GUNLOCKP(p);
  	}
      }
      return code;
Index: openafs/src/afs/OBSD/osi_machdep.h
diff -c openafs/src/afs/OBSD/osi_machdep.h:1.25 openafs/src/afs/OBSD/osi_machdep.h:1.27
*** openafs/src/afs/OBSD/osi_machdep.h:1.25	Thu Jan 26 11:00:42 2006
--- openafs/src/afs/OBSD/osi_machdep.h	Mon Mar 13 11:26:27 2006
***************
*** 16,22 ****
   * afs_osi.h.
   */
  
! /* $Id: osi_machdep.h,v 1.25 2006/01/26 16:00:42 shadow Exp $ */
  
  #ifndef _OSI_MACHDEP_H_
  #define _OSI_MACHDEP_H_
--- 16,22 ----
   * afs_osi.h.
   */
  
! /* $Id: osi_machdep.h,v 1.27 2006/03/13 16:26:27 rees Exp $ */
  
  #ifndef _OSI_MACHDEP_H_
  #define _OSI_MACHDEP_H_
***************
*** 104,133 ****
  #define	gop_lookupname(fnamep, segflg, followlink, compvpp) \
  	afs_nbsd_lookupname((fnamep), (segflg), (followlink), (compvpp))
  
  #ifdef KERNEL
  
  #ifdef AFS_GLOBAL_SUNLOCK
  extern struct proc *afs_global_owner;
  extern struct lock afs_global_lock;
! #define AFS_GLOCK() \
      do { \
!         osi_Assert(curproc); \
!  	lockmgr(&amp;afs_global_lock, LK_EXCLUSIVE, 0, curproc); \
          osi_Assert(afs_global_owner == NULL); \
!    	afs_global_owner = curproc; \
      } while (0)
! #define AFS_GUNLOCK() \
      do { \
!         osi_Assert(curproc); \
!  	osi_Assert(afs_global_owner == curproc); \
          afs_global_owner = NULL; \
!         lockmgr(&amp;afs_global_lock, LK_RELEASE, 0, curproc); \
      } while(0)
  #define ISAFS_GLOCK() (afs_global_owner == curproc &amp;&amp; curproc)
  #else
  extern struct lock afs_global_lock;
! #define AFS_GLOCK()
! #define AFS_GUNLOCK()
  #define AFS_ASSERT_GLOCK()
  #define ISAFS_GLOCK() 1
  #endif
--- 104,141 ----
  #define	gop_lookupname(fnamep, segflg, followlink, compvpp) \
  	afs_nbsd_lookupname((fnamep), (segflg), (followlink), (compvpp))
  
+ #ifdef AFS_OBSD39_ENV
+ #define afs_osi_lockmgr(l, f, i, p) lockmgr((l), (f), (i))
+ #else
+ #define afs_osi_lockmgr(l, f, i, p) lockmgr((l), (f), (i), (p))
+ #endif
+ 
  #ifdef KERNEL
  
+ #define AFS_GLOCK() AFS_GLOCKP(curproc)
+ #define AFS_GUNLOCK() AFS_GUNLOCKP(curproc)
  #ifdef AFS_GLOBAL_SUNLOCK
  extern struct proc *afs_global_owner;
  extern struct lock afs_global_lock;
! #define AFS_GLOCKP(p) \
      do { \
!         osi_Assert(p); \
!  	afs_osi_lockmgr(&amp;afs_global_lock, LK_EXCLUSIVE, 0, (p)); \
          osi_Assert(afs_global_owner == NULL); \
!    	afs_global_owner = (p); \
      } while (0)
! #define AFS_GUNLOCKP(p) \
      do { \
!         osi_Assert(p); \
!  	osi_Assert(afs_global_owner == (p)); \
          afs_global_owner = NULL; \
!         afs_osi_lockmgr(&amp;afs_global_lock, LK_RELEASE, 0, (p)); \
      } while(0)
  #define ISAFS_GLOCK() (afs_global_owner == curproc &amp;&amp; curproc)
  #else
  extern struct lock afs_global_lock;
! #define AFS_GLOCKP(p)
! #define AFS_GUNLOCKP(p)
  #define AFS_ASSERT_GLOCK()
  #define ISAFS_GLOCK() 1
  #endif
Index: openafs/src/afs/OBSD/osi_vnodeops.c
diff -c openafs/src/afs/OBSD/osi_vnodeops.c:1.19 openafs/src/afs/OBSD/osi_vnodeops.c:1.20
*** openafs/src/afs/OBSD/osi_vnodeops.c:1.19	Tue Jan 18 11:15:36 2005
--- openafs/src/afs/OBSD/osi_vnodeops.c	Thu Mar  9 10:27:17 2006
***************
*** 3,9 ****
   * Original NetBSD version for Transarc afs by John Kohl &lt;jtk@MIT.EDU&gt;
   * OpenBSD version by Jim Rees &lt;rees@umich.edu&gt;
   *
!  * $Id: osi_vnodeops.c,v 1.19 2005/01/18 16:15:36 rees Exp $
   */
  
  /*
--- 3,9 ----
   * Original NetBSD version for Transarc afs by John Kohl &lt;jtk@MIT.EDU&gt;
   * OpenBSD version by Jim Rees &lt;rees@umich.edu&gt;
   *
!  * $Id: osi_vnodeops.c,v 1.20 2006/03/09 15:27:17 rees Exp $
   */
  
  /*
***************
*** 99,105 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_vnodeops.c,v 1.19 2005/01/18 16:15:36 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afs/afsincludes.h"	/* Afs-based standard headers */
--- 99,105 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/OBSD/osi_vnodeops.c,v 1.20 2006/03/09 15:27:17 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 933,939 ****
  
      if (!vc)
  	panic("afs_nbsd_lock: null vcache");
!     return lockmgr(&amp;vc-&gt;rwlock, ap-&gt;a_flags | LK_CANRECURSE, &amp;vp-&gt;v_interlock,
  		   ap-&gt;a_p);
  }
  
--- 933,939 ----
  
      if (!vc)
  	panic("afs_nbsd_lock: null vcache");
!     return afs_osi_lockmgr(&amp;vc-&gt;rwlock, ap-&gt;a_flags | LK_CANRECURSE, &amp;vp-&gt;v_interlock,
  		   ap-&gt;a_p);
  }
  
***************
*** 950,956 ****
  
      if (!vc)
  	panic("afs_nbsd_unlock: null vcache");
!     return lockmgr(&amp;vc-&gt;rwlock, ap-&gt;a_flags | LK_RELEASE, &amp;vp-&gt;v_interlock,
  		   ap-&gt;a_p);
  }
  
--- 950,956 ----
  
      if (!vc)
  	panic("afs_nbsd_unlock: null vcache");
!     return afs_osi_lockmgr(&amp;vc-&gt;rwlock, ap-&gt;a_flags | LK_RELEASE, &amp;vp-&gt;v_interlock,
  		   ap-&gt;a_p);
  }
  
Index: openafs/src/afs/SUNOS/osi_inode.h
diff -c openafs/src/afs/SUNOS/osi_inode.h:1.1 openafs/src/afs/SUNOS/osi_inode.h:1.2
*** openafs/src/afs/SUNOS/osi_inode.h:1.1	Wed Aug 21 15:23:16 2002
--- openafs/src/afs/SUNOS/osi_inode.h	Wed Mar 22 15:05:47 2006
***************
*** 1 ****
! #error kernel code not supported on SunOS 4 
--- 1 ----
! #error kernel code not supported on SunOS 4
Index: openafs/src/afs/VNOPS/afs_vnop_attrs.c
diff -c openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.40 openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.41
*** openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.40	Sun Oct 23 02:27:03 2005
--- openafs/src/afs/VNOPS/afs_vnop_attrs.c	Wed Apr  5 12:04:37 2006
***************
*** 24,30 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.40 2005/10/23 06:27:03 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 24,30 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.41 2006/04/05 16:04:37 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 105,118 ****
  	/* The mount point's vnode. */
  	if (tvp) {
  	    attrs-&gt;va_nodeid =
! 		tvp-&gt;mtpoint.Fid.Vnode + (tvp-&gt;mtpoint.Fid.Volume &lt;&lt; 16);
  	    if (FidCmp(&amp;afs_rootFid, &amp;avc-&gt;fid) &amp;&amp; !attrs-&gt;va_nodeid)
  		attrs-&gt;va_nodeid = 2;
  	    afs_PutVolume(tvp, READ_LOCK);
  	} else
  	    attrs-&gt;va_nodeid = 2;
      } else
! 	attrs-&gt;va_nodeid = avc-&gt;fid.Fid.Vnode + (avc-&gt;fid.Fid.Volume &lt;&lt; 16);
      attrs-&gt;va_nodeid &amp;= 0x7fffffff;	/* Saber C hates negative inode #s! */
      attrs-&gt;va_nlink = fakedir ? 100 : avc-&gt;m.LinkCount;
      attrs-&gt;va_size = fakedir ? 4096 : avc-&gt;m.Length;
--- 105,121 ----
  	/* The mount point's vnode. */
  	if (tvp) {
  	    attrs-&gt;va_nodeid =
! 	      afs_calc_inum (tvp-&gt;mtpoint.Fid.Volume,
! 			      tvp-&gt;mtpoint.Fid.Vnode);
  	    if (FidCmp(&amp;afs_rootFid, &amp;avc-&gt;fid) &amp;&amp; !attrs-&gt;va_nodeid)
  		attrs-&gt;va_nodeid = 2;
  	    afs_PutVolume(tvp, READ_LOCK);
  	} else
  	    attrs-&gt;va_nodeid = 2;
      } else
! 	attrs-&gt;va_nodeid = 
! 	      afs_calc_inum (avc-&gt;fid.Fid.Volume,
! 			      avc-&gt;fid.Fid.Vnode);
      attrs-&gt;va_nodeid &amp;= 0x7fffffff;	/* Saber C hates negative inode #s! */
      attrs-&gt;va_nlink = fakedir ? 100 : avc-&gt;m.LinkCount;
      attrs-&gt;va_size = fakedir ? 4096 : avc-&gt;m.Length;
Index: openafs/src/afs/VNOPS/afs_vnop_flock.c
diff -c openafs/src/afs/VNOPS/afs_vnop_flock.c:1.27 openafs/src/afs/VNOPS/afs_vnop_flock.c:1.29
*** openafs/src/afs/VNOPS/afs_vnop_flock.c:1.27	Sun Apr  3 14:09:14 2005
--- openafs/src/afs/VNOPS/afs_vnop_flock.c	Mon Mar 13 14:18:07 2006
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_flock.c,v 1.27 2005/04/03 18:09:14 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 16,22 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_flock.c,v 1.29 2006/03/13 19:18:07 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 569,575 ****
  #endif
  	) &amp;&amp; code != LOCK_UN)
  	code |= LOCK_NB;	/* non-blocking, s.v.p. */
! #if	defined(AFS_OSF_ENV)
      code = HandleFlock(avc, code, &amp;treq, clid, 0 /*!onlymine */ );
  #elif defined(AFS_SGI_ENV)
      AFS_RWLOCK((vnode_t *) avc, VRWLOCK_WRITE);
--- 569,575 ----
  #endif
  	) &amp;&amp; code != LOCK_UN)
  	code |= LOCK_NB;	/* non-blocking, s.v.p. */
! #if	defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)
      code = HandleFlock(avc, code, &amp;treq, clid, 0 /*!onlymine */ );
  #elif defined(AFS_SGI_ENV)
      AFS_RWLOCK((vnode_t *) avc, VRWLOCK_WRITE);
Index: openafs/src/afs/VNOPS/afs_vnop_read.c
diff -c openafs/src/afs/VNOPS/afs_vnop_read.c:1.33 openafs/src/afs/VNOPS/afs_vnop_read.c:1.34
*** openafs/src/afs/VNOPS/afs_vnop_read.c:1.33	Thu Oct 13 11:12:08 2005
--- openafs/src/afs/VNOPS/afs_vnop_read.c	Mon Feb 20 23:45:10 2006
***************
*** 19,25 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_read.c,v 1.33 2005/10/13 15:12:08 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 19,25 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_read.c,v 1.34 2006/02/21 04:45:10 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 353,358 ****
--- 353,364 ----
  
  	if (len &lt;= 0)
  	    break;		/* surprise eof */
+ #ifdef AFS_DARWIN80_ENV
+ 	if (tuiop) {
+ 	    uio_free(tuiop);
+ 	    tuiop = 0;
+ 	}
+ #endif
      }				/* the whole while loop */
  
      /*
***************
*** 880,885 ****
--- 886,897 ----
  	filePos += len;
  	if (len &lt;= 0)
  	    break;		/* surprise eof */
+ #ifdef AFS_DARWIN80_ENV
+ 	if (tuiop) {
+ 	    uio_free(tuiop);
+ 	    tuiop = 0;
+ 	}
+ #endif
      }
  
      /* if we make it here with tdc non-zero, then it is the last chunk we
Index: openafs/src/afs/VNOPS/afs_vnop_remove.c
diff -c openafs/src/afs/VNOPS/afs_vnop_remove.c:1.48 openafs/src/afs/VNOPS/afs_vnop_remove.c:1.52
*** openafs/src/afs/VNOPS/afs_vnop_remove.c:1.48	Tue Jan 10 10:09:55 2006
--- openafs/src/afs/VNOPS/afs_vnop_remove.c	Mon Mar 13 14:18:07 2006
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.48 2006/01/10 15:09:55 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.52 2006/03/13 19:18:07 rees Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 349,354 ****
--- 349,356 ----
      if (tvc &amp;&amp; osi_Active(tvc)) {
  	/* about to delete whole file, prefetch it first */
  	ReleaseWriteLock(&amp;adp-&gt;lock);
+ 	if (tdc)
+ 	    ReleaseSharedLock(&amp;tdc-&gt;lock);
  	ObtainWriteLock(&amp;tvc-&gt;lock, 143);
  #if	defined(AFS_OSF_ENV)
  	afs_Wire(tvc, &amp;treq);
***************
*** 356,363 ****
  	FetchWholeEnchilada(tvc, &amp;treq);
  #endif
  	ReleaseWriteLock(&amp;tvc-&gt;lock);
- 	if (tdc) 
- 	    ReleaseSharedLock(&amp;tdc-&gt;lock);
  	ObtainWriteLock(&amp;adp-&gt;lock, 144);
  	/* Technically I don't think we need this back, but let's hold it 
  	   anyway; The "got" reference should actually be sufficient. */
--- 358,363 ----
***************
*** 374,381 ****
      Ttvc = tvc;
      Tnam = aname;
      Tnam1 = 0;
-     if (tvc)
  #ifndef AFS_DARWIN80_ENV
  	Ttvcr = VREFCOUNT(tvc);
  #endif
  #ifdef	AFS_AIX_ENV
--- 374,381 ----
      Ttvc = tvc;
      Tnam = aname;
      Tnam1 = 0;
  #ifndef AFS_DARWIN80_ENV
+     if (tvc)
  	Ttvcr = VREFCOUNT(tvc);
  #endif
  #ifdef	AFS_AIX_ENV
***************
*** 393,399 ****
  	code = afsrename(adp, aname, adp, unlname, acred, &amp;treq);
  	Tnam1 = unlname;
  	if (!code) {
! 	    char *oldmvid = NULL;
  	    if (tvc-&gt;mvid) 
  		oldmvid = tvc-&gt;mvid;
  	    tvc-&gt;mvid = (struct VenusFid *)unlname;
--- 393,399 ----
  	code = afsrename(adp, aname, adp, unlname, acred, &amp;treq);
  	Tnam1 = unlname;
  	if (!code) {
! 	    struct VenusFid *oldmvid = NULL;
  	    if (tvc-&gt;mvid) 
  		oldmvid = tvc-&gt;mvid;
  	    tvc-&gt;mvid = (struct VenusFid *)unlname;
***************
*** 438,443 ****
--- 438,449 ----
  
      if (NBObtainWriteLock(&amp;avc-&gt;lock, 423))
  	return 0;
+ #if defined(AFS_DARWIN80_ENV)
+     if (vnode_get(AFSTOV(avc))) {
+ 	ReleaseWriteLock(&amp;avc-&gt;lock);
+ 	return 0;
+     }
+ #endif
  
      if (avc-&gt;mvid &amp;&amp; (doit || (avc-&gt;states &amp; CUnlinkedDel))) {
  	if ((code = afs_InitReq(&amp;treq, avc-&gt;uncred))) {
***************
*** 487,492 ****
--- 493,501 ----
  	    crfree(cred);
  	}
      } else {
+ #if defined(AFS_DARWIN80_ENV)
+ 	vnode_put(AFSTOV(avc));
+ #endif
  	ReleaseWriteLock(&amp;avc-&gt;lock);
      }
  
Index: openafs/src/afs/VNOPS/afs_vnop_write.c
diff -c openafs/src/afs/VNOPS/afs_vnop_write.c:1.48 openafs/src/afs/VNOPS/afs_vnop_write.c:1.50
*** openafs/src/afs/VNOPS/afs_vnop_write.c:1.48	Thu Oct 13 11:12:08 2005
--- openafs/src/afs/VNOPS/afs_vnop_write.c	Mon Apr  3 21:35:15 2006
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_write.c,v 1.48 2005/10/13 15:12:08 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_write.c,v 1.50 2006/04/04 01:35:15 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 106,112 ****
  #endif
      afs_int32 error;
  #ifdef AFS_DARWIN80_ENV
!     uio_t tuiop;
  #else
      struct uio tuio;
      struct uio *tuiop = &amp;tuio;
--- 106,112 ----
  #endif
      afs_int32 error;
  #ifdef AFS_DARWIN80_ENV
!     uio_t tuiop = NULL;
  #else
      struct uio tuio;
      struct uio *tuiop = &amp;tuio;
***************
*** 264,269 ****
--- 264,271 ----
  	}
  
  #ifdef  AFS_DARWIN80_ENV
+         if (tuiop)
+ 	    uio_free(tuiop);
  	trimlen = len;
  	tuiop = afsio_darwin_partialcopy(auio, trimlen);
  #else
***************
*** 366,372 ****
  #endif
      afs_int32 error;
  #ifdef AFS_DARWIN80_ENV
!     uio_t tuiop;
  #else
      struct uio tuio;
      struct uio *tuiop = &amp;tuio;
--- 368,374 ----
  #endif
      afs_int32 error;
  #ifdef AFS_DARWIN80_ENV
!     uio_t tuiop = NULL;
  #else
      struct uio tuio;
      struct uio *tuiop = &amp;tuio;
***************
*** 527,532 ****
--- 529,536 ----
  	}
  
  #ifdef  AFS_DARWIN80_ENV
+ 	if (tuiop)
+ 	    uio_free(tuiop);
  	trimlen = len;
  	tuiop = afsio_darwin_partialcopy(auio, trimlen);
  #else
***************
*** 869,883 ****
  	afs_PutFakeStat(&amp;fakestat);
  	return 0;
      }
- #elif	defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
-     if (count &gt; 1) {
- 	/* The vfs layer may call this repeatedly with higher "count"; only on the last close (i.e. count = 1) we should actually proceed with the close. */
- 	afs_PutFakeStat(&amp;fakestat);
- 	return 0;
-     }
- #endif
- #ifndef	AFS_SUN5_ENV
- #if defined(AFS_SGI_ENV)
      /* unlock any locks for pid - could be wrong for child .. */
      AFS_RWLOCK((vnode_t *) avc, VRWLOCK_WRITE);
  #ifdef AFS_SGI65_ENV
--- 873,878 ----
***************
*** 894,899 ****
--- 889,900 ----
  #endif /* AFS_SGI65_ENV */
      /* afs_chkpgoob will drop and re-acquire the global lock. */
      afs_chkpgoob(&amp;avc-&gt;v, btoc(avc-&gt;m.Length));
+ #elif	defined(AFS_SUN5_ENV)
+     if (count &gt; 1) {
+ 	/* The vfs layer may call this repeatedly with higher "count"; only on the last close (i.e. count = 1) we should actually proceed with the close. */
+ 	afs_PutFakeStat(&amp;fakestat);
+ 	return 0;
+     }
  #else /* AFS_SGI_ENV */
      if (avc-&gt;flockCount) {	/* Release Lock */
  #if	defined(AFS_OSF_ENV) 
***************
*** 903,909 ****
  #endif
      }
  #endif /* AFS_SGI_ENV */
- #endif /* AFS_SUN5_ENV */
      if (aflags &amp; (FWRITE | FTRUNC)) {
  	if (afs_BBusy()) {
  	    /* do it yourself if daemons are all busy */
--- 904,909 ----
Index: openafs/src/afsd/Makefile.in
diff -c openafs/src/afsd/Makefile.in:1.17 openafs/src/afsd/Makefile.in:1.18
*** openafs/src/afsd/Makefile.in:1.17	Thu Jan 13 20:11:48 2005
--- openafs/src/afsd/Makefile.in	Thu Mar  9 01:34:29 2006
***************
*** 9,15 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! LDFLAGS = ${XLDFLAGS}
  
  #
  # What to make
--- 9,15 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! LDFLAGS = ${XLDFLAGS} ${ARCHFLAGS}
  
  #
  # What to make
Index: openafs/src/afsd/afs.rc.obsd
diff -c openafs/src/afsd/afs.rc.obsd:1.3 openafs/src/afsd/afs.rc.obsd:1.4
*** openafs/src/afsd/afs.rc.obsd:1.3	Fri Jan 31 16:35:14 2003
--- openafs/src/afsd/afs.rc.obsd	Fri Apr 21 10:58:38 2006
***************
*** 5,9 ****
  rm -f /usr/vice/etc/openbsd_afs
  /sbin/modload -o /usr/vice/etc/openbsd_afs /usr/vice/etc/libafs.o 
  
! /usr/vice/etc/afsd -nosettime
  /usr/vice/bin/fs setcrypt on
--- 5,9 ----
  rm -f /usr/vice/etc/openbsd_afs
  /sbin/modload -o /usr/vice/etc/openbsd_afs /usr/vice/etc/libafs.o 
  
! /usr/vice/etc/afsd -afsdb -stat 600
  /usr/vice/bin/fs setcrypt on
Index: openafs/src/afsd/afsd.c
diff -c openafs/src/afsd/afsd.c:1.59 openafs/src/afsd/afsd.c:1.60
*** openafs/src/afsd/afsd.c:1.59	Wed Nov 30 23:02:23 2005
--- openafs/src/afsd/afsd.c	Thu Mar 23 10:35:53 2006
***************
*** 58,64 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsd/afsd.c,v 1.59 2005/12/01 04:02:23 shadow Exp $");
  
  #define VFS 1
  
--- 58,64 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsd/afsd.c,v 1.60 2006/03/23 15:35:53 shadow Exp $");
  
  #define VFS 1
  
***************
*** 1074,1079 ****
--- 1074,1083 ----
  	    return "cannot use reiserfs as cache partition";
  	} else if (statfsbuf.f_type == 0x58465342) {	/* XFS_SUPER_MAGIC */
  	    return "cannot use xfs as cache partition";
+ 	} else if (statfsbuf.f_type == 0x01021994) {    /* TMPFS_SUPER_MAGIC */
+             return "cannot use tmpfs as cache partition";
+         } else if (statfsbuf.f_type != 0xEF53) {
+             return "must use ext2 or ext3 for cache partition";
  	}
      }
  #endif
***************
*** 1741,1747 ****
--- 1745,1756 ----
  
      if (!(cacheFlags &amp; AFSCALL_INIT_MEMCACHE)
  	&amp;&amp; (fsTypeMsg = CheckCacheBaseDir(cacheBaseDir))) {
+ #ifdef AFS_SUN5_ENV
  	printf("%s: WARNING: Cache dir check failed (%s)\n", rn, fsTypeMsg);
+ #else
+ 	printf("%s: ERROR: Cache dir check failed (%s)\n", rn, fsTypeMsg);
+ 	exit(1);
+ #endif
      }
  #if 0
      fputs(AFS_GOVERNMENT_MESSAGE, stdout);
Index: openafs/src/afsmonitor/afsmon-output.c
diff -c openafs/src/afsmonitor/afsmon-output.c:1.9 openafs/src/afsmonitor/afsmon-output.c:1.10
*** openafs/src/afsmonitor/afsmon-output.c:1.9	Tue Jul 15 19:14:32 2003
--- openafs/src/afsmonitor/afsmon-output.c	Tue Apr  4 16:51:13 2006
***************
*** 29,35 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsmonitor/afsmon-output.c,v 1.9 2003/07/15 23:14:32 shadow Exp $");
  
  #include &lt;afs/xstat_fs.h&gt;
  #include &lt;afs/xstat_cm.h&gt;
--- 29,35 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsmonitor/afsmon-output.c,v 1.10 2006/04/04 20:51:13 shadow Exp $");
  
  #include &lt;afs/xstat_fs.h&gt;
  #include &lt;afs/xstat_cm.h&gt;
***************
*** 389,395 ****
      afs_int32 numLongs;		/*# longwords received */
      struct fs_stats_FullPerfStats *fullPerfP;	/*Ptr to full perf stats */
      char *printableTime;	/*Ptr to printable time string */
! 
  
      numLongs = a_fs_Results-&gt;data.AFS_CollData_len;
      if (numLongs != fullPerfLongs) {
--- 389,395 ----
      afs_int32 numLongs;		/*# longwords received */
      struct fs_stats_FullPerfStats *fullPerfP;	/*Ptr to full perf stats */
      char *printableTime;	/*Ptr to printable time string */
!     time_t probeTime;
  
      numLongs = a_fs_Results-&gt;data.AFS_CollData_len;
      if (numLongs != fullPerfLongs) {
***************
*** 400,406 ****
  	return;
      }
  
!     printableTime = ctime((time_t *) &amp; (a_fs_Results-&gt;probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
      fullPerfP = (struct fs_stats_FullPerfStats *)
  	(a_fs_Results-&gt;data.AFS_CollData_val);
--- 400,407 ----
  	return;
      }
  
!     probeTime = a_fs_Results-&gt;probeTime;
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
      fullPerfP = (struct fs_stats_FullPerfStats *)
  	(a_fs_Results-&gt;data.AFS_CollData_val);
***************
*** 449,454 ****
--- 450,456 ----
      afs_int32 numLongs;		/* longwords in result */
      afs_int32 *currLong;	/* ptr to longwords in result */
      int i;
+     time_t probeTime;
  
      if (afsmon_debug) {
  	fprintf(debugFD, "[ %s ] Called, a_outfile= %s, a_detOutput= %d\n",
***************
*** 464,470 ****
      }
  
      /* get the probe time and strip the \n at the end */
!     printTime = ctime((time_t *) &amp; (xstat_fs_Results.probeTime));
      printTime[strlen(printTime) - 1] = '\0';
      hostname = xstat_fs_Results.connP-&gt;hostName;
  
--- 466,473 ----
      }
  
      /* get the probe time and strip the \n at the end */
!     probeTime = xstat_fs_Results.probeTime;
!     printTime = ctime(&amp;probeTime);
      printTime[strlen(printTime) - 1] = '\0';
      hostname = xstat_fs_Results.connP-&gt;hostName;
  
***************
*** 709,714 ****
--- 712,718 ----
      afs_int32 numLongs;		/*# longwords received */
      struct afs_stats_CMPerf *perfP;	/*Ptr to performance stats */
      char *printableTime;	/*Ptr to printable time string */
+     time_t probeTime;
  
      numLongs = xstat_cm_Results.data.AFSCB_CollData_len;
      if (numLongs != perfLongs) {
***************
*** 718,724 ****
  	return;
      }
  
!     printableTime = ctime((time_t *) &amp; (xstat_cm_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
      perfP = (struct afs_stats_CMPerf *)
  	(xstat_cm_Results.data.AFSCB_CollData_val);
--- 722,729 ----
  	return;
      }
  
!     probeTime = xstat_cm_Results.probeTime;
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
      perfP = (struct afs_stats_CMPerf *)
  	(xstat_cm_Results.data.AFSCB_CollData_val);
***************
*** 935,941 ****
      static afs_int32 fullPerfLongs = (sizeof(struct afs_stats_CMFullPerf) &gt;&gt; 2);	/*Correct #longs */
      afs_int32 numLongs;		/*# longs actually received */
      struct afs_stats_CMFullPerf *fullP;	/*Ptr to full perf info */
! 
      char *printableTime;	/*Ptr to printable time string */
  
      numLongs = xstat_cm_Results.data.AFSCB_CollData_len;
--- 940,946 ----
      static afs_int32 fullPerfLongs = (sizeof(struct afs_stats_CMFullPerf) &gt;&gt; 2);	/*Correct #longs */
      afs_int32 numLongs;		/*# longs actually received */
      struct afs_stats_CMFullPerf *fullP;	/*Ptr to full perf info */
!     time_t probeTime;
      char *printableTime;	/*Ptr to printable time string */
  
      numLongs = xstat_cm_Results.data.AFSCB_CollData_len;
***************
*** 947,953 ****
  	return;
      }
  
!     printableTime = ctime((time_t *) &amp; (xstat_cm_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
      fullP = (struct afs_stats_CMFullPerf *)
  	(xstat_cm_Results.data.AFSCB_CollData_val);
--- 952,959 ----
  	return;
      }
  
!     probeTime = xstat_cm_Results.probeTime;
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
      fullP = (struct afs_stats_CMFullPerf *)
  	(xstat_cm_Results.data.AFSCB_CollData_val);
***************
*** 1029,1034 ****
--- 1035,1041 ----
      afs_int32 numLongs;		/* longwords in result */
      afs_int32 *currLong;	/* ptr to longwords in result */
      int i;
+     time_t probeTime;
  
      if (afsmon_debug) {
  	fprintf(debugFD, "[ %s ] Called, a_outfile= %s, a_detOutput= %d\n",
***************
*** 1045,1051 ****
      }
  
      /* get the probe time and strip the \n at the end */
!     printTime = ctime((time_t *) &amp; (xstat_cm_Results.probeTime));
      printTime[strlen(printTime) - 1] = '\0';
      hostname = xstat_cm_Results.connP-&gt;hostName;
  
--- 1052,1059 ----
      }
  
      /* get the probe time and strip the \n at the end */
!     probeTime = xstat_cm_Results.probeTime;
!     printTime = ctime(&amp;probeTime);
      printTime[strlen(printTime) - 1] = '\0';
      hostname = xstat_cm_Results.connP-&gt;hostName;
  
Index: openafs/src/afsmonitor/afsmon-parselog.c
diff -c openafs/src/afsmonitor/afsmon-parselog.c:1.5 openafs/src/afsmonitor/afsmon-parselog.c:1.6
*** openafs/src/afsmonitor/afsmon-parselog.c:1.5	Tue Jul 15 19:14:32 2003
--- openafs/src/afsmonitor/afsmon-parselog.c	Tue Apr  4 16:51:13 2006
***************
*** 22,28 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsmonitor/afsmon-parselog.c,v 1.5 2003/07/15 23:14:32 shadow Exp $");
  
  #include &lt;afs/xstat_fs.h&gt;
  #include &lt;afs/xstat_cm.h&gt;
--- 22,28 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsmonitor/afsmon-parselog.c,v 1.6 2006/04/04 20:51:13 shadow Exp $");
  
  #include &lt;afs/xstat_fs.h&gt;
  #include &lt;afs/xstat_cm.h&gt;
***************
*** 320,326 ****
      long numLongs;		/*# longwords received */
      struct fs_stats_FullPerfStats *fullPerfP;	/*Ptr to full perf stats */
      char *printableTime;	/*Ptr to printable time string */
! 
  
      numLongs = a_fs_Results-&gt;data.AFS_CollData_len;
      if (numLongs != fullPerfLongs) {
--- 320,326 ----
      long numLongs;		/*# longwords received */
      struct fs_stats_FullPerfStats *fullPerfP;	/*Ptr to full perf stats */
      char *printableTime;	/*Ptr to printable time string */
!     time_t probeTime;
  
      numLongs = a_fs_Results-&gt;data.AFS_CollData_len;
      if (numLongs != fullPerfLongs) {
***************
*** 329,335 ****
  	return;
      }
  
!     printableTime = ctime(&amp;(a_fs_Results-&gt;probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
      fullPerfP = (struct fs_stats_FullPerfStats *)
  	(a_fs_Results-&gt;data.AFS_CollData_val);
--- 329,336 ----
  	return;
      }
  
!     probeTime = a_fs_Results-&gt;probeTime;
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
      fullPerfP = (struct fs_stats_FullPerfStats *)
  	(a_fs_Results-&gt;data.AFS_CollData_val);
Index: openafs/src/afsmonitor/afsmonitor.c
diff -c openafs/src/afsmonitor/afsmonitor.c:1.20 openafs/src/afsmonitor/afsmonitor.c:1.21
*** openafs/src/afsmonitor/afsmonitor.c:1.20	Fri Aug 12 17:26:10 2005
--- openafs/src/afsmonitor/afsmonitor.c	Thu Mar  9 01:34:29 2006
***************
*** 19,25 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsmonitor/afsmonitor.c,v 1.20 2005/08/12 21:26:10 rees Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;math.h&gt;
--- 19,25 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/afsmonitor/afsmonitor.c,v 1.21 2006/03/09 06:34:29 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;math.h&gt;
***************
*** 3680,3686 ****
--- 3680,3690 ----
  	    }
  	    strncpy(curr_FS-&gt;hostName, he-&gt;h_name, HOST_NAME_LEN);	/* complete name */
  	    memcpy(&amp;(curr_skt-&gt;sin_addr.s_addr), he-&gt;h_addr, 4);
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+ 	    curr_skt-&gt;sin_family = AF_INET;		/*Internet family */
+ #else
  	    curr_skt-&gt;sin_family = htons(AF_INET);	/*Internet family */
+ #endif
  	    curr_skt-&gt;sin_port = htons(7000);	/*FileServer port */
  #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
  	    curr_skt-&gt;sin_len = sizeof(struct sockaddr_in);
***************
*** 3759,3765 ****
--- 3763,3773 ----
  	    }
  	    strncpy(curr_CM-&gt;hostName, he-&gt;h_name, HOST_NAME_LEN);	/* complete name */
  	    memcpy(&amp;(curr_skt-&gt;sin_addr.s_addr), he-&gt;h_addr, 4);
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+ 	    curr_skt-&gt;sin_family = AF_INET;		/*Internet family */
+ #else
  	    curr_skt-&gt;sin_family = htons(AF_INET);	/*Internet family */
+ #endif
  	    curr_skt-&gt;sin_port = htons(7001);	/*Cache Manager port */
  #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
  	    curr_skt-&gt;sin_len = sizeof(struct sockaddr_in);
Index: openafs/src/afsweb/apache_afs_weblog.c
diff -c openafs/src/afsweb/apache_afs_weblog.c:1.4 openafs/src/afsweb/apache_afs_weblog.c:1.5
*** openafs/src/afsweb/apache_afs_weblog.c:1.4	Tue Jul 15 19:14:35 2003
--- openafs/src/afsweb/apache_afs_weblog.c	Tue Apr  4 16:51:15 2006
***************
*** 91,97 ****
      char *time_string;
  
      t = time(NULL);
!     time_string = (char *)ctime((time_t *) &amp; t);
      time_string[strlen(time_string) - 1] = '\0';
      return (time_string);
  }
--- 91,97 ----
      char *time_string;
  
      t = time(NULL);
!     time_string = (char *)ctime(&amp;t);
      time_string[strlen(time_string) - 1] = '\0';
      return (time_string);
  }
Index: openafs/src/aklog/aklog.h
diff -c openafs/src/aklog/aklog.h:1.4 openafs/src/aklog/aklog.h:1.5
*** openafs/src/aklog/aklog.h:1.4	Thu Jun 30 17:06:15 2005
--- openafs/src/aklog/aklog.h	Mon Mar 20 12:29:28 2006
***************
*** 1,5 ****
  /* 
!  * $Id: aklog.h,v 1.4 2005/06/30 21:06:15 kenh Exp $
   *
   * Copyright 1990,1991 by the Massachusetts Institute of Technology
   * For distribution and copying rights, see the file "mit-copyright.h"
--- 1,5 ----
  /* 
!  * $Id: aklog.h,v 1.5 2006/03/20 17:29:28 jaltman Exp $
   *
   * Copyright 1990,1991 by the Massachusetts Institute of Technology
   * For distribution and copying rights, see the file "mit-copyright.h"
***************
*** 9,15 ****
  #define __AKLOG_H__
  
  #if !defined(lint) &amp;&amp; !defined(SABER)
! static char *rcsid_aklog_h = "$Id: aklog.h,v 1.4 2005/06/30 21:06:15 kenh Exp $";
  #endif /* lint || SABER */
  
  #include &lt;krb5.h&gt;
--- 9,15 ----
  #define __AKLOG_H__
  
  #if !defined(lint) &amp;&amp; !defined(SABER)
! static char *rcsid_aklog_h = "$Id: aklog.h,v 1.5 2006/03/20 17:29:28 jaltman Exp $";
  #endif /* lint || SABER */
  
  #include &lt;krb5.h&gt;
***************
*** 54,60 ****
  struct ktext {
      unsigned int length;
      unsigned char dat[MAX_KTXT_LEN];
!     u_int32_t mbz;
  };
  
  struct credentials {
--- 54,60 ----
  struct ktext {
      unsigned int length;
      unsigned char dat[MAX_KTXT_LEN];
!     afs_uint32 mbz;
  };
  
  struct credentials {
Index: openafs/src/audit/Makefile.in
diff -c openafs/src/audit/Makefile.in:1.8 openafs/src/audit/Makefile.in:1.9
*** openafs/src/audit/Makefile.in:1.8	Thu Apr 17 11:05:59 2003
--- openafs/src/audit/Makefile.in	Thu Mar  9 01:34:29 2006
***************
*** 15,21 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=-I. -I${srcdir} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
  
  all: ${TOP_LIBDIR}/libaudit.a ${TOP_INCDIR}/afs/audit.h
  
--- 15,21 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=-I. -I${srcdir} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS}
  
  all: ${TOP_LIBDIR}/libaudit.a ${TOP_INCDIR}/afs/audit.h
  
Index: openafs/src/auth/Makefile.in
diff -c openafs/src/auth/Makefile.in:1.13 openafs/src/auth/Makefile.in:1.14
*** openafs/src/auth/Makefile.in:1.13	Mon Oct 18 02:08:16 2004
--- openafs/src/auth/Makefile.in	Fri Mar 17 14:54:32 2006
***************
*** 96,102 ****
  	cd test; $(MAKE)
  
  clean:
! 	$(RM) -f *.o *.a copyauth setkey auth.h cellconfig.h acfg_errors.c ktc_errors.c core\
  	AFS_component_version_number.c
  
  include ../config/Makefile.version
--- 96,102 ----
  	cd test; $(MAKE)
  
  clean:
! 	$(RM) -f *.o *.a copyauth setkey auth.h cellconfig.h acfg_errors.c ktc_errors.c core \
  	AFS_component_version_number.c
  
  include ../config/Makefile.version
Index: openafs/src/auth/cellconfig.c
diff -c openafs/src/auth/cellconfig.c:1.46 openafs/src/auth/cellconfig.c:1.47
*** openafs/src/auth/cellconfig.c:1.46	Mon Nov  7 14:48:07 2005
--- openafs/src/auth/cellconfig.c	Tue Mar 28 13:39:45 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/auth/cellconfig.c,v 1.46 2005/11/07 19:48:07 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;afs/pthread_glock.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/auth/cellconfig.c,v 1.47 2006/03/28 18:39:45 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;afs/pthread_glock.h&gt;
***************
*** 736,743 ****
  		     struct afsconf_cell *acellInfo)
  {
      afs_int32 code;
!     int tservice, i;
!     size_t len;
      unsigned char answer[1024];
      unsigned char *p;
      char *dotcellname;
--- 736,742 ----
  		     struct afsconf_cell *acellInfo)
  {
      afs_int32 code;
!     int tservice, i, len;
      unsigned char answer[1024];
      unsigned char *p;
      char *dotcellname;
Index: openafs/src/auth/test/Makefile.in
diff -c openafs/src/auth/test/Makefile.in:1.5 openafs/src/auth/test/Makefile.in:1.6
*** openafs/src/auth/test/Makefile.in:1.5	Wed Oct 31 23:59:35 2001
--- openafs/src/auth/test/Makefile.in	Thu Mar  9 01:34:30 2006
***************
*** 12,18 ****
  LDIRS= -L${DESTDIR}/lib -L${DESTDIR}/lib/afs -L${DESTDIR}/lib/rx
  LIBS= -lauth -lsys -lrx -llwp -lafsutil ${XLIBS}
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${XCFLAGS}
  
  tests all: testcellconf ktctest
  
--- 12,18 ----
  LDIRS= -L${DESTDIR}/lib -L${DESTDIR}/lib/afs -L${DESTDIR}/lib/rx
  LIBS= -lauth -lsys -lrx -llwp -lafsutil ${XLIBS}
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${XCFLAGS} ${ARCHFLAGS}
  
  tests all: testcellconf ktctest
  
Index: openafs/src/bozo/bos.c
diff -c openafs/src/bozo/bos.c:1.22 openafs/src/bozo/bos.c:1.23
*** openafs/src/bozo/bos.c:1.22	Sat Oct  9 21:38:50 2004
--- openafs/src/bozo/bos.c	Fri Mar 17 14:54:36 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/bozo/bos.c,v 1.22 2004/10/10 01:38:50 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;stdlib.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/bozo/bos.c,v 1.23 2006/03/17 19:54:36 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;stdlib.h&gt;
***************
*** 52,61 ****
  
  #include "bosint.h"
  
! #define MRAFS_OFFSET  9
! #define ADDPARMOFFSET 26
  
! static struct SalvageParms {
      afs_int32 Optdebug;
      afs_int32 Optnowrite;
      afs_int32 Optforce;
--- 52,63 ----
  
  #include "bosint.h"
  
! /* command offsets for bos salvage command */
! #define MRAFS_OFFSET  10
! #define ADDPARMOFFSET 27
  
! /* MR-AFS salvage parameters */
! struct MRAFSSalvageParms {
      afs_int32 Optdebug;
      afs_int32 Optnowrite;
      afs_int32 Optforce;
***************
*** 74,80 ****
      afs_int32 OptLogLevel;
      afs_int32 OptRxDebug;
      afs_uint32 OptResidencies;
! } mrafsParm;
  
  /* dummy routine for the audit work.  It should do nothing since audits */
  /* occur at the server level and bos is not a server. */
--- 76,82 ----
      afs_int32 OptLogLevel;
      afs_int32 OptRxDebug;
      afs_uint32 OptResidencies;
! };
  
  /* dummy routine for the audit work.  It should do nothing since audits */
  /* occur at the server level and bos is not a server. */
***************
*** 1224,1240 ****
  
  #define PARMBUFFERSSIZE 32
  
! static
! DoSalvage(aconn, aparm1, aparm2, aoutName, showlog, parallel, atmpDir,
! 	  orphans)
!      struct rx_connection *aconn;
!      char *aoutName;
!      char *aparm1;
!      char *aparm2;
!      afs_int32 showlog;
!      char *parallel;
!      char *atmpDir;
!      char *orphans;
  {
      register afs_int32 code;
      char *parms[6];
--- 1226,1236 ----
  
  #define PARMBUFFERSSIZE 32
  
! static afs_int32
! DoSalvage(struct rx_connection * aconn, char * aparm1, char * aparm2, 
! 	  char * aoutName, afs_int32 showlog, char * parallel, 
! 	  char * atmpDir, char * orphans, int dafs, 
! 	  struct MRAFSSalvageParms * mrafsParm)
  {
      register afs_int32 code;
      char *parms[6];
***************
*** 1285,1303 ****
  	parms[code] = "";
      if (!aparm2)
  	aparm2 = "";
      /* MUST pass canonical (wire-format) salvager path to bosserver */
-     strncpy(tbuffer, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH, BOZO_BSSIZE);
      if (*aparm2 != 0) {
! 	if ((strlen(tbuffer) + 1 + strlen(partName) + 1 + strlen(aparm2) +
! 	     1) &gt; BOZO_BSSIZE) {
! 	    printf("bos: command line too big\n");
! 	    return (E2BIG);
  	}
- 	strcat(tbuffer, " ");
- 	strcat(tbuffer, partName);
- 	strcat(tbuffer, " ");
- 	strcat(tbuffer, aparm2);
      } else {
  	if ((strlen(tbuffer) + 4 + strlen(partName) + 1) &gt; BOZO_BSSIZE) {
  	    printf("bos: command line too big\n");
  	    return (E2BIG);
--- 1281,1323 ----
  	parms[code] = "";
      if (!aparm2)
  	aparm2 = "";
+ 
      /* MUST pass canonical (wire-format) salvager path to bosserver */
      if (*aparm2 != 0) {
! 	/* single volume salvage */
! 	if (dafs) {
! 	    /* for DAFS, we call the salvagserver binary with special options.
! 	     * in this mode, it simply uses SALVSYNC to tell the currently
! 	     * running salvageserver to offline and salvage the volume in question */
! 	    strncpy(tbuffer, AFSDIR_CANONICAL_SERVER_SALSRV_FILEPATH, BOZO_BSSIZE);
! 
! 	    if ((strlen(tbuffer) + 9 + strlen(partName) + 1 + strlen(aparm2) +
! 		 1) &gt; BOZO_BSSIZE) {
! 		printf("bos: command line too big\n");
! 		return (E2BIG);
! 	    }
! 
! 	    strcat(tbuffer, " -client ");
! 	    strcat(tbuffer, partName);
! 	    strcat(tbuffer, " ");
! 	    strcat(tbuffer, aparm2);
! 	} else {
! 	    strncpy(tbuffer, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH, BOZO_BSSIZE);
! 
! 	    if ((strlen(tbuffer) + 1 + strlen(partName) + 1 + strlen(aparm2) +
! 		 1) &gt; BOZO_BSSIZE) {
! 		printf("bos: command line too big\n");
! 		return (E2BIG);
! 	    }
! 
! 	    strcat(tbuffer, " ");
! 	    strcat(tbuffer, partName);
! 	    strcat(tbuffer, " ");
! 	    strcat(tbuffer, aparm2);
  	}
      } else {
+ 	/* partition salvage */
+ 	strncpy(tbuffer, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH, BOZO_BSSIZE);
  	if ((strlen(tbuffer) + 4 + strlen(partName) + 1) &gt; BOZO_BSSIZE) {
  	    printf("bos: command line too big\n");
  	    return (E2BIG);
***************
*** 1306,1380 ****
  	strcat(tbuffer, partName);
      }
  
!     /* add the parallel option if given */
!     if (parallel != NULL) {
! 	if ((strlen(tbuffer) + 11 + strlen(parallel) + 1) &gt; BOZO_BSSIZE) {
! 	    printf("bos: command line too big\n");
! 	    return (E2BIG);
  	}
- 	strcat(tbuffer, " -parallel ");
- 	strcat(tbuffer, parallel);
-     }
  
!     /* add the tmpdir option if given */
!     if (atmpDir != NULL) {
! 	if ((strlen(tbuffer) + 9 + strlen(atmpDir) + 1) &gt; BOZO_BSSIZE) {
! 	    printf("bos: command line too big\n");
! 	    return (E2BIG);
  	}
- 	strcat(tbuffer, " -tmpdir ");
- 	strcat(tbuffer, atmpDir);
-     }
  
!     /* add the orphans option if given */
!     if (orphans != NULL) {
! 	if ((strlen(tbuffer) + 10 + strlen(orphans) + 1) &gt; BOZO_BSSIZE) {
! 	    printf("bos: command line too big\n");
! 	    return (E2BIG);
  	}
- 	strcat(tbuffer, " -orphans ");
- 	strcat(tbuffer, orphans);
-     }
  
!     if (mrafsParm.Optdebug)
! 	strcat(tbuffer, " -debug");
!     if (mrafsParm.Optnowrite)
! 	strcat(tbuffer, " -nowrite");
!     if (mrafsParm.Optforce)
! 	strcat(tbuffer, " -force");
!     if (mrafsParm.Optoktozap)
! 	strcat(tbuffer, " -oktozap");
!     if (mrafsParm.Optrootfiles)
! 	strcat(tbuffer, " -rootfiles");
!     if (mrafsParm.Optsalvagedirs)
! 	strcat(tbuffer, " -salvagedirs");
!     if (mrafsParm.Optblockreads)
! 	strcat(tbuffer, " -blockreads");
!     if (mrafsParm.OptListResidencies)
! 	strcat(tbuffer, " -ListResidencies");
!     if (mrafsParm.OptSalvageRemote)
! 	strcat(tbuffer, " -SalvageRemote");
!     if (mrafsParm.OptSalvageArchival)
! 	strcat(tbuffer, " -SalvageArchival");
!     if (mrafsParm.OptIgnoreCheck)
! 	strcat(tbuffer, " -IgnoreCheck");
!     if (mrafsParm.OptForceOnLine)
! 	strcat(tbuffer, " -ForceOnLine");
!     if (mrafsParm.OptUseRootDirACL)
! 	strcat(tbuffer, " -UseRootDirACL");
!     if (mrafsParm.OptTraceBadLinkCounts)
! 	strcat(tbuffer, " -TraceBadLinkCounts");
!     if (mrafsParm.OptDontAskFS)
! 	strcat(tbuffer, " -DontAskFS");
!     if (mrafsParm.OptLogLevel) {
! 	sprintf(pbuffer, " -LogLevel %ld", mrafsParm.OptLogLevel);
! 	strcat(tbuffer, pbuffer);
!     }
!     if (mrafsParm.OptRxDebug)
! 	strcat(tbuffer, " -rxdebug");
!     if (mrafsParm.OptResidencies) {
! 	sprintf(pbuffer, " -Residencies %lu", mrafsParm.OptResidencies);
! 	strcat(tbuffer, pbuffer);
      }
  
      parms[0] = tbuffer;
--- 1326,1407 ----
  	strcat(tbuffer, partName);
      }
  
!     /* For DAFS, specifying a single volume does not result in a standard
!      * salvager call.  Instead, it simply results in a SALVSYNC call to the
!      * online salvager daemon.  This interface does not give us the same rich
!      * set of call flags.  Thus, we skip these steps for DAFS single-volume 
!      * calls */
!     if (!dafs || (*aparm2 == 0)) {
! 	/* add the parallel option if given */
! 	if (parallel != NULL) {
! 	    if ((strlen(tbuffer) + 11 + strlen(parallel) + 1) &gt; BOZO_BSSIZE) {
! 		printf("bos: command line too big\n");
! 		return (E2BIG);
! 	    }
! 	    strcat(tbuffer, " -parallel ");
! 	    strcat(tbuffer, parallel);
  	}
  
! 	/* add the tmpdir option if given */
! 	if (atmpDir != NULL) {
! 	    if ((strlen(tbuffer) + 9 + strlen(atmpDir) + 1) &gt; BOZO_BSSIZE) {
! 		printf("bos: command line too big\n");
! 		return (E2BIG);
! 	    }
! 	    strcat(tbuffer, " -tmpdir ");
! 	    strcat(tbuffer, atmpDir);
  	}
  
! 	/* add the orphans option if given */
! 	if (orphans != NULL) {
! 	    if ((strlen(tbuffer) + 10 + strlen(orphans) + 1) &gt; BOZO_BSSIZE) {
! 		printf("bos: command line too big\n");
! 		return (E2BIG);
! 	    }
! 	    strcat(tbuffer, " -orphans ");
! 	    strcat(tbuffer, orphans);
  	}
  
! 	if (mrafsParm-&gt;Optdebug)
! 	    strcat(tbuffer, " -debug");
! 	if (mrafsParm-&gt;Optnowrite)
! 	    strcat(tbuffer, " -nowrite");
! 	if (mrafsParm-&gt;Optforce)
! 	    strcat(tbuffer, " -force");
! 	if (mrafsParm-&gt;Optoktozap)
! 	    strcat(tbuffer, " -oktozap");
! 	if (mrafsParm-&gt;Optrootfiles)
! 	    strcat(tbuffer, " -rootfiles");
! 	if (mrafsParm-&gt;Optsalvagedirs)
! 	    strcat(tbuffer, " -salvagedirs");
! 	if (mrafsParm-&gt;Optblockreads)
! 	    strcat(tbuffer, " -blockreads");
! 	if (mrafsParm-&gt;OptListResidencies)
! 	    strcat(tbuffer, " -ListResidencies");
! 	if (mrafsParm-&gt;OptSalvageRemote)
! 	    strcat(tbuffer, " -SalvageRemote");
! 	if (mrafsParm-&gt;OptSalvageArchival)
! 	    strcat(tbuffer, " -SalvageArchival");
! 	if (mrafsParm-&gt;OptIgnoreCheck)
! 	    strcat(tbuffer, " -IgnoreCheck");
! 	if (mrafsParm-&gt;OptForceOnLine)
! 	    strcat(tbuffer, " -ForceOnLine");
! 	if (mrafsParm-&gt;OptUseRootDirACL)
! 	    strcat(tbuffer, " -UseRootDirACL");
! 	if (mrafsParm-&gt;OptTraceBadLinkCounts)
! 	    strcat(tbuffer, " -TraceBadLinkCounts");
! 	if (mrafsParm-&gt;OptDontAskFS)
! 	    strcat(tbuffer, " -DontAskFS");
! 	if (mrafsParm-&gt;OptLogLevel) {
! 	    sprintf(pbuffer, " -LogLevel %ld", mrafsParm-&gt;OptLogLevel);
! 	    strcat(tbuffer, pbuffer);
! 	}
! 	if (mrafsParm-&gt;OptRxDebug)
! 	    strcat(tbuffer, " -rxdebug");
! 	if (mrafsParm-&gt;OptResidencies) {
! 	    sprintf(pbuffer, " -Residencies %lu", mrafsParm-&gt;OptResidencies);
! 	    strcat(tbuffer, pbuffer);
! 	}
      }
  
      parms[0] = tbuffer;
***************
*** 1481,1502 ****
      char tname[BOZO_BSSIZE];
      afs_int32 newID;
      extern struct ubik_client *cstruct;
!     afs_int32 curGoal, showlog = 0, mrafs = 0;
      char *parallel;
      char *tmpDir;
      char *orphans;
      char *tp;
  
      memset(&amp;mrafsParm, 0, sizeof(mrafsParm));
  
      /* parm 0 is machine name, 1 is partition, 2 is volume, 3 is -all flag */
      tconn = GetConn(as, 0);
  
-     /* Find out whether fileserver is running MR-AFS (has a scanner instance) */
-     /* XXX this should really be done some other way, potentially by RPC */
      tp = &amp;tname[0];
!     if (code = BOZO_GetInstanceParm(tconn, "fs", 3, &amp;tp) == 0)
! 	mrafs = 1;
  
      /* we can do a volume, a partition or the whole thing, but not mixtures
       * thereof */
--- 1508,1543 ----
      char tname[BOZO_BSSIZE];
      afs_int32 newID;
      extern struct ubik_client *cstruct;
!     afs_int32 curGoal, showlog = 0, dafs = 0, mrafs = 0;
      char *parallel;
      char *tmpDir;
      char *orphans;
      char *tp;
+     char * serviceName;
+     struct MRAFSSalvageParms mrafsParm;
  
      memset(&amp;mrafsParm, 0, sizeof(mrafsParm));
  
      /* parm 0 is machine name, 1 is partition, 2 is volume, 3 is -all flag */
      tconn = GetConn(as, 0);
  
      tp = &amp;tname[0];
! 
!     /* find out whether fileserver is running demand attach fs */
!     if (code = BOZO_GetInstanceParm(tconn, "dafs", 0, &amp;tp) == 0) {
! 	dafs = 1;
! 	serviceName = "dafs";
! 	/* Find out whether fileserver is running MR-AFS (has a scanner instance) */
! 	/* XXX this should really be done some other way, potentially by RPC */
! 	if (code = BOZO_GetInstanceParm(tconn, serviceName, 4, &amp;tp) == 0)
! 	    mrafs = 1;
!     } else {
! 	serviceName = "fs";
! 	/* Find out whether fileserver is running MR-AFS (has a scanner instance) */
! 	/* XXX this should really be done some other way, potentially by RPC */
! 	if (code = BOZO_GetInstanceParm(tconn, serviceName, 3, &amp;tp) == 0)
! 	    mrafs = 1;
!     }
  
      /* we can do a volume, a partition or the whole thing, but not mixtures
       * thereof */
***************
*** 1542,1547 ****
--- 1583,1596 ----
  	orphans = as-&gt;parms[8].items-&gt;data;
      }
  
+     if (dafs) {
+ 	if (!as-&gt;parms[9].items) { /* -forceDAFS flag */
+ 	    printf("This is a demand attach fileserver.  Are you sure you want to proceed with a manual salvage?\n");
+ 	    printf("must specify -forceDAFS flag in order to proceed.\n");
+ 	    return EINVAL;
+ 	}
+     }
+ 
      if (mrafs) {
  	if (as-&gt;parms[MRAFS_OFFSET].items)
  	    mrafsParm.Optdebug = 1;
***************
*** 1597,1603 ****
      } else {
  	int stop = 0;
  
! 	for (i = 9; i &lt; ADDPARMOFFSET; i++) {
  	    if (as-&gt;parms[i].items) {
  		printf(" %s only possible for MR-AFS fileserver.\n",
  		       as-&gt;parms[i].name);
--- 1646,1652 ----
      } else {
  	int stop = 0;
  
! 	for (i = MRAFS_OFFSET; i &lt; ADDPARMOFFSET; i++) {
  	    if (as-&gt;parms[i].items) {
  		printf(" %s only possible for MR-AFS fileserver.\n",
  		       as-&gt;parms[i].name);
***************
*** 1610,1621 ****
  
      if (as-&gt;parms[4].items) {
  	/* salvage whole enchilada */
! 	curGoal = GetServerGoal(tconn, "fs");
  	if (curGoal == BSTAT_NORMAL) {
! 	    printf("bos: shutting down fs.\n");
! 	    code = BOZO_SetTStatus(tconn, "fs", BSTAT_SHUTDOWN);
  	    if (code) {
! 		printf("bos: failed to stop 'fs' (%s)\n", em(code));
  		return code;
  	    }
  	    code = BOZO_WaitAll(tconn);	/* wait for shutdown to complete */
--- 1659,1670 ----
  
      if (as-&gt;parms[4].items) {
  	/* salvage whole enchilada */
! 	curGoal = GetServerGoal(tconn, serviceName);
  	if (curGoal == BSTAT_NORMAL) {
! 	    printf("bos: shutting down '%s'.\n", serviceName);
! 	    code = BOZO_SetTStatus(tconn, serviceName, BSTAT_SHUTDOWN);
  	    if (code) {
! 		printf("bos: failed to stop '%s' (%s)\n", serviceName, em(code));
  		return code;
  	    }
  	    code = BOZO_WaitAll(tconn);	/* wait for shutdown to complete */
***************
*** 1626,1637 ****
  	/* now do the salvage operation */
  	printf("Starting salvage.\n");
  	rc = DoSalvage(tconn, NULL, NULL, outName, showlog, parallel, tmpDir,
! 		       orphans);
  	if (curGoal == BSTAT_NORMAL) {
! 	    printf("bos: restarting fs.\n");
! 	    code = BOZO_SetTStatus(tconn, "fs", BSTAT_NORMAL);
  	    if (code) {
! 		printf("bos: failed to restart 'fs' (%s)\n", em(code));
  		return code;
  	    }
  	}
--- 1675,1686 ----
  	/* now do the salvage operation */
  	printf("Starting salvage.\n");
  	rc = DoSalvage(tconn, NULL, NULL, outName, showlog, parallel, tmpDir,
! 		       orphans, dafs, &amp;mrafsParm);
  	if (curGoal == BSTAT_NORMAL) {
! 	    printf("bos: restarting %s.\n", serviceName);
! 	    code = BOZO_SetTStatus(tconn, serviceName, BSTAT_NORMAL);
  	    if (code) {
! 		printf("bos: failed to restart '%s' (%s)\n", serviceName, em(code));
  		return code;
  	    }
  	}
***************
*** 1651,1663 ****
  		   as-&gt;parms[1].items-&gt;data);
  	    return -1;
  	}
! 	curGoal = GetServerGoal(tconn, "fs");
  	/* salvage a whole partition (specified by parms[1]) */
  	if (curGoal == BSTAT_NORMAL) {
! 	    printf("bos: shutting down fs.\n");
! 	    code = BOZO_SetTStatus(tconn, "fs", BSTAT_SHUTDOWN);
  	    if (code) {
! 		printf("bos: can't stop 'fs' (%s)\n", em(code));
  		return code;
  	    }
  	    code = BOZO_WaitAll(tconn);	/* wait for shutdown to complete */
--- 1700,1712 ----
  		   as-&gt;parms[1].items-&gt;data);
  	    return -1;
  	}
! 	curGoal = GetServerGoal(tconn, serviceName);
  	/* salvage a whole partition (specified by parms[1]) */
  	if (curGoal == BSTAT_NORMAL) {
! 	    printf("bos: shutting down '%s'.\n", serviceName);
! 	    code = BOZO_SetTStatus(tconn, serviceName, BSTAT_SHUTDOWN);
  	    if (code) {
! 		printf("bos: can't stop '%s' (%s)\n", serviceName, em(code));
  		return code;
  	    }
  	    code = BOZO_WaitAll(tconn);	/* wait for shutdown to complete */
***************
*** 1668,1679 ****
  	/* now do the salvage operation */
  	printf("Starting salvage.\n");
  	rc = DoSalvage(tconn, as-&gt;parms[1].items-&gt;data, NULL, outName,
! 		       showlog, parallel, tmpDir, orphans);
  	if (curGoal == BSTAT_NORMAL) {
! 	    printf("bos: restarting fs.\n");
! 	    code = BOZO_SetTStatus(tconn, "fs", BSTAT_NORMAL);
  	    if (code) {
! 		printf("bos: failed to restart 'fs' (%s)\n", em(code));
  		return code;
  	    }
  	}
--- 1717,1728 ----
  	/* now do the salvage operation */
  	printf("Starting salvage.\n");
  	rc = DoSalvage(tconn, as-&gt;parms[1].items-&gt;data, NULL, outName,
! 		       showlog, parallel, tmpDir, orphans, dafs, &amp;mrafsParm);
  	if (curGoal == BSTAT_NORMAL) {
! 	    printf("bos: restarting '%s'.\n", serviceName);
! 	    code = BOZO_SetTStatus(tconn, serviceName, BSTAT_NORMAL);
  	    if (code) {
! 		printf("bos: failed to restart '%s' (%s)\n", serviceName, em(code));
  		return code;
  	    }
  	}
***************
*** 1723,1729 ****
  	}
  	printf("Starting salvage.\n");
  	rc = DoSalvage(tconn, as-&gt;parms[1].items-&gt;data, tname, outName,
! 		       showlog, parallel, tmpDir, orphans);
  	if (rc)
  	    return rc;
      }
--- 1772,1778 ----
  	}
  	printf("Starting salvage.\n");
  	rc = DoSalvage(tconn, as-&gt;parms[1].items-&gt;data, tname, outName,
! 		       showlog, parallel, tmpDir, orphans, dafs, &amp;mrafsParm);
  	if (rc)
  	    return rc;
      }
***************
*** 2153,2158 ****
--- 2202,2209 ----
  		"directory to place tmp files");
      cmd_AddParm(ts, "-orphans", CMD_SINGLE, CMD_OPTIONAL,
  		"ignore | remove | attach");
+     cmd_AddParm(ts, "-forceDAFS", CMD_FLAG, CMD_OPTIONAL,
+ 		"(DAFS) force salvage of demand attach fileserver");
      cmd_AddParm(ts, "-debug", CMD_FLAG, CMD_OPTIONAL,
  		"(MR-AFS) Run in Debugging mode");
      cmd_AddParm(ts, "-nowrite", CMD_FLAG, CMD_OPTIONAL,
Index: openafs/src/bozo/bosserver.c
diff -c openafs/src/bozo/bosserver.c:1.30 openafs/src/bozo/bosserver.c:1.32
*** openafs/src/bozo/bosserver.c:1.30	Wed Feb  1 11:09:15 2006
--- openafs/src/bozo/bosserver.c	Fri Mar 17 14:54:36 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/bozo/bosserver.c,v 1.30 2006/02/01 16:09:15 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/bozo/bosserver.c,v 1.32 2006/03/17 19:54:36 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
***************
*** 51,57 ****
  #define BOZO_LWP_STACKSIZE	16000
  extern int BOZO_ExecuteRequest();
  extern int RXSTATS_ExecuteRequest();
! extern struct bnode_ops fsbnode_ops, ezbnode_ops, cronbnode_ops;
  
  void bozo_Log();
  
--- 51,57 ----
  #define BOZO_LWP_STACKSIZE	16000
  extern int BOZO_ExecuteRequest();
  extern int RXSTATS_ExecuteRequest();
! extern struct bnode_ops fsbnode_ops, dafsbnode_ops, ezbnode_ops, cronbnode_ops;
  
  void bozo_Log();
  
***************
*** 718,723 ****
--- 718,724 ----
      struct ktc_encryptionKey tkey;
      int i;
      char namebuf[AFSDIR_PATH_MAX];
+     int rxMaxMTU = -1;
  #ifndef AFS_NT40_ENV
      int nofork = 0;
      struct stat sb;
***************
*** 812,817 ****
--- 813,832 ----
  	    bozo_isrestricted = 1;
  	}
  #endif
+ 	else if (!strcmp(argv[i], "-rxmaxmtu")) {
+ 	    if ((i + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for -rxmaxmtu\n"); 
+ 		exit(1); 
+ 	    }
+ 	    rxMaxMTU = atoi(argv[++i]);
+ 	    if ((rxMaxMTU &lt; RX_MIN_PACKET_SIZE) || 
+ 		(rxMaxMTU &gt; RX_MAX_PACKET_DATA_SIZE)) {
+ 		printf("rxMaxMTU %d% invalid; must be between %d-%d\n",
+ 			rxMaxMTU, RX_MIN_PACKET_SIZE, 
+ 			RX_MAX_PACKET_DATA_SIZE);
+ 		exit(1);
+ 	    }
+ 	}
  	else if (strcmp(argv[code], "-auditlog") == 0) {
  	    int tempfd, flags;
  	    FILE *auditout;
***************
*** 849,860 ****
--- 864,877 ----
  #ifndef AFS_NT40_ENV
  	    printf("Usage: bosserver [-noauth] [-log] "
  		   "[-auditlog &lt;log path&gt;] "
+ 		   "[-rxmaxmtu &lt;bytes&gt;] "
  		   "[-syslog[=FACILITY]] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-nofork] " "[-help]\n");
  #else
  	    printf("Usage: bosserver [-noauth] [-log] "
  		   "[-auditlog &lt;log path&gt;] "
+ 		   "[-rxmaxmtu &lt;bytes&gt;] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-help]\n");
  #endif
***************
*** 878,883 ****
--- 895,901 ----
      }
  
      bnode_Register("fs", &amp;fsbnode_ops, 3);
+     bnode_Register("dafs", &amp;dafsbnode_ops, 4);
      bnode_Register("simple", &amp;ezbnode_ops, 1);
      bnode_Register("cron", &amp;cronbnode_ops, 2);
  
***************
*** 1006,1011 ****
--- 1024,1033 ----
      /* Disable jumbograms */
      rx_SetNoJumbo();
  
+     if (rxMaxMTU != -1) {
+ 	rx_SetMaxMTU(rxMaxMTU);
+     }
+ 
      tservice = rx_NewService( /* port */ 0, /* service id */ 1,
  			     /*service name */ "bozo",
  			     /* security classes */
Index: openafs/src/bozo/fsbnodeops.c
diff -c openafs/src/bozo/fsbnodeops.c:1.13 openafs/src/bozo/fsbnodeops.c:1.15
*** openafs/src/bozo/fsbnodeops.c:1.13	Sun Dec  7 17:49:18 2003
--- openafs/src/bozo/fsbnodeops.c	Mon Mar 20 12:29:52 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/bozo/fsbnodeops.c,v 1.13 2003/12/07 22:49:18 jaltman Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;lwp.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/bozo/fsbnodeops.c,v 1.15 2006/03/20 17:29:52 jaltman Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;lwp.h&gt;
***************
*** 41,53 ****
  #include &lt;afs/afsutil.h&gt;
  #include "bnode.h"
  
- static int fs_timeout(), fs_getstat(), fs_setstat(), fs_delete();
- static int fs_procexit(), fs_getstring(), fs_getparm(), fs_restartp();
- static int fs_hascore();
- struct bnode *fs_create();
- 
- static SetNeedsClock();
- static NudgeProcs();
  
  static int emergency = 0;
  
--- 41,46 ----
***************
*** 76,124 ****
      The needsSalvage flag is cleared when the salvager exits.
  */
  
- struct bnode_ops fsbnode_ops = {
-     fs_create,
-     fs_timeout,
-     fs_getstat,
-     fs_setstat,
-     fs_delete,
-     fs_procexit,
-     fs_getstring,
-     fs_getparm,
-     fs_restartp,
-     fs_hascore,
- };
- 
  struct fsbnode {
      struct bnode b;
      afs_int32 timeSDStarted;	/* time shutdown operation started */
      char *filecmd;		/* command to start primary file server */
      char *volcmd;		/* command to start secondary vol server */
      char *salcmd;		/* command to start salvager */
      char *scancmd;		/* command to start scanner (MR-AFS) */
      struct bnode_proc *fileProc;	/* process for file server */
      struct bnode_proc *volProc;	/* process for vol server */
      struct bnode_proc *salProc;	/* process for salvager */
      struct bnode_proc *scanProc;	/* process for scanner (MR-AFS) */
      afs_int32 lastFileStart;	/* last start for file */
      afs_int32 lastVolStart;	/* last start for vol */
      afs_int32 lastScanStart;	/* last start for scanner (MR-AFS) */
      char fileRunning;		/* file process is running */
      char volRunning;		/* volser is running */
      char salRunning;		/* salvager is running */
      char scanRunning;		/* scanner is running (MR_AFS) */
      char fileSDW;		/* file shutdown wait */
      char volSDW;		/* vol shutdown wait */
      char salSDW;		/* waiting for the salvager to shutdown */
      char scanSDW;		/* scanner shutdown wait (MR_AFS) */
      char fileKillSent;		/* kill signal has been sent */
      char volKillSent;
      char salKillSent;
      char scanKillSent;		/* kill signal has been sent (MR_AFS) */
      char needsSalvage;		/* salvage before running */
      char needsClock;		/* do we need clock ticks */
  };
  
  /* Function to tell whether this bnode has a core file or not.  You might
   * think that this could be in bnode.c, and decide what core files to check
   * for based on the bnode's coreName property, but that doesn't work because
--- 69,173 ----
      The needsSalvage flag is cleared when the salvager exits.
  */
  
  struct fsbnode {
      struct bnode b;
      afs_int32 timeSDStarted;	/* time shutdown operation started */
      char *filecmd;		/* command to start primary file server */
      char *volcmd;		/* command to start secondary vol server */
+     char *salsrvcmd;            /* command to start salvageserver (demand attach fs) */
      char *salcmd;		/* command to start salvager */
      char *scancmd;		/* command to start scanner (MR-AFS) */
      struct bnode_proc *fileProc;	/* process for file server */
      struct bnode_proc *volProc;	/* process for vol server */
+     struct bnode_proc *salsrvProc;	/* process for salvageserver (demand attach fs) */
      struct bnode_proc *salProc;	/* process for salvager */
      struct bnode_proc *scanProc;	/* process for scanner (MR-AFS) */
      afs_int32 lastFileStart;	/* last start for file */
      afs_int32 lastVolStart;	/* last start for vol */
+     afs_int32 lastSalsrvStart;	/* last start for salvageserver (demand attach fs) */
      afs_int32 lastScanStart;	/* last start for scanner (MR-AFS) */
      char fileRunning;		/* file process is running */
      char volRunning;		/* volser is running */
+     char salsrvRunning;		/* salvageserver is running (demand attach fs) */
      char salRunning;		/* salvager is running */
      char scanRunning;		/* scanner is running (MR_AFS) */
      char fileSDW;		/* file shutdown wait */
      char volSDW;		/* vol shutdown wait */
+     char salsrvSDW;		/* salvageserver shutdown wait (demand attach fs) */
      char salSDW;		/* waiting for the salvager to shutdown */
      char scanSDW;		/* scanner shutdown wait (MR_AFS) */
      char fileKillSent;		/* kill signal has been sent */
      char volKillSent;
+     char salsrvKillSent;        /* kill signal has been sent (demand attach fs) */
      char salKillSent;
      char scanKillSent;		/* kill signal has been sent (MR_AFS) */
      char needsSalvage;		/* salvage before running */
      char needsClock;		/* do we need clock ticks */
  };
  
+ 
+ 
+ struct bnode * fs_create(char *ainstance, char *afilecmd, char *avolcmd, 
+ 			 char *asalcmd, char *ascancmd);
+ struct bnode * dafs_create(char *ainstance, char *afilecmd, char *avolcmd, 
+ 			   char * asalsrvcmd, char *asalcmd, char *ascancmd);
+ 
+ static int fs_hascore(register struct ezbnode *abnode);
+ static int fs_restartp(register struct fsbnode *abnode);
+ static int SetSalFlag(register struct fsbnode *abnode, register int aflag);
+ static int RestoreSalFlag(register struct fsbnode *abnode);
+ static int fs_delete(struct fsbnode *abnode);
+ static int fs_timeout(struct fsbnode *abnode);
+ static int fs_getstat(struct fsbnode *abnode, afs_int32 * astatus);
+ static int fs_setstat(register struct fsbnode *abnode, afs_int32 astatus);
+ static int fs_procexit(struct fsbnode *abnode, struct bnode_proc *aproc);
+ static int fs_getstring(struct fsbnode *abnode, char *abuffer, afs_int32 alen);
+ 
+ 
+ static int fs_getparm(struct fsbnode *abnode, afs_int32 aindex, 
+ 		      char *abuffer, afs_int32 alen);
+ static int dafs_getparm(struct fsbnode *abnode, afs_int32 aindex, 
+ 			char *abuffer, afs_int32 alen);
+ 
+ #ifdef AFS_NT40_ENV
+ static void AppendExecutableExtension(char *cmd);
+ #else
+ #define AppendExecutableExtension(x)
+ #endif
+ 
+ static void SetNeedsClock(register struct fsbnode *ab);
+ static int NudgeProcs(register struct fsbnode *abnode);
+ 
+ 
+ 
+ struct bnode_ops fsbnode_ops = {
+     fs_create,
+     fs_timeout,
+     fs_getstat,
+     fs_setstat,
+     fs_delete,
+     fs_procexit,
+     fs_getstring,
+     fs_getparm,
+     fs_restartp,
+     fs_hascore,
+ };
+ 
+ /* demand attach fs bnode ops */
+ struct bnode_ops dafsbnode_ops = {
+     dafs_create,
+     fs_timeout,
+     fs_getstat,
+     fs_setstat,
+     fs_delete,
+     fs_procexit,
+     fs_getstring,
+     dafs_getparm,
+     fs_restartp,
+     fs_hascore,
+ };
+ 
+ 
  /* Function to tell whether this bnode has a core file or not.  You might
   * think that this could be in bnode.c, and decide what core files to check
   * for based on the bnode's coreName property, but that doesn't work because
***************
*** 140,145 ****
--- 189,199 ----
      if (access(tbuffer, 0) == 0)
  	return 1;
  
+     /* see if salvageserver left a core file */
+     bnode_CoreName(abnode, "salsrv", tbuffer);
+     if (access(tbuffer, 0) == 0)
+ 	return 1;
+ 
      /* see if salvager left a core file */
      bnode_CoreName(abnode, "salv", tbuffer);
      if (access(tbuffer, 0) == 0)
***************
*** 198,203 ****
--- 252,276 ----
      if (code)
  	return code;
  
+     if (abnode-&gt;salsrvcmd) {    /* only in demand attach fs */
+ 	/* now do same for salsrvcmd (demand attach fs) */
+ 	code = bnode_ParseLine(abnode-&gt;salsrvcmd, &amp;tt);
+ 	if (code)
+ 	    return 0;
+ 	if (!tt)
+ 	    return 0;
+ 	code = stat(tt-&gt;key, &amp;tstat);
+ 	if (code) {
+ 	    bnode_FreeTokens(tt);
+ 	    return 0;
+ 	}
+ 	if (tstat.st_ctime &gt; abnode-&gt;lastScanStart)
+ 	    code = 1;
+ 	else
+ 	    code = 0;
+ 	bnode_FreeTokens(tt);
+     }
+ 
      if (abnode-&gt;scancmd) {	/* Only in MR-AFS */
  	/* now do same for scancmd (MR-AFS) */
  	code = bnode_ParseLine(abnode-&gt;scancmd, &amp;tt);
***************
*** 228,241 ****
      char tbuffer[AFSDIR_PATH_MAX];
      int fd;
  
!     abnode-&gt;needsSalvage = aflag;
!     strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
! 	       SALFILE, abnode-&gt;b.name, NULL);
!     if (aflag) {
! 	fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
! 	close(fd);
!     } else {
! 	unlink(tbuffer);
      }
      return 0;
  }
--- 301,317 ----
      char tbuffer[AFSDIR_PATH_MAX];
      int fd;
  
!     /* don't use the salvage flag for demand attach fs */
!     if (abnode-&gt;salsrvcmd == NULL) {
! 	abnode-&gt;needsSalvage = aflag;
! 	strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
! 		   SALFILE, abnode-&gt;b.name, NULL);
! 	if (aflag) {
! 	    fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
! 	    close(fd);
! 	} else {
! 	    unlink(tbuffer);
! 	}
      }
      return 0;
  }
***************
*** 246,258 ****
  {
      char tbuffer[AFSDIR_PATH_MAX];
  
!     strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
! 	       SALFILE, abnode-&gt;b.name, NULL);
!     if (access(tbuffer, 0) == 0) {
! 	/* file exists, so need to salvage */
! 	abnode-&gt;needsSalvage = 1;
!     } else {
  	abnode-&gt;needsSalvage = 0;
      }
      return 0;
  }
--- 322,339 ----
  {
      char tbuffer[AFSDIR_PATH_MAX];
  
!     /* never set needs salvage flag for demand attach fs */
!     if (abnode-&gt;salsrvcmd != NULL) {
  	abnode-&gt;needsSalvage = 0;
+     } else {
+ 	strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
+ 		   SALFILE, abnode-&gt;b.name, NULL);
+ 	if (access(tbuffer, 0) == 0) {
+ 	    /* file exists, so need to salvage */
+ 	    abnode-&gt;needsSalvage = 1;
+ 	} else {
+ 	    abnode-&gt;needsSalvage = 0;
+ 	}
      }
      return 0;
  }
***************
*** 272,277 ****
--- 353,360 ----
      free(abnode-&gt;filecmd);
      free(abnode-&gt;volcmd);
      free(abnode-&gt;salcmd);
+     if (abnode-&gt;salsrvcmd)
+ 	free(abnode-&gt;salsrvcmd);
      if (abnode-&gt;scancmd)
  	free(abnode-&gt;scancmd);
      free(abnode);
***************
*** 304,398 ****
      char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
      int bailout = 0;
  
!     fileCmdpath = volCmdpath = salCmdpath = NULL;
  
      /* construct local paths from canonical (wire-format) paths */
      if (ConstructLocalBinPath(afilecmd, &amp;fileCmdpath)) {
  	bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
  	bailout = 1;
      }
      if (ConstructLocalBinPath(avolcmd, &amp;volCmdpath)) {
  	bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
  	bailout = 1;
      }
      if (ConstructLocalBinPath(asalcmd, &amp;salCmdpath)) {
  	bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
  	bailout = 1;
      }
  
      if (ascancmd &amp;&amp; strlen(ascancmd)) {
  	if (ConstructLocalBinPath(ascancmd, &amp;scanCmdpath)) {
  	    bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
  	    bailout = 1;
  	}
      }
  
      if (!bailout) {
  	sscanf(fileCmdpath, "%s", cmdname);
- #ifdef AFS_NT40_ENV
  	AppendExecutableExtension(cmdname);
- #endif
  	if (stat(cmdname, &amp;tstat)) {
  	    bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
  	    bailout = 1;
  	}
  
  	sscanf(volCmdpath, "%s", cmdname);
- #ifdef AFS_NT40_ENV
  	AppendExecutableExtension(cmdname);
- #endif
  	if (stat(cmdname, &amp;tstat)) {
  	    bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
  	    bailout = 1;
  	}
  
  	sscanf(salCmdpath, "%s", cmdname);
- #ifdef AFS_NT40_ENV
  	AppendExecutableExtension(cmdname);
- #endif
  	if (stat(cmdname, &amp;tstat)) {
  	    bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
  	    bailout = 1;
  	}
  
  	if (ascancmd &amp;&amp; strlen(ascancmd)) {
  	    sscanf(scanCmdpath, "%s", cmdname);
- #ifdef AFS_NT40_ENV
  	    AppendExecutableExtension(cmdname);
- #endif
  	    if (stat(cmdname, &amp;tstat)) {
  		bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
  		bailout = 1;
  	    }
  	}
      }
  
      if (bailout) {
! 	free(fileCmdpath);
! 	free(volCmdpath);
! 	free(salCmdpath);
  	return NULL;
      }
  
      te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
      memset(te, 0, sizeof(struct fsbnode));
      te-&gt;filecmd = fileCmdpath;
      te-&gt;volcmd = volCmdpath;
      te-&gt;salcmd = salCmdpath;
      if (ascancmd &amp;&amp; strlen(ascancmd))
  	te-&gt;scancmd = scanCmdpath;
      else
  	te-&gt;scancmd = NULL;
!     if (bnode_InitBnode(te, &amp;fsbnode_ops, ainstance) != 0) {
! 	free(te);
! 	free(fileCmdpath);
! 	free(volCmdpath);
! 	free(salCmdpath);
! 	return NULL;
      }
      bnode_SetTimeout(te, POLLTIME);	/* ask for timeout activations every 10 seconds */
      RestoreSalFlag(te);		/* restore needsSalvage flag based on file's existence */
      SetNeedsClock(te);		/* compute needsClock field */
      return (struct bnode *)te;
  }
  
--- 387,621 ----
      char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
      int bailout = 0;
  
!     te = fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
  
      /* construct local paths from canonical (wire-format) paths */
      if (ConstructLocalBinPath(afilecmd, &amp;fileCmdpath)) {
  	bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
  	bailout = 1;
+ 	goto done;
      }
      if (ConstructLocalBinPath(avolcmd, &amp;volCmdpath)) {
  	bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
  	bailout = 1;
+ 	goto done;
      }
      if (ConstructLocalBinPath(asalcmd, &amp;salCmdpath)) {
  	bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
  	bailout = 1;
+ 	goto done;
      }
  
      if (ascancmd &amp;&amp; strlen(ascancmd)) {
  	if (ConstructLocalBinPath(ascancmd, &amp;scanCmdpath)) {
  	    bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
  	    bailout = 1;
+ 	    goto done;
  	}
      }
  
      if (!bailout) {
  	sscanf(fileCmdpath, "%s", cmdname);
  	AppendExecutableExtension(cmdname);
  	if (stat(cmdname, &amp;tstat)) {
  	    bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
  	    bailout = 1;
+ 	    goto done;
  	}
  
  	sscanf(volCmdpath, "%s", cmdname);
  	AppendExecutableExtension(cmdname);
  	if (stat(cmdname, &amp;tstat)) {
  	    bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
  	    bailout = 1;
+ 	    goto done;
  	}
  
  	sscanf(salCmdpath, "%s", cmdname);
  	AppendExecutableExtension(cmdname);
  	if (stat(cmdname, &amp;tstat)) {
  	    bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
  	    bailout = 1;
+ 	    goto done;
  	}
  
  	if (ascancmd &amp;&amp; strlen(ascancmd)) {
  	    sscanf(scanCmdpath, "%s", cmdname);
  	    AppendExecutableExtension(cmdname);
  	    if (stat(cmdname, &amp;tstat)) {
  		bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
  		bailout = 1;
+ 		goto done;
  	    }
  	}
      }
  
+     te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
+     if (te == NULL) {
+ 	bailout = 1;
+ 	goto done;
+     }
+     memset(te, 0, sizeof(struct fsbnode));
+     te-&gt;filecmd = fileCmdpath;
+     te-&gt;volcmd = volCmdpath;
+     te-&gt;salsrvcmd = NULL;
+     te-&gt;salcmd = salCmdpath;
+     if (ascancmd &amp;&amp; strlen(ascancmd))
+ 	te-&gt;scancmd = scanCmdpath;
+     else
+ 	te-&gt;scancmd = NULL;
+     if (bnode_InitBnode(te, &amp;fsbnode_ops, ainstance) != 0) {
+ 	bailout = 1;
+ 	goto done;
+     }
+     bnode_SetTimeout(te, POLLTIME);	/* ask for timeout activations every 10 seconds */
+     RestoreSalFlag(te);		/* restore needsSalvage flag based on file's existence */
+     SetNeedsClock(te);		/* compute needsClock field */
+ 
+  done:
      if (bailout) {
! 	if (te)
! 	    free(te);
! 	if (fileCmdpath)
! 	    free(fileCmdpath);
! 	if (volCmdpath)
! 	    free(volCmdpath);
! 	if (salCmdpath)
! 	    free(salCmdpath);
! 	if (scanCmdpath)
! 	    free(scanCmdpath);
  	return NULL;
      }
  
+     return (struct bnode *)te;
+ }
+ 
+ /* create a demand attach fs bnode */
+ struct bnode *
+ dafs_create(char *ainstance, char *afilecmd, char *avolcmd, 
+ 	    char * asalsrvcmd, char *asalcmd, char *ascancmd)
+ {
+     struct stat tstat;
+     register struct fsbnode *te;
+     char cmdname[AFSDIR_PATH_MAX];
+     char *fileCmdpath, *volCmdpath, *salsrvCmdpath, *salCmdpath, *scanCmdpath;
+     int bailout = 0;
+ 
+     te = fileCmdpath = volCmdpath = salsrvCmdpath = salCmdpath = scanCmdpath = NULL;
+ 
+     /* construct local paths from canonical (wire-format) paths */
+     if (ConstructLocalBinPath(afilecmd, &amp;fileCmdpath)) {
+ 	bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
+ 	bailout = 1;
+ 	goto done;
+     }
+     if (ConstructLocalBinPath(avolcmd, &amp;volCmdpath)) {
+ 	bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
+ 	bailout = 1;
+ 	goto done;
+     }
+     if (ConstructLocalBinPath(asalsrvcmd, &amp;salsrvCmdpath)) {
+ 	bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd);
+ 	bailout = 1;
+ 	goto done;
+     }
+     if (ConstructLocalBinPath(asalcmd, &amp;salCmdpath)) {
+ 	bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
+ 	bailout = 1;
+ 	goto done;
+     }
+ 
+     if (ascancmd &amp;&amp; strlen(ascancmd)) {
+ 	if (ConstructLocalBinPath(ascancmd, &amp;scanCmdpath)) {
+ 	    bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
+ 	    bailout = 1;
+ 	    goto done;
+ 	}
+     }
+ 
+     if (!bailout) {
+ 	sscanf(fileCmdpath, "%s", cmdname);
+ 	AppendExecutableExtension(cmdname);
+ 	if (stat(cmdname, &amp;tstat)) {
+ 	    bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
+ 	    bailout = 1;
+ 	    goto done;
+ 	}
+ 
+ 	sscanf(volCmdpath, "%s", cmdname);
+ 	AppendExecutableExtension(cmdname);
+ 	if (stat(cmdname, &amp;tstat)) {
+ 	    bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
+ 	    bailout = 1;
+ 	    goto done;
+ 	}
+ 
+ 	sscanf(salsrvCmdpath, "%s", cmdname);
+ 	AppendExecutableExtension(cmdname);
+ 	if (stat(cmdname, &amp;tstat)) {
+ 	    bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname);
+ 	    bailout = 1;
+ 	    goto done;
+ 	}
+ 
+ 	sscanf(salCmdpath, "%s", cmdname);
+ 	AppendExecutableExtension(cmdname);
+ 	if (stat(cmdname, &amp;tstat)) {
+ 	    bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
+ 	    bailout = 1;
+ 	    goto done;
+ 	}
+ 
+ 	if (ascancmd &amp;&amp; strlen(ascancmd)) {
+ 	    sscanf(scanCmdpath, "%s", cmdname);
+ 	    AppendExecutableExtension(cmdname);
+ 	    if (stat(cmdname, &amp;tstat)) {
+ 		bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
+ 		bailout = 1;
+ 		goto done;
+ 	    }
+ 	}
+     }
+ 
      te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
+     if (te == NULL) {
+ 	bailout = 1;
+ 	goto done;
+     }
      memset(te, 0, sizeof(struct fsbnode));
      te-&gt;filecmd = fileCmdpath;
      te-&gt;volcmd = volCmdpath;
+     te-&gt;salsrvcmd = salsrvCmdpath;
      te-&gt;salcmd = salCmdpath;
      if (ascancmd &amp;&amp; strlen(ascancmd))
  	te-&gt;scancmd = scanCmdpath;
      else
  	te-&gt;scancmd = NULL;
!     if (bnode_InitBnode(te, &amp;dafsbnode_ops, ainstance) != 0) {
! 	bailout = 1;
! 	goto done;
      }
      bnode_SetTimeout(te, POLLTIME);	/* ask for timeout activations every 10 seconds */
      RestoreSalFlag(te);		/* restore needsSalvage flag based on file's existence */
      SetNeedsClock(te);		/* compute needsClock field */
+ 
+  done:
+     if (bailout) {
+ 	if (te)
+ 	    free(te);
+ 	if (fileCmdpath)
+ 	    free(fileCmdpath);
+ 	if (volCmdpath)
+ 	    free(volCmdpath);
+ 	if (salsrvCmdpath)
+ 	    free(salsrvCmdpath);
+ 	if (salCmdpath)
+ 	    free(salCmdpath);
+ 	if (scanCmdpath)
+ 	    free(scanCmdpath);
+ 	return NULL;
+     }
+ 
      return (struct bnode *)te;
  }
  
***************
*** 431,436 ****
--- 654,668 ----
  		 FSSDTIME);
  	}
      }
+     if (abnode-&gt;salsrvSDW) {
+ 	if (!abnode-&gt;salsrvKillSent &amp;&amp; now - abnode-&gt;timeSDStarted &gt; SDTIME) {
+ 	    bnode_StopProc(abnode-&gt;salsrvProc, SIGKILL);
+ 	    abnode-&gt;salsrvKillSent = 1;
+ 	    bozo_Log
+ 		("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
+ 		 SDTIME);
+ 	}
+     }
      if (abnode-&gt;scanSDW) {
  	if (!abnode-&gt;scanKillSent &amp;&amp; now - abnode-&gt;timeSDStarted &gt; SDTIME) {
  	    bnode_StopProc(abnode-&gt;scanProc, SIGKILL);
***************
*** 449,463 ****
  {
      register afs_int32 temp;
      if (abnode-&gt;volSDW || abnode-&gt;fileSDW || abnode-&gt;salSDW
! 	|| abnode-&gt;scanSDW)
  	temp = BSTAT_SHUTTINGDOWN;
      else if (abnode-&gt;salRunning)
  	temp = BSTAT_NORMAL;
      else if (abnode-&gt;volRunning &amp;&amp; abnode-&gt;fileRunning
! 	     &amp;&amp; (!abnode-&gt;scancmd || abnode-&gt;scanRunning))
  	temp = BSTAT_NORMAL;
      else if (!abnode-&gt;salRunning &amp;&amp; !abnode-&gt;volRunning
! 	     &amp;&amp; !abnode-&gt;fileRunning &amp;&amp; !abnode-&gt;scanRunning)
  	temp = BSTAT_SHUTDOWN;
      else
  	temp = BSTAT_STARTINGUP;
--- 681,697 ----
  {
      register afs_int32 temp;
      if (abnode-&gt;volSDW || abnode-&gt;fileSDW || abnode-&gt;salSDW
! 	|| abnode-&gt;scanSDW || abnode-&gt;salsrvSDW)
  	temp = BSTAT_SHUTTINGDOWN;
      else if (abnode-&gt;salRunning)
  	temp = BSTAT_NORMAL;
      else if (abnode-&gt;volRunning &amp;&amp; abnode-&gt;fileRunning
! 	     &amp;&amp; (!abnode-&gt;scancmd || abnode-&gt;scanRunning)
! 	     &amp;&amp; (!abnode-&gt;salsrvcmd || abnode-&gt;salsrvRunning))
  	temp = BSTAT_NORMAL;
      else if (!abnode-&gt;salRunning &amp;&amp; !abnode-&gt;volRunning
! 	     &amp;&amp; !abnode-&gt;fileRunning &amp;&amp; !abnode-&gt;scanRunning
! 	     &amp;&amp; !abnode-&gt;salsrvRunning)
  	temp = BSTAT_SHUTDOWN;
      else
  	temp = BSTAT_STARTINGUP;
***************
*** 508,513 ****
--- 742,752 ----
  	abnode-&gt;scanRunning = 0;
  	abnode-&gt;scanSDW = 0;
  	abnode-&gt;scanKillSent = 0;
+     } else if (aproc == abnode-&gt;salsrvProc) {
+ 	abnode-&gt;salsrvProc = 0;
+ 	abnode-&gt;salsrvRunning = 0;
+ 	abnode-&gt;salsrvSDW = 0;
+ 	abnode-&gt;salsrvKillSent = 0;
      }
  
      /* now restart anyone who needs to restart */
***************
*** 515,528 ****
  }
  
  /* make sure we're periodically checking the state if we need to */
! static int
  SetNeedsClock(register struct fsbnode *ab)
  {
      if (ab-&gt;b.goal == 1 &amp;&amp; ab-&gt;fileRunning &amp;&amp; ab-&gt;volRunning
! 	&amp;&amp; (!ab-&gt;scancmd || ab-&gt;scanRunning))
  	ab-&gt;needsClock = 0;	/* running normally */
      else if (ab-&gt;b.goal == 0 &amp;&amp; !ab-&gt;fileRunning &amp;&amp; !ab-&gt;volRunning
! 	     &amp;&amp; !ab-&gt;salRunning &amp;&amp; !ab-&gt;scanRunning)
  	ab-&gt;needsClock = 0;	/* halted normally */
      else
  	ab-&gt;needsClock = 1;	/* other */
--- 754,768 ----
  }
  
  /* make sure we're periodically checking the state if we need to */
! static void
  SetNeedsClock(register struct fsbnode *ab)
  {
      if (ab-&gt;b.goal == 1 &amp;&amp; ab-&gt;fileRunning &amp;&amp; ab-&gt;volRunning
! 	&amp;&amp; (!ab-&gt;scancmd || ab-&gt;scanRunning)
! 	&amp;&amp; (!ab-&gt;salsrvcmd || ab-&gt;salsrvRunning))
  	ab-&gt;needsClock = 0;	/* running normally */
      else if (ab-&gt;b.goal == 0 &amp;&amp; !ab-&gt;fileRunning &amp;&amp; !ab-&gt;volRunning
! 	     &amp;&amp; !ab-&gt;salRunning &amp;&amp; !ab-&gt;scanRunning &amp;&amp; !ab-&gt;salsrvRunning)
  	ab-&gt;needsClock = 0;	/* halted normally */
      else
  	ab-&gt;needsClock = 1;	/* other */
***************
*** 562,567 ****
--- 802,819 ----
  		    abnode-&gt;volRunning = 1;
  		}
  	    }
+ 	    if (abnode-&gt;salsrvcmd) {
+ 		if (!abnode-&gt;salsrvRunning) {
+ 		    abnode-&gt;lastSalsrvStart = FT_ApproxTime();
+ 		    code =
+ 			bnode_NewProc(abnode, abnode-&gt;salsrvcmd, "salsrv",
+ 				      &amp;tp);
+ 		    if (code == 0) {
+ 			abnode-&gt;salsrvProc = tp;
+ 			abnode-&gt;salsrvRunning = 1;
+ 		    }
+ 		}
+ 	    }
  	    if (abnode-&gt;scancmd) {
  		if (!abnode-&gt;scanRunning) {
  		    abnode-&gt;lastScanStart = FT_ApproxTime();
***************
*** 576,582 ****
  	    }
  	} else {		/* file is not running */
  	    /* see how to start */
! 	    if (!abnode-&gt;needsSalvage) {
  		/* no crash apparent, just start up normally */
  		if (!abnode-&gt;fileRunning) {
  		    abnode-&gt;lastFileStart = FT_ApproxTime();
--- 828,835 ----
  	    }
  	} else {		/* file is not running */
  	    /* see how to start */
! 	    /* for demand attach fs, needsSalvage flag is ignored */
! 	    if (!abnode-&gt;needsSalvage || abnode-&gt;salsrvcmd) {
  		/* no crash apparent, just start up normally */
  		if (!abnode-&gt;fileRunning) {
  		    abnode-&gt;lastFileStart = FT_ApproxTime();
***************
*** 596,601 ****
--- 849,864 ----
  			abnode-&gt;volRunning = 1;
  		    }
  		}
+ 		if (abnode-&gt;salsrvcmd &amp;&amp; !abnode-&gt;salsrvRunning) {
+ 		    abnode-&gt;lastSalsrvStart = FT_ApproxTime();
+ 		    code =
+ 			bnode_NewProc(abnode, abnode-&gt;salsrvcmd, "salsrv",
+ 				      &amp;tp);
+ 		    if (code == 0) {
+ 			abnode-&gt;salsrvProc = tp;
+ 			abnode-&gt;salsrvRunning = 1;
+ 		    }
+ 		}
  		if (abnode-&gt;scancmd &amp;&amp; !abnode-&gt;scanRunning) {
  		    abnode-&gt;lastScanStart = FT_ApproxTime();
  		    code =
***************
*** 656,661 ****
--- 919,929 ----
  	    abnode-&gt;volSDW = 1;
  	    abnode-&gt;timeSDStarted = now;
  	}
+ 	if (abnode-&gt;salsrvRunning &amp;&amp; !abnode-&gt;salsrvSDW) {
+ 	    bnode_StopProc(abnode-&gt;salsrvProc, SIGTERM);
+ 	    abnode-&gt;salsrvSDW = 1;
+ 	    abnode-&gt;timeSDStarted = now;
+ 	}
  	if (abnode-&gt;scanRunning &amp;&amp; !abnode-&gt;scanSDW) {
  	    bnode_StopProc(abnode-&gt;scanProc, SIGTERM);
  	    abnode-&gt;scanSDW = 1;
***************
*** 724,726 ****
--- 992,1013 ----
  	return BZDOM;
      return 0;
  }
+ 
+ static int
+ dafs_getparm(struct fsbnode *abnode, afs_int32 aindex, char *abuffer,
+ 	     afs_int32 alen)
+ {
+     if (aindex == 0)
+ 	strcpy(abuffer, abnode-&gt;filecmd);
+     else if (aindex == 1)
+ 	strcpy(abuffer, abnode-&gt;volcmd);
+     else if (aindex == 2)
+ 	strcpy(abuffer, abnode-&gt;salsrvcmd);
+     else if (aindex == 3)
+ 	strcpy(abuffer, abnode-&gt;salcmd);
+     else if (aindex == 4 &amp;&amp; abnode-&gt;scancmd)
+ 	strcpy(abuffer, abnode-&gt;scancmd);
+     else
+ 	return BZDOM;
+     return 0;
+ }
Index: openafs/src/bozo/test/Makefile.in
diff -c openafs/src/bozo/test/Makefile.in:1.6 openafs/src/bozo/test/Makefile.in:1.7
*** openafs/src/bozo/test/Makefile.in:1.6	Wed Oct 31 23:59:36 2001
--- openafs/src/bozo/test/Makefile.in	Thu Mar  9 01:34:31 2006
***************
*** 11,17 ****
  INCDIRS=-I${TOP_INCDIR} -I..
  LDIRS=-L${TOP_LIBDIR} -L${DESTDIR}/lib/afs -L..
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS}
  
  all: testproc smail-notifier
  
--- 11,17 ----
  INCDIRS=-I${TOP_INCDIR} -I..
  LDIRS=-L${TOP_LIBDIR} -L${DESTDIR}/lib/afs -L..
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS} ${ARCHFLAGS}
  
  all: testproc smail-notifier
  
Index: openafs/src/bucoord/commands.c
diff -c openafs/src/bucoord/commands.c:1.17 openafs/src/bucoord/commands.c:1.18
*** openafs/src/bucoord/commands.c:1.17	Sun Jul 10 23:22:19 2005
--- openafs/src/bucoord/commands.c	Tue Apr 11 15:27:03 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/bucoord/commands.c,v 1.17 2005/07/11 03:22:19 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #if defined(AFS_LINUX24_ENV)
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/bucoord/commands.c,v 1.18 2006/04/11 19:27:03 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #if defined(AFS_LINUX24_ENV)
***************
*** 1964,1970 ****
      code = bc_StartDmpRst(bc_globalConfig, dumpPath, vsName, volsToDump,
  			  /*destServer */ 0, /*destPartition */ 0,
  			  /*fromDate */ 0,
! 			  /*newExt */ 0, /*oldFlag */ 0,
  			  parent, level, bc_Dumper, portp, /*portCount */ 1,
  			  baseds, doAppend, dontExecute);
      if (code)
--- 1964,1970 ----
      code = bc_StartDmpRst(bc_globalConfig, dumpPath, vsName, volsToDump,
  			  /*destServer */ 0, /*destPartition */ 0,
  			  /*fromDate */ 0,
! 			  /*newExt */ NULL, /*oldFlag */ 0,
  			  parent, level, bc_Dumper, portp, /*portCount */ 1,
  			  baseds, doAppend, dontExecute);
      if (code)
Index: openafs/src/budb/struct_ops.c
diff -c openafs/src/budb/struct_ops.c:1.7 openafs/src/budb/struct_ops.c:1.8
*** openafs/src/budb/struct_ops.c:1.7	Sun Dec  7 20:45:28 2003
--- openafs/src/budb/struct_ops.c	Tue Apr  4 16:51:16 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/budb/struct_ops.c,v 1.7 2003/12/08 01:45:28 jaltman Exp $");
  
  #include &lt;stdio.h&gt;
  #ifdef AFS_NT40_ENV
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/budb/struct_ops.c,v 1.8 2006/04/04 20:51:16 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #ifdef AFS_NT40_ENV
***************
*** 36,56 ****
   * ----------------------------------
   */
  
! printDbHeader(ptr)
!      struct DbHeader *ptr;
  {
      printf("version = %d\n", ptr-&gt;dbversion);
!     printf("created = %s", ctime((time_t *) &amp; ptr-&gt;created));
      printf("cell = %s\n", ptr-&gt;cell);
      printf("lastDumpId = %u\n", ptr-&gt;lastDumpId);
      printf("lastInstanceId = %d\n", ptr-&gt;lastInstanceId);
      printf("lastTapeId = %d\n", ptr-&gt;lastTapeId);
  }
  
! printDump(fid, dptr)
!      FILE *fid;
!      struct dump *dptr;
  {
      fprintf(fid, "id = %u\n", dptr-&gt;id);
      fprintf(fid, "idHashChain = %d\n", dptr-&gt;idHashChain);
      fprintf(fid, "name = %s\n", dptr-&gt;dumpName);
--- 36,57 ----
   * ----------------------------------
   */
  
! void
! printDbHeader(struct DbHeader *ptr)
  {
+     time_t created = ptr-&gt;created;
      printf("version = %d\n", ptr-&gt;dbversion);
!     printf("created = %s", ctime(&amp;created));
      printf("cell = %s\n", ptr-&gt;cell);
      printf("lastDumpId = %u\n", ptr-&gt;lastDumpId);
      printf("lastInstanceId = %d\n", ptr-&gt;lastInstanceId);
      printf("lastTapeId = %d\n", ptr-&gt;lastTapeId);
  }
  
! void
! printDump(FILE *fid, struct dump *dptr)
  {
+     time_t created = dptr-&gt;created;
      fprintf(fid, "id = %u\n", dptr-&gt;id);
      fprintf(fid, "idHashChain = %d\n", dptr-&gt;idHashChain);
      fprintf(fid, "name = %s\n", dptr-&gt;dumpName);
***************
*** 59,65 ****
      fprintf(fid, "nameHashChain = %d\n", dptr-&gt;nameHashChain);
      fprintf(fid, "flags = 0x%x\n", dptr-&gt;flags);
      fprintf(fid, "parent = %u\n", dptr-&gt;parent);
!     fprintf(fid, "created = %s", ctime((time_t *) &amp; dptr-&gt;created));
      fprintf(fid, "nVolumes = %d\n", dptr-&gt;nVolumes);
      /* printTapeSet(&amp;dptr-&gt;tapes); */
      fprintf(fid, "firstTape = %d\n", dptr-&gt;firstTape);
--- 60,66 ----
      fprintf(fid, "nameHashChain = %d\n", dptr-&gt;nameHashChain);
      fprintf(fid, "flags = 0x%x\n", dptr-&gt;flags);
      fprintf(fid, "parent = %u\n", dptr-&gt;parent);
!     fprintf(fid, "created = %s", ctime(&amp;created));
      fprintf(fid, "nVolumes = %d\n", dptr-&gt;nVolumes);
      /* printTapeSet(&amp;dptr-&gt;tapes); */
      fprintf(fid, "firstTape = %d\n", dptr-&gt;firstTape);
***************
*** 67,75 ****
  
  }
  
! printDumpEntry(deptr)
!      struct budb_dumpEntry *deptr;
  {
      printf("id = %u\n", deptr-&gt;id);
      printf("Initial id = %u\n", deptr-&gt;initialDumpID);
      printf("Appended id = %u\n", deptr-&gt;appendedDumpID);
--- 68,77 ----
  
  }
  
! void 
! printDumpEntry(struct budb_dumpEntry *deptr)
  {
+     time_t created = deptr-&gt;created;
      printf("id = %u\n", deptr-&gt;id);
      printf("Initial id = %u\n", deptr-&gt;initialDumpID);
      printf("Appended id = %u\n", deptr-&gt;appendedDumpID);
***************
*** 94,100 ****
      printf("volumeSet = %s\n", deptr-&gt;volumeSetName);
      printf("dump path = %s\n", deptr-&gt;dumpPath);
      printf("name = %s\n", deptr-&gt;name);
!     printf("created = %s", ctime((time_t *) &amp; deptr-&gt;created));
      printf("nVolumes = %d\n", deptr-&gt;nVolumes);
  
      printTapeSet(&amp;deptr-&gt;tapes, (deptr-&gt;flags &amp; BUDB_DUMP_XBSA_NSS));
--- 96,102 ----
      printf("volumeSet = %s\n", deptr-&gt;volumeSetName);
      printf("dump path = %s\n", deptr-&gt;dumpPath);
      printf("name = %s\n", deptr-&gt;name);
!     printf("created = %s", ctime(&amp;created));
      printf("nVolumes = %d\n", deptr-&gt;nVolumes);
  
      printTapeSet(&amp;deptr-&gt;tapes, (deptr-&gt;flags &amp; BUDB_DUMP_XBSA_NSS));
***************
*** 156,169 ****
  }
  
  int
! printTape(fid, tptr)
!      FILE *fid;
!      struct tape *tptr;
  {
      fprintf(fid, "name = %s\n", tptr-&gt;name);
      fprintf(fid, "nameHashChain = %d\n", tptr-&gt;nameHashChain);
      fprintf(fid, "flags = 0x%x\n", tptr-&gt;flags);
!     fprintf(fid, "written = %s", ctime((time_t *) &amp; tptr-&gt;written));
      fprintf(fid, "nMBytes = %d\n", tptr-&gt;nMBytes);
      fprintf(fid, "nBytes = %d\n", tptr-&gt;nBytes);
      fprintf(fid, "nFiles = %d\n", tptr-&gt;nFiles);
--- 158,170 ----
  }
  
  int
! printTape(FILE *fid, struct tape *tptr)
  {
+     time_t written = tptr-&gt;written;
      fprintf(fid, "name = %s\n", tptr-&gt;name);
      fprintf(fid, "nameHashChain = %d\n", tptr-&gt;nameHashChain);
      fprintf(fid, "flags = 0x%x\n", tptr-&gt;flags);
!     fprintf(fid, "written = %s", ctime(&amp;written));
      fprintf(fid, "nMBytes = %d\n", tptr-&gt;nMBytes);
      fprintf(fid, "nBytes = %d\n", tptr-&gt;nBytes);
      fprintf(fid, "nFiles = %d\n", tptr-&gt;nFiles);
***************
*** 178,186 ****
  }
  
  int
! printTapeEntry(teptr)
!      struct budb_tapeEntry *teptr;
  {
      printf("name = %s\n", teptr-&gt;name);
      printf("flags = 0x%x", teptr-&gt;flags);
      if (teptr-&gt;flags &amp; BUDB_TAPE_TAPEERROR)
--- 179,189 ----
  }
  
  int
! printTapeEntry(struct budb_tapeEntry *teptr)
  {
+     time_t written = teptr-&gt;written;
+     time_t expires = teptr-&gt;expires;
+ 
      printf("name = %s\n", teptr-&gt;name);
      printf("flags = 0x%x", teptr-&gt;flags);
      if (teptr-&gt;flags &amp; BUDB_TAPE_TAPEERROR)
***************
*** 196,203 ****
      if (teptr-&gt;flags &amp; BUDB_TAPE_WRITTEN)
  	printf(": Successful");
      printf("\n");
!     printf("written = %s", ctime((time_t *) &amp; teptr-&gt;written));
!     printf("expires = %s", cTIME((time_t *) &amp; teptr-&gt;expires));
      printf("kBytes Tape Used = %u\n", teptr-&gt;useKBytes);
      printf("nMBytes Data = %d\n", teptr-&gt;nMBytes);
      printf("nBytes  Data = %d\n", teptr-&gt;nBytes);
--- 199,206 ----
      if (teptr-&gt;flags &amp; BUDB_TAPE_WRITTEN)
  	printf(": Successful");
      printf("\n");
!     printf("written = %s", ctime(&amp;written));
!     printf("expires = %s", cTIME(&amp;expires));
      printf("kBytes Tape Used = %u\n", teptr-&gt;useKBytes);
      printf("nMBytes Data = %d\n", teptr-&gt;nMBytes);
      printf("nBytes  Data = %d\n", teptr-&gt;nBytes);
***************
*** 227,235 ****
  }
  
  int
! printVolumeEntry(veptr)
!      struct budb_volumeEntry *veptr;
  {
      printf("name = %s\n", veptr-&gt;name);
      printf("flags = 0x%x", veptr-&gt;flags);
      if (veptr-&gt;flags &amp; BUDB_VOL_TAPEERROR)
--- 230,238 ----
  }
  
  int
! printVolumeEntry(struct budb_volumeEntry *veptr)
  {
+     time_t clone = veptr-&gt;clone;
      printf("name = %s\n", veptr-&gt;name);
      printf("flags = 0x%x", veptr-&gt;flags);
      if (veptr-&gt;flags &amp; BUDB_VOL_TAPEERROR)
***************
*** 251,257 ****
      printf("tapeSeq = %d\n", veptr-&gt;tapeSeq);
  
      printf("position = %d\n", veptr-&gt;position);
!     printf("clone = %s", ctime((time_t *) &amp; veptr-&gt;clone));
      printf("startByte = %d\n", veptr-&gt;startByte);
      printf("nBytes = %d\n", veptr-&gt;nBytes);
      printf("seq = %d\n", veptr-&gt;seq);
--- 254,260 ----
      printf("tapeSeq = %d\n", veptr-&gt;tapeSeq);
  
      printf("position = %d\n", veptr-&gt;position);
!     printf("clone = %s", ctime(&amp;clone));
      printf("startByte = %d\n", veptr-&gt;startByte);
      printf("nBytes = %d\n", veptr-&gt;nBytes);
      printf("seq = %d\n", veptr-&gt;seq);
***************
*** 262,278 ****
  }
  
  int
! printVolFragment(fid, vfptr)
!      FILE *fid;
!      struct volFragment *vfptr;
  {
      fprintf(fid, "vol = %d\n", vfptr-&gt;vol);
      fprintf(fid, "sameNameChain = %d\n", vfptr-&gt;sameNameChain);
      fprintf(fid, "tape = %d\n", vfptr-&gt;tape);
      fprintf(fid, "sameTapeChain = %d\n", vfptr-&gt;sameTapeChain);
      fprintf(fid, "position = %d\n", vfptr-&gt;position);
!     fprintf(fid, "clone = %s", ctime((time_t *) &amp; vfptr-&gt;clone));
!     fprintf(fid, "incTime = %s", ctime((time_t *) &amp; vfptr-&gt;incTime));
      fprintf(fid, "startByte = %d\n", vfptr-&gt;startByte);
      fprintf(fid, "nBytes = %d\n", vfptr-&gt;nBytes);
      fprintf(fid, "flags = %d\n", vfptr-&gt;flags);
--- 265,281 ----
  }
  
  int
! printVolFragment(FILE *fid, struct volFragment *vfptr)
  {
+     time_t clone = vfptr-&gt;clone;
+     time_t incTime = vfptr-&gt;incTime;
      fprintf(fid, "vol = %d\n", vfptr-&gt;vol);
      fprintf(fid, "sameNameChain = %d\n", vfptr-&gt;sameNameChain);
      fprintf(fid, "tape = %d\n", vfptr-&gt;tape);
      fprintf(fid, "sameTapeChain = %d\n", vfptr-&gt;sameTapeChain);
      fprintf(fid, "position = %d\n", vfptr-&gt;position);
!     fprintf(fid, "clone = %s", ctime(&amp;clone));
!     fprintf(fid, "incTime = %s", ctime(&amp;incTime));
      fprintf(fid, "startByte = %d\n", vfptr-&gt;startByte);
      fprintf(fid, "nBytes = %d\n", vfptr-&gt;nBytes);
      fprintf(fid, "flags = %d\n", vfptr-&gt;flags);
Index: openafs/src/cf/osconf.m4
diff -c openafs/src/cf/osconf.m4:1.79 openafs/src/cf/osconf.m4:1.83
*** openafs/src/cf/osconf.m4:1.79	Wed Feb  1 11:20:07 2006
--- openafs/src/cf/osconf.m4	Wed Apr 26 11:36:24 2006
***************
*** 2,7 ****
--- 2,8 ----
  AC_DEFUN([OPENAFS_OSCONF], [
  
  dnl defaults, override in case below as needed
+ CFLAGS=
  XCFLAGS='${DBG} ${OPTMZ}'
  SHLIB_SUFFIX="so"
  CC="cc"
***************
*** 11,23 ****
  
  dnl debugging and optimization flag defaults
  dnl Note, these are all the defaults for if debug/optimize turned on, and
! dnl the arch cases below do not override
  KERN_DBG=-g
  KERN_OPTMZ=-O
  DBG=-g
  OPTMZ=-O
  LWP_DBG=-g
  LWP_OPTMZ=-O
  
  dnl standard programs
  AC_PROG_RANLIB
--- 12,26 ----
  
  dnl debugging and optimization flag defaults
  dnl Note, these are all the defaults for if debug/optimize turned on, and
! dnl the arch cases below do override as needed
  KERN_DBG=-g
  KERN_OPTMZ=-O
  DBG=-g
  OPTMZ=-O
  LWP_DBG=-g
  LWP_OPTMZ=-O
+ PAM_DBG=-g
+ PAM_OPTMZ=
  
  dnl standard programs
  AC_PROG_RANLIB
***************
*** 72,82 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O2 -D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 75,86 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 87,97 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O2 -D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 91,102 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 102,112 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O2 -D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 107,118 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 206,216 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-pthread"
! 		PAM_CFLAGS="-O2 -pipe -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_LINKER="${MT_CC} -shared"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O2 -pipe"
  		YACC="byacc"
  		;;
  
--- 212,223 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-pthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-pipe -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_LINKER="${MT_CC} -shared"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-pipe"
  		YACC="byacc"
  		;;
  
***************
*** 218,228 ****
  		LEX="flex -l"
  		MT_CFLAGS='${XCFLAGS} -DAFS_PTHREAD_ENV -D_REENTRANT '
  		MT_LIBS="-lpthread" # XXX -pthread soon
! 		PAM_CFLAGS="-O2 -pipe -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_LINKER="${MT_CC} -shared"
  		TXLIBS="/usr/lib/libcurses.so"
! 		XCFLAGS="-O2 -pipe"
  		YACC="yacc"
  		;;
  
--- 225,236 ----
  		LEX="flex -l"
  		MT_CFLAGS='${XCFLAGS} -DAFS_PTHREAD_ENV -D_REENTRANT '
  		MT_LIBS="-lpthread" # XXX -pthread soon
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-pipe -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_LINKER="${MT_CC} -shared"
  		TXLIBS="/usr/lib/libcurses.so"
! 		XCFLAGS="-pipe"
  		YACC="yacc"
  		;;
  
***************
*** 230,240 ****
  		LEX="flex -l"
  		MT_CFLAGS='${XCFLAGS}'
  		MT_LIBS=""
! 		PAM_CFLAGS="-O2 -pipe -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_LINKER="${MT_CC} -shared"
  		TXLIBS="/usr/lib/libcurses.so"
! 		XCFLAGS="-O2 -pipe"
  		YACC="bison -y"
  		;;
  
--- 238,249 ----
  		LEX="flex -l"
  		MT_CFLAGS='${XCFLAGS}'
  		MT_LIBS=""
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-pipe -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_LINKER="${MT_CC} -shared"
  		TXLIBS="/usr/lib/libcurses.so"
! 		XCFLAGS="-pipe"
  		YACC="bison -y"
  		;;
  
***************
*** 243,253 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE -G0"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
--- 252,263 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE -G0"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
***************
*** 257,267 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
--- 267,278 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
***************
*** 270,280 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_CFLAGS="-fPIC"
  		TXLIBS="/usr/lib64/libncurses.so"
! 		XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
--- 281,292 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_CFLAGS="-fPIC"
  		TXLIBS="/usr/lib64/libncurses.so"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
***************
*** 283,293 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_CFLAGS="-fPIC"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE -fPIC"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 295,306 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_CFLAGS="-fPIC"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE -fPIC"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 300,310 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O2 -D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 313,324 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 322,332 ****
  		LWP_DBG=-g
  		LWP_OPTMZ=-O2
  		OPTMZ=-O2
! 		PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
--- 336,346 ----
  		LWP_DBG=-g
  		LWP_OPTMZ=-O2
  		OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
***************
*** 343,353 ****
  		LWP_DBG=-g
  		LWP_OPTMZ=-O2
  		OPTMZ=-O2
! 		PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
--- 357,368 ----
  		LWP_DBG=-g
  		LWP_OPTMZ=-O2
  		OPTMZ=-O2
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
***************
*** 364,374 ****
  		LWP_DBG=-g
  		LWP_OPTMZ=-O2
  		OPTMZ=-O2
! 		PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
--- 379,390 ----
  		LWP_DBG=-g
  		LWP_OPTMZ=-O2
  		OPTMZ=-O2
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
***************
*** 378,389 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-pthread"
! 		PAM_CFLAGS="-O2 -pipe -fpic"
  		SHLIB_CFLAGS="-fpic"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_LINKER="${MT_CC} -shared"
  		TXLIBS="/usr/lib/libcurses.a"
! 		XCFLAGS="-O2"
  		YACC="yacc"
  		;;
  
--- 394,406 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-pthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-pipe -fpic"
  		SHLIB_CFLAGS="-fpic"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		SHLIB_LINKER="${MT_CC} -shared"
  		TXLIBS="/usr/lib/libcurses.a"
! 		XCFLAGS=
  		YACC="yacc"
  		;;
  
***************
*** 392,402 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O2 -D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 409,420 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 407,412 ****
--- 425,431 ----
  		REGEX_OBJ="regex.o"
  		XCFLAGS="-traditional-cpp"
  		SHLIB_LINKER="${MT_CC} -dynamiclib"
+ 		SHLIB_SUFFIX="dylib"
  		;;
  
  	ppc_darwin_13)
***************
*** 416,421 ****
--- 435,441 ----
  		REGEX_OBJ="regex.o"
  		XCFLAGS="-no-cpp-precomp"
  		SHLIB_LINKER="${MT_CC} -dynamiclib"
+ 		SHLIB_SUFFIX="dylib"
  		;;
  
  	ppc_darwin_14)
***************
*** 425,430 ****
--- 445,451 ----
  		REGEX_OBJ="regex.o"
  		XCFLAGS="-no-cpp-precomp"
  		SHLIB_LINKER="${MT_CC} -dynamiclib"
+ 		SHLIB_SUFFIX="dylib"
  		;;
  
  	ppc_darwin_60)
***************
*** 435,440 ****
--- 456,462 ----
  		XCFLAGS="-no-cpp-precomp"
  		TXLIBS="-lncurses"
  		SHLIB_LINKER="${MT_CC} -dynamiclib"
+ 		SHLIB_SUFFIX="dylib"
  		;;
  
  	ppc_darwin_70)
***************
*** 449,468 ****
  		TXLIBS="-lncurses"
  		EXTRA_VLIBOBJS="fstab.o"
  		SHLIB_LINKER="${MT_CC} -dynamiclib"
  		;;
  
  	*_darwin_80)
  		AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration"
  		LEX="lex -l"
! 		MT_CFLAGS='-DAFS_PTHREAD_ENV -D_REENTRANT ${XCFLAGS}'
  		KROOT=
  		KINCLUDES='-I$(KROOT)/System/Library/Frameworks/Kernel.framework/Headers'
! 		LWP_OPTMZ="-O2"
  		REGEX_OBJ="regex.o"
- 		XCFLAGS="-no-cpp-precomp"
  		TXLIBS="-lncurses"
  		EXTRA_VLIBOBJS="fstab.o"
  		SHLIB_LINKER="${MT_CC} -dynamiclib"
  		;;
  
  	ppc_linux*)
--- 471,510 ----
  		TXLIBS="-lncurses"
  		EXTRA_VLIBOBJS="fstab.o"
  		SHLIB_LINKER="${MT_CC} -dynamiclib"
+ 		SHLIB_SUFFIX="dylib"
  		;;
  
  	*_darwin_80)
  		AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration"
  		LEX="lex -l"
! 		MT_CFLAGS='-DAFS_PTHREAD_ENV -D_REENTRANT ${XCFLAGS} ${ARCHFLAGS}'
  		KROOT=
  		KINCLUDES='-I$(KROOT)/System/Library/Frameworks/Kernel.framework/Headers'
! 		KERN_OPTMZ="-Os"
! 		LWP_OPTMZ="-Os"
! 		OPTMZ="-Os"
  		REGEX_OBJ="regex.o"
  		TXLIBS="-lncurses"
  		EXTRA_VLIBOBJS="fstab.o"
  		SHLIB_LINKER="${MT_CC} -dynamiclib"
+ 		SHLIB_SUFFIX="dylib"
+ 		;;
+ 
+ 	*_darwin_90)
+ 		AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration"
+ 		LEX="lex -l"
+ 		MT_CFLAGS='-DAFS_PTHREAD_ENV -D_REENTRANT ${XCFLAGS} ${ARCHFLAGS}'
+ 		KROOT=
+ 		KINCLUDES='-I$(KROOT)/System/Library/Frameworks/Kernel.framework/Headers'
+ 		LD="cc"
+ 		KERN_OPTMZ="-Os"
+ 		LWP_OPTMZ="-Os"
+ 		OPTMZ="-Os"
+ 		REGEX_OBJ="regex.o"
+ 		TXLIBS="-lncurses"
+ 		EXTRA_VLIBOBJS="fstab.o"
+ 		SHLIB_LINKER="${MT_CC} -dynamiclib"
+ 		SHLIB_SUFFIX="dylib"
  		;;
  
  	ppc_linux*)
***************
*** 470,480 ****
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O2 -D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 512,523 ----
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 549,559 ****
  		MT_CC="$CC"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O -g -D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 592,604 ----
  		MT_CC="$CC"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		OPTMZ=-O
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 567,577 ****
  		MT_CC="$CC"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O -g -D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 612,623 ----
  		MT_CC="$CC"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 585,595 ****
  		MT_CC="$CC"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x -Xlinker -Bsymbolic"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O -g -D_LARGEFILE64_SOURCE -D__s390x__"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
--- 631,643 ----
  		MT_CC="$CC"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x -Xlinker -Bsymbolic"
  		TXLIBS="-lncurses"
! 		OPTMZ=-O
! 		XCFLAGS="-D_LARGEFILE64_SOURCE -D__s390x__"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
***************
*** 656,690 ****
  		SHLIB_LINKER="${CC} -shared"
  		;;
  
! 	sparc64_linux*)
  		KERN_OPTMZ=-O2
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-O2 -D_LARGEFILE64_SOURCE"
! 		XCFLAGS64="-O2 -D_LARGEFILE64_SOURCE -m64"
  		XLDFLAGS64="-m64"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
- 	sparc_linux22)
- 		KERN_OPTMZ=-O2
- 		LEX="flex -l"
- 		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
- 		MT_LIBS="-lpthread"
- 		PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC"
- 		SHLIB_LDFLAGS="-shared -Xlinker -x"
- 		TXLIBS="-lncurses"
- 		XCFLAGS="-O2 -D_LARGEFILE64_SOURCE"
- 		YACC="bison -y"
- 		SHLIB_LINKER="${MT_CC} -shared"
- 		;;
- 
  	sun4_413)
  		CCXPG2="/usr/xpg2bin/cc"
  		CC="gcc"
--- 704,726 ----
  		SHLIB_LINKER="${CC} -shared"
  		;;
  
! 	sparc*_linux*)
  		KERN_OPTMZ=-O2
  		LEX="flex -l"
  		MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}'
  		MT_LIBS="-lpthread"
! 		PAM_OPTMZ=-O2
! 		PAM_CFLAGS="-Dlinux -DLINUX_PAM -fPIC"
  		SHLIB_CFLAGS="-fPIC"
  		SHLIB_LDFLAGS="-shared -Xlinker -x"
  		TXLIBS="-lncurses"
! 		XCFLAGS="-D_LARGEFILE64_SOURCE"
! 		XCFLAGS64="-D_LARGEFILE64_SOURCE -m64"
  		XLDFLAGS64="-m64"
  		YACC="bison -y"
  		SHLIB_LINKER="${MT_CC} -shared"
  		;;
  
  	sun4_413)
  		CCXPG2="/usr/xpg2bin/cc"
  		CC="gcc"
***************
*** 947,952 ****
--- 983,1000 ----
  	;;
  esac
  
+ 
+ 
+ dnl pthreads fixes
+ case $AFS_SYSNAME in
+ dnl we'll go ahead and turn on XOPEN2K and ISO_C99
+ dnl if this causes problems, we should scale back to _XOPEN_SOURCE=500
+ 	*linux*)
+ 		MT_CFLAGS="${MT_CFLAGS} -D_XOPEN_SOURCE=600 -D_BSD_SOURCE"
+ 	;;
+ esac
+ 
+ 
  dnl Disable the default for debugging/optimization if not enabled
  if test "x$enable_debug_kernel" = "xno"; then
    KERN_DBG=
***************
*** 995,1000 ****
--- 1043,1050 ----
  AC_SUBST(OPTMZ)
  AC_SUBST(PAM_CFLAGS)
  AC_SUBST(PAM_LIBS)
+ AC_SUBST(PAM_DBG)
+ AC_SUBST(PAM_OPTMZ)
  AC_SUBST(PINSTALL_LIBS)
  AC_SUBST(RANLIB)
  AC_SUBST(REGEX_OBJ)
Index: openafs/src/cmd/test/Makefile.in
diff -c openafs/src/cmd/test/Makefile.in:1.7 openafs/src/cmd/test/Makefile.in:1.8
*** openafs/src/cmd/test/Makefile.in:1.7	Tue Oct 15 23:58:30 2002
--- openafs/src/cmd/test/Makefile.in	Thu Mar  9 01:34:33 2006
***************
*** 14,20 ****
  
  INCDIRS=  -I${SRCDIR}/include -I${SRCDIR}/include/afs -I..
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS}
  
  all: test
  test tests: ctest dtest itest
--- 14,20 ----
  
  INCDIRS=  -I${SRCDIR}/include -I${SRCDIR}/include/afs -I..
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS} ${ARCHFLAGS}
  
  all: test
  test tests: ctest dtest itest
Index: openafs/src/comerr/test/Makefile.in
diff -c openafs/src/comerr/test/Makefile.in:1.6 openafs/src/comerr/test/Makefile.in:1.7
*** openafs/src/comerr/test/Makefile.in:1.6	Wed Oct 31 23:59:42 2001
--- openafs/src/comerr/test/Makefile.in	Thu Mar  9 01:34:34 2006
***************
*** 6,12 ****
  INCDIRS=-I${TOP_INCDIR} -I..
  LDIRS=-L${TOP_LIBDIR} -L${DESTDIR}/lib/afs -L..
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} -lcom_err ${XCFLAGS}
  
  all: test
  
--- 6,12 ----
  INCDIRS=-I${TOP_INCDIR} -I..
  LDIRS=-L${TOP_LIBDIR} -L${DESTDIR}/lib/afs -L..
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} -lcom_err ${XCFLAGS} ${ARCHFLAGS}
  
  all: test
  
Index: openafs/src/config/Makefile.config.in
diff -c openafs/src/config/Makefile.config.in:1.10 openafs/src/config/Makefile.config.in:1.12
*** openafs/src/config/Makefile.config.in:1.10	Sun May  9 23:19:01 2004
--- openafs/src/config/Makefile.config.in	Wed Apr 26 11:36:21 2006
***************
*** 60,65 ****
--- 60,67 ----
  OPTMZ = @OPTMZ@
  PAM_CFLAGS = @PAM_CFLAGS@
  PAM_LIBS = @PAM_LIBS@
+ PAM_OPTMZ = @PAM_OPTMZ@
+ PAM_DBG = @PAM_DBG@
  PINSTALL_LIBS = @PINSTALL_LIBS@
  RANLIB = @RANLIB@
  REGEX_OBJ = @REGEX_OBJ@
***************
*** 125,132 ****
  COMMON_INCL=-I${TOP_OBJDIR}/src/config -I. -I${srcdir} -I${TOP_INCDIR} -I${TOP_INCDIR}/afs -I${TOP_INCDIR}/rx -I${TOP_OBJDIR} -I${TOP_SRCDIR} -I${TOP_OBJDIR}/src
  COMMON_CFLAGS=${DBG} ${OPTMZ} ${COMMON_INCL}
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS}
! LDFLAGS=${XLDFLAGS}
  
  .c.o:
  	$(CCOBJ) $(CFLAGS) -c $&lt;
--- 127,134 ----
  COMMON_INCL=-I${TOP_OBJDIR}/src/config -I. -I${srcdir} -I${TOP_INCDIR} -I${TOP_INCDIR}/afs -I${TOP_INCDIR}/rx -I${TOP_OBJDIR} -I${TOP_SRCDIR} -I${TOP_OBJDIR}/src
  COMMON_CFLAGS=${DBG} ${OPTMZ} ${COMMON_INCL}
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${ARCHFLAGS}
! LDFLAGS=${XLDFLAGS} ${ARCHFLAGS}
  
  .c.o:
  	$(CCOBJ) $(CFLAGS) -c $&lt;
Index: openafs/src/config/Makefile.i386_djgpp
diff -c openafs/src/config/Makefile.i386_djgpp:1.7 openafs/src/config/Makefile.i386_djgpp:1.8
*** openafs/src/config/Makefile.i386_djgpp:1.7	Wed Oct 31 23:59:43 2001
--- openafs/src/config/Makefile.i386_djgpp	Thu Mar  9 01:34:35 2006
***************
*** 16,22 ****
  #PAM_CFLAGS = -O2 -Dlinux -DLINUX_PAM -fPIC
  # Put -O2 here to _ensure_ all Makefiles pick it up.
  XCFLAGS= ${DBG} -Dfds_bits=fd_bits -DAFS_AFSDB_ENV -DAFS_FREELANCE_CLIENT
! MT_CFLAGS=${XCFLAGS}
  XLDFLAGS=
  SHLIB_LDFLAGS = -shared -Xlinker -x
  SHLIB_SUFFIX=so
--- 16,22 ----
  #PAM_CFLAGS = -O2 -Dlinux -DLINUX_PAM -fPIC
  # Put -O2 here to _ensure_ all Makefiles pick it up.
  XCFLAGS= ${DBG} -Dfds_bits=fd_bits -DAFS_AFSDB_ENV -DAFS_FREELANCE_CLIENT
! MT_CFLAGS=${XCFLAGS} ${ARCHFLAGS}
  XLDFLAGS=
  SHLIB_LDFLAGS = -shared -Xlinker -x
  SHLIB_SUFFIX=so
Index: openafs/src/config/Makefile.in
diff -c openafs/src/config/Makefile.in:1.14 openafs/src/config/Makefile.in:1.15
*** openafs/src/config/Makefile.in:1.14	Sat Jan 11 02:34:04 2003
--- openafs/src/config/Makefile.in	Thu Mar  9 01:34:35 2006
***************
*** 8,14 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${DBG} ${OPTMZ} -I${TOP_INCDIR} -I. ${XCFLAGS}
  
  INST=$(RM) -f $@; $(CP) $? $@
  
--- 8,14 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${DBG} ${OPTMZ} -I${TOP_INCDIR} -I. ${XCFLAGS} ${ARCHFLAGS}
  
  INST=$(RM) -f $@; $(CP) $? $@
  
Index: openafs/src/config/NTMakefile
diff -c openafs/src/config/NTMakefile:1.19 openafs/src/config/NTMakefile:1.20
*** openafs/src/config/NTMakefile:1.19	Sun Nov 20 20:56:48 2005
--- openafs/src/config/NTMakefile	Sat Mar  4 16:42:12 2006
***************
*** 230,235 ****
--- 230,238 ----
  !	IF (!EXIST($(OJT)\volser))
  		$(MKDIR) $(OJT)\volser
  !	ENDIF
+ !	IF (!EXIST($(OJT)\xstat))
+ 		$(MKDIR) $(OJT)\xstat
+ !	ENDIF
  !	IF (!EXIST($(OJT)\WINNT))
  		$(MKDIR) $(OJT)\WINNT
  !	ENDIF
Index: openafs/src/config/NTMakefile.amd64_w2k
diff -c openafs/src/config/NTMakefile.amd64_w2k:1.23 openafs/src/config/NTMakefile.amd64_w2k:1.24
*** openafs/src/config/NTMakefile.amd64_w2k:1.23	Tue Feb 14 09:03:22 2006
--- openafs/src/config/NTMakefile.amd64_w2k	Mon Apr 24 11:02:48 2006
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=0000
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=0001
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/NTMakefile.i386_nt40
diff -c openafs/src/config/NTMakefile.i386_nt40:1.83 openafs/src/config/NTMakefile.i386_nt40:1.84
*** openafs/src/config/NTMakefile.i386_nt40:1.83	Tue Feb 14 09:03:22 2006
--- openafs/src/config/NTMakefile.i386_nt40	Mon Apr 24 11:02:48 2006
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=0000
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=0001
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/NTMakefile.i386_w2k
diff -c openafs/src/config/NTMakefile.i386_w2k:1.22 openafs/src/config/NTMakefile.i386_w2k:1.23
*** openafs/src/config/NTMakefile.i386_w2k:1.22	Tue Feb 14 09:03:22 2006
--- openafs/src/config/NTMakefile.i386_w2k	Mon Apr 24 11:02:48 2006
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=0000
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=0001
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/afs_sysnames.h
diff -c openafs/src/config/afs_sysnames.h:1.73 openafs/src/config/afs_sysnames.h:1.77
*** openafs/src/config/afs_sysnames.h:1.73	Tue Jan 10 23:44:49 2006
--- openafs/src/config/afs_sysnames.h	Wed Mar 15 11:15:07 2006
***************
*** 60,65 ****
--- 60,67 ----
  #define SYS_NAME_ID_ppc_darwin_70        507
  #define SYS_NAME_ID_ppc_darwin_80        508
  #define SYS_NAME_ID_x86_darwin_80        509
+ #define SYS_NAME_ID_ppc_darwin_90        510
+ #define SYS_NAME_ID_x86_darwin_90        511
  
  #define SYS_NAME_ID_next_mach20		 601
  #define SYS_NAME_ID_next_mach30		 602
***************
*** 157,162 ****
--- 159,165 ----
  #define SYS_NAME_ID_s390_linux2         1900
  #define SYS_NAME_ID_s390_linux22        1901
  #define SYS_NAME_ID_s390_linux24        1902
+ #define SYS_NAME_ID_s390_linux26        1907
  #define SYS_NAME_ID_s390x_linux2         1903
  #define SYS_NAME_ID_s390x_linux22        1904
  #define SYS_NAME_ID_s390x_linux24        1905
***************
*** 178,183 ****
--- 181,187 ----
  #define SYS_NAME_ID_i386_fbsd_52        2107
  #define SYS_NAME_ID_i386_fbsd_53        2108
  #define SYS_NAME_ID_i386_fbsd_60        2112
+ #define SYS_NAME_ID_i386_fbsd_61        2113
  
  #define SYS_NAME_ID_ia64_linux2		2200
  #define SYS_NAME_ID_ia64_linux22	2201
***************
*** 218,223 ****
--- 222,228 ----
  #define SYS_NAME_ID_i386_obsd36		2605
  #define SYS_NAME_ID_i386_obsd37		2606
  #define SYS_NAME_ID_i386_obsd38		2607
+ #define SYS_NAME_ID_i386_obsd39		2608
  
  #define SYS_NAME_ID_amd64_linux2        2700
  #define SYS_NAME_ID_amd64_linux22       2701
Index: openafs/src/config/linux-version
diff -c openafs/src/config/linux-version:1.3 openafs/src/config/linux-version:1.4
*** openafs/src/config/linux-version:1.3	Fri Dec  1 17:52:01 2000
--- openafs/src/config/linux-version	Thu Mar 23 10:48:29 2006
***************
*** 40,54 ****
  for VERS in $LINUX_VERS ; do
  	dir=$LINUX_SRCDIR$VERS
  	if [ ! -d $dir ] ; then
  		echo "ERROR: Cannot build for Linux kernel $VERS: $dir does not exist."
  		errors=true
  		continue
  	fi
  	header=$LINUX_SRCDIR$VERS/include/linux/version.h
  	if [ ! -f $header ] ; then
! 	    echo "ERROR: Cannot build for Linux kernel $VERS: $header does not exist."
! 	    errors=true
! 	    continue
  	fi
  
  	vers=`fgrep UTS_RELEASE $LINUX_SRCDIR$VERS/include/linux/version.h |
--- 40,60 ----
  for VERS in $LINUX_VERS ; do
  	dir=$LINUX_SRCDIR$VERS
  	if [ ! -d $dir ] ; then
+ 	    dir=$LINUX_SRCDIR
+ 	    if [ ! -d $dir ] ; then
  		echo "ERROR: Cannot build for Linux kernel $VERS: $dir does not exist."
  		errors=true
  		continue
+       	    fi
  	fi
  	header=$LINUX_SRCDIR$VERS/include/linux/version.h
  	if [ ! -f $header ] ; then
! 	    header=$LINUX_SRCDIR/include/linux/version.h
! 	    if [ ! -f $header ] ; then
! 	        echo "ERROR: Cannot build for Linux kernel $VERS: $header does not exist."
! 	        errors=true
! 	        continue
! 	    fi
  	fi
  
  	vers=`fgrep UTS_RELEASE $LINUX_SRCDIR$VERS/include/linux/version.h |
Index: openafs/src/config/param.i386_fbsd_61.h
diff -c /dev/null openafs/src/config/param.i386_fbsd_61.h:1.1
*** /dev/null	Thu Apr 27 12:42:29 2006
--- openafs/src/config/param.i386_fbsd_61.h	Tue Feb 21 16:07:57 2006
***************
*** 0 ****
--- 1,198 ----
+ #ifndef	AFS_PARAM_H
+ #define	AFS_PARAM_H
+ 
+ /* Machine / Operating system information */
+ #define SYS_NAME	"i386_fbsd_61"
+ #define SYS_NAME_ID	SYS_NAME_ID_i386_fbsd_61
+ 
+ #define AFSLITTLE_ENDIAN    1
+ #define AFS_HAVE_FFS        1	/* Use system's ffs. */
+ #define AFS_HAVE_STATVFS    1	/* System doesn't support statvfs */
+ #define AFS_VM_RDWR_ENV	    1	/* read/write implemented via VM */
+ 
+ #ifndef UKERNEL
+ /* This section for kernel libafs compiles only */
+ 
+ #ifndef IGNORE_STDS_H
+ #include &lt;sys/param.h&gt;
+ #endif
+ 
+ #define AFS_XBSD_ENV 1		/* {Free,Open,Net}BSD */
+ #define AFS_X86_XBSD_ENV 1
+ 
+ #define AFS_NAMEI_ENV     1	/* User space interface to file system */
+ #define AFS_64BIT_ENV 1
+ #define AFS_64BIT_CLIENT 1
+ #define AFS_64BIT_IOPS_ENV 1	/* Needed for NAMEI */
+ #define AFS_FBSD_ENV 1
+ #define AFS_FBSD40_ENV 1
+ #define AFS_FBSD42_ENV 1
+ #define AFS_FBSD43_ENV 1
+ #define AFS_FBSD44_ENV 1
+ #define AFS_FBSD45_ENV 1
+ #define AFS_FBSD46_ENV 1
+ #define AFS_FBSD47_ENV 1
+ #define AFS_FBSD50_ENV 1
+ #define AFS_FBSD51_ENV 1
+ #define AFS_FBSD52_ENV 1
+ #define AFS_FBSD53_ENV 1
+ #define AFS_FBSD60_ENV 1
+ #define AFS_FBSD61_ENV 1
+ #define AFS_X86_FBSD_ENV 1
+ #define AFS_X86_FBSD40_ENV 1
+ #define AFS_X86_FBSD42_ENV 1
+ #define AFS_X86_FBSD43_ENV 1
+ #define AFS_X86_FBSD46_ENV 1
+ #define AFS_X86_FBSD47_ENV 1
+ #define AFS_X86_FBSD50_ENV 1
+ #define AFS_X86_ENV 1
+ #define AFS_NONFSTRANS 1
+ #define FTRUNC O_TRUNC
+ 
+ #define IUPD 0x0010
+ #define IACC 0x0020
+ #define ICHG 0x0040
+ #define IMOD 0x0080
+ 
+ #define IN_LOCK(ip)     lockmgr(&amp;ip-&gt;i_lock, LK_EXCLUSIVE, \
+                                 NULL, curproc)
+ #define IN_UNLOCK(ip)   lockmgr(&amp;ip-&gt;i_lock, LK_RELEASE, \
+                                 NULL, curproc)
+ 
+ #include &lt;afs/afs_sysnames.h&gt;
+ 
+ #define AFS_VFS_ENV	1
+ #define AFS_VFSINCL_ENV 1
+ #define AFS_GREEDY43_ENV	1
+ #define AFS_ENV  	1
+ 
+ #define AFS_SYSCALL	339
+ #define AFS_MOUNT_AFS	"afs"
+ 
+ #ifndef MOUNT_UFS
+ #define MOUNT_UFS "ufs"
+ #endif
+ 
+ #ifndef	MOUNT_AFS
+ #define	MOUNT_AFS AFS_MOUNT_AFS
+ #endif
+ 
+ #define RXK_LISTENER_ENV 1
+ #define AFS_GCPAGS	        0	/* if nonzero, garbage collect PAGs */
+ #define AFS_USE_GETTIMEOFDAY    1	/* use gettimeofday to implement rx clock */
+ 
+ /* Extra kernel definitions (from kdefs file) */
+ #ifdef _KERNEL
+ #define AFS_GLOBAL_SUNLOCK        1
+ #define	AFS_VFS34	1	/* What is VFS34??? */
+ #define	AFS_SHORTGID	0	/* are group id's short? */
+ #define	afsio_iov	uio_iov
+ #define	afsio_iovcnt	uio_iovcnt
+ #define	afsio_offset	uio_offset
+ #define	afsio_seg	uio_segflg
+ #define	afsio_resid	uio_resid
+ #define	AFS_UIOSYS	UIO_SYSSPACE
+ #define	AFS_UIOUSER	UIO_USERSPACE
+ #define	AFS_CLBYTES	CLBYTES
+ #define	osi_GetTime(x)	microtime(x)
+ #define AFS_KALLOC(x)   osi_fbsd_alloc((x), 1)
+ #undef	AFS_KALLOC_NOSLEEP
+ #define	AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+ #define AFS_KFREE(x,y)  osi_fbsd_free((x))
+ #define	v_count		v_usecount
+ #define v_vfsp		v_mount
+ #define vfs_bsize	mnt_stat.f_bsize
+ #define vfs_fsid	mnt_stat.f_fsid
+ #define va_nodeid	va_fileid
+ #define vfs_vnodecovered mnt_vnodecovered
+ #define direct		dirent
+ #define vnode_t		struct vnode
+ 
+ #ifndef MUTEX_DEFAULT
+ #define MUTEX_DEFAULT   0
+ #endif /* MUTEX_DEFAULT */
+ 
+ #ifndef SSYS
+ #define SSYS            0x00002
+ #endif /* SSYS */
+ 
+ #define p_rcred         p_ucred
+ 
+ #if	!defined(ASSEMBLER) &amp;&amp; !defined(__LANGUAGE_ASSEMBLY__)
+ enum vcexcl { NONEXCL, EXCL };
+ 
+ #ifdef KERNEL
+ #ifndef MIN
+ #define MIN(A,B) ((A) &lt; (B) ? (A) : (B))
+ #endif
+ #ifndef MAX
+ #define MAX(A,B) ((A) &gt; (B) ? (A) : (B))
+ #endif
+ #endif /* KERNEL */
+ 
+ #endif /* ! ASSEMBLER &amp; ! __LANGUAGE_ASSEMBLY__ */
+ #endif /* _KERNEL */
+ 
+ #else /* !defined(UKERNEL) */
+ 
+ /* This section for user space compiles only */
+ 
+ #define UKERNEL			1	/* user space kernel */
+ #define AFS_ENV			1
+ #define AFS_VFSINCL_ENV         1
+ #define AFS_USR_FBSD40_ENV	1
+ #define AFS_USR_FBSD42_ENV	1
+ #define AFS_USR_FBSD43_ENV	1
+ #define AFS_USR_FBSD44_ENV	1
+ #define AFS_USR_FBSD45_ENV	1
+ #define AFS_USR_FBSD46_ENV	1
+ #define AFS_USR_FBSD47_ENV	1
+ #define AFS_USR_FBSD50_ENV	1
+ #define AFS_USR_FBSD51_ENV	1
+ #define AFS_USR_FBSD52_ENV	1
+ #define AFS_USR_FBSD53_ENV	1
+ #define AFS_USR_FBSD60_ENV	1
+ #define AFS_USR_FBSD61_ENV	1
+ #define AFS_USR_FBSD_ENV	1
+ #define AFS_NONFSTRANS 1
+ 
+ #define AFS_MOUNT_AFS "afs"	/* The name of the filesystem type. */
+ #define AFS_SYSCALL 339
+ #define AFS_NAMEI_ENV         1	/* User space interface to file system */
+ #define AFS_64BIT_ENV 1
+ #define AFS_64BIT_IOPS_ENV    1	/* Needed for NAMEI */
+ #define AFS_USERSPACE_IP_ADDR 1
+ #define RXK_LISTENER_ENV      1
+ #define AFS_GCPAGS	      0	/* if nonzero, garbage collect PAGs */
+ 
+ #include &lt;afs/afs_sysnames.h&gt;
+ 
+ #define	afsio_iov	uio_iov
+ #define	afsio_iovcnt	uio_iovcnt
+ #define	afsio_offset	uio_offset
+ #define	afsio_seg	uio_segflg
+ #define	afsio_fmode	uio_fmode
+ #define	afsio_resid	uio_resid
+ #define	AFS_UIOSYS	1
+ #define	AFS_UIOUSER	UIO_USERSPACE
+ #define	AFS_CLBYTES	MCLBYTES
+ #define	AFS_MINCHANGE	2
+ #define	VATTR_NULL	usr_vattr_null
+ 
+ #define AFS_DIRENT
+ #ifndef CMSERVERPREF
+ #define CMSERVERPREF
+ #endif
+ 
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/types.h&gt;
+ #include &lt;sys/mount.h&gt;
+ #include &lt;sys/fcntl.h&gt;
+ #include &lt;sys/uio.h&gt;
+ #include &lt;sys/socket.h&gt;
+ #include &lt;netinet/in.h&gt;
+ #include &lt;limits.h&gt;
+ 
+ #endif /* !defined(UKERNEL) */
+ 
+ #endif /* AFS_PARAM_H */
Index: openafs/src/config/param.i386_linux26.h
diff -c openafs/src/config/param.i386_linux26.h:1.7 openafs/src/config/param.i386_linux26.h:1.8
*** openafs/src/config/param.i386_linux26.h:1.7	Mon May 23 17:04:14 2005
--- openafs/src/config/param.i386_linux26.h	Fri Mar 31 00:51:06 2006
***************
*** 86,91 ****
--- 86,96 ----
  #define SYS_NAME       "i386_linux26"
  #define SYS_NAME_ID    SYS_NAME_ID_i386_linux26
  
+ #ifdef __GLIBC__
+ #if (__GLIBC__ &gt; 2) || (__GLIBC__ == 2 &amp;&amp; __GLIBC_MINOR__ &gt; 3)
+ #define USE_UCONTEXT
+ #endif
+ #endif
  #endif /* AFS_PARAM_H */
  
  
Index: openafs/src/config/param.i386_obsd39.h
diff -c /dev/null openafs/src/config/param.i386_obsd39.h:1.1
*** /dev/null	Thu Apr 27 12:42:29 2006
--- openafs/src/config/param.i386_obsd39.h	Thu Mar  9 10:27:18 2006
***************
*** 0 ****
--- 1,69 ----
+ /*
+  * Jim Rees, University of Michigan CITI
+  */
+ 
+ #ifndef	AFS_PARAM_H
+ #define	AFS_PARAM_H
+ 
+ #ifndef IGNORE_STDS_H
+ #include &lt;sys/param.h&gt;
+ #endif
+ 
+ #define SYS_NAME		"i386_obsd39"
+ #define SYS_NAME_ID		SYS_NAME_ID_i386_obsd39
+ 
+ #define AFS_XBSD_ENV		1	/* {Free,Open,Net}BSD */
+ #define AFS_X86_XBSD_ENV	1
+ 
+ #define AFS_NAMEI_ENV		1	/* User space interface to file system */
+ #define AFS_64BIT_ENV		1
+ #define AFS_64BIT_CLIENT	1
+ #define AFS_64BIT_IOPS_ENV	1	/* Needed for NAMEI */
+ #define AFS_OBSD_ENV		1
+ #define AFS_OBSD34_ENV		1
+ #define AFS_OBSD35_ENV		1
+ #define AFS_OBSD36_ENV		1
+ #define AFS_OBSD37_ENV		1
+ #define AFS_OBSD38_ENV		1
+ #define AFS_OBSD39_ENV		1
+ #define AFS_NONFSTRANS		1
+ #define AFS_VM_RDWR_ENV		1
+ #define AFS_VFS_ENV		1
+ #define AFS_VFSINCL_ENV		1
+ 
+ #define FTRUNC O_TRUNC
+ 
+ #define AFS_SYSCALL		208
+ #define AFS_MOUNT_AFS		"afs"
+ 
+ #define RXK_LISTENER_ENV	1
+ #define AFS_GCPAGS	        0	/* if nonzero, garbage collect PAGs */
+ #define AFS_USE_GETTIMEOFDAY    1	/* use gettimeofday to implement rx clock */
+ 
+ #define AFSLITTLE_ENDIAN	1
+ 
+ #ifndef IGNORE_STDS_H
+ #include &lt;afs/afs_sysnames.h&gt;
+ #endif
+ 
+ /* Extra kernel definitions (from kdefs file) */
+ #ifdef _KERNEL
+ #ifdef MULTIPROCESSOR
+ #define AFS_GLOBAL_SUNLOCK	1
+ #endif
+ #define	AFS_SHORTGID		0	/* are group id's short? */
+ 
+ #if	!defined(ASSEMBLER) &amp;&amp; !defined(__LANGUAGE_ASSEMBLY__)
+ enum vcexcl { NONEXCL, EXCL };
+ 
+ #ifndef MIN
+ #define MIN(A,B) ((A) &lt; (B) ? (A) : (B))
+ #endif
+ #ifndef MAX
+ #define MAX(A,B) ((A) &gt; (B) ? (A) : (B))
+ #endif
+ 
+ #endif /* ! ASSEMBLER &amp; ! __LANGUAGE_ASSEMBLY__ */
+ #endif /* _KERNEL */
+ 
+ #endif /* AFS_PARAM_H */
Index: openafs/src/config/param.ppc_darwin_80.h
diff -c openafs/src/config/param.ppc_darwin_80.h:1.8 openafs/src/config/param.ppc_darwin_80.h:1.9
*** openafs/src/config/param.ppc_darwin_80.h:1.8	Mon Feb 13 13:29:37 2006
--- openafs/src/config/param.ppc_darwin_80.h	Thu Mar  9 01:34:35 2006
***************
*** 7,15 ****
  #define AFS_ENV                 1
  #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
  #define AFS_64BIT_CLIENT        1
! #define AFS_64BIT_IOPS_ENV 1
! #define AFS_PPC_ENV 1
! #define AFS_VFSINCL_ENV 1
  
  #include &lt;afs/afs_sysnames.h&gt;
  
--- 7,21 ----
  #define AFS_ENV                 1
  #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
  #define AFS_64BIT_CLIENT        1
! #define AFS_64BIT_IOPS_ENV	1
! #if defined(__ppc__)
! #define AFS_PPC_ENV		1
! #elif defined(__i386__)
! #define AFS_X86_ENV		1
! #else
! #error Unsupported architecture
! #endif
! #define AFS_VFSINCL_ENV		1
  
  #include &lt;afs/afs_sysnames.h&gt;
  
***************
*** 29,43 ****
  #define AFS_MOUNT_AFS    "afs"
  
  /* Machine / Operating system information */
! #define sys_ppc_darwin_12   1
! #define sys_ppc_darwin_13   1
! #define sys_ppc_darwin_14   1
! #define sys_ppc_darwin_60   1
! #define sys_ppc_darwin_70   1
! #define sys_ppc_darwin_80   1
! #define SYS_NAME        "ppc_darwin_80"
! #define SYS_NAME_ID     SYS_NAME_ID_ppc_darwin_80
! #define AFSBIG_ENDIAN   1
  #define AFS_HAVE_FFS    1	/* Use system's ffs. */
  
  #define AFS_GCPAGS               0
--- 35,63 ----
  #define AFS_MOUNT_AFS    "afs"
  
  /* Machine / Operating system information */
! #if defined(__ppc__)
! #define sys_ppc_darwin_12	1
! #define sys_ppc_darwin_13	1
! #define sys_ppc_darwin_14	1
! #define sys_ppc_darwin_60	1
! #define sys_ppc_darwin_70	1
! #define sys_ppc_darwin_80	1
! #define SYS_NAME		"ppc_darwin_80"
! #define SYS_NAME_ID		SYS_NAME_ID_ppc_darwin_80
! #define AFSBIG_ENDIAN		1
! #elif defined(__i386__)
! #define sys_x86_darwin_12	1
! #define sys_x86_darwin_13	1
! #define sys_x86_darwin_14	1
! #define sys_x86_darwin_60	1
! #define sys_x86_darwin_70	1
! #define sys_x86_darwin_80	1
! #define SYS_NAME		"x86_darwin_80"
! #define SYS_NAME_ID		SYS_NAME_ID_x86_darwin_80
! #define AFSLITTLE_ENDIAN	1
! #else
! #error Unsupported architecture
! #endif
  #define AFS_HAVE_FFS    1	/* Use system's ffs. */
  
  #define AFS_GCPAGS               0
***************
*** 83,89 ****
  #define AFS_VFSINCL_ENV 1	/* NOBODY uses this.... */
  #define AFS_ENV                 1
  #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
! #define AFS_PPC_ENV 1
  
  #include &lt;afs/afs_sysnames.h&gt;
  #define AFS_USERSPACE_ENV
--- 103,115 ----
  #define AFS_VFSINCL_ENV 1	/* NOBODY uses this.... */
  #define AFS_ENV                 1
  #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
! #if defined(__ppc__)
! #define AFS_PPC_ENV		1
! #elif defined(__i386__)
! #define AFS_X86_ENV		1
! #else
! #error Unsupported architecture
! #endif
  
  #include &lt;afs/afs_sysnames.h&gt;
  #define AFS_USERSPACE_ENV
***************
*** 101,115 ****
  #define AFS_MOUNT_AFS    "afs"
  
  /* Machine / Operating system information */
! #define sys_ppc_darwin_12   1
! #define sys_ppc_darwin_13   1
! #define sys_ppc_darwin_14   1
! #define sys_ppc_darwin_60   1
! #define sys_ppc_darwin_70   1
! #define sys_ppc_darwin_80   1
! #define SYS_NAME        "ppc_darwin_80"
! #define SYS_NAME_ID     SYS_NAME_ID_ppc_darwin_80
! #define AFSBIG_ENDIAN   1
  #define AFS_HAVE_FFS    1	/* Use system's ffs. */
  
  #define AFS_UIOSYS      UIO_SYSSPACE
--- 127,155 ----
  #define AFS_MOUNT_AFS    "afs"
  
  /* Machine / Operating system information */
! #if defined(__ppc__)
! #define sys_ppc_darwin_12	1
! #define sys_ppc_darwin_13	1
! #define sys_ppc_darwin_14	1
! #define sys_ppc_darwin_60	1
! #define sys_ppc_darwin_70	1
! #define sys_ppc_darwin_80	1
! #define SYS_NAME		"ppc_darwin_80"
! #define SYS_NAME_ID		SYS_NAME_ID_ppc_darwin_80
! #define AFSBIG_ENDIAN		1
! #elif defined(__i386__)
! #define sys_x86_darwin_12	1
! #define sys_x86_darwin_13	1
! #define sys_x86_darwin_14	1
! #define sys_x86_darwin_60	1
! #define sys_x86_darwin_70	1
! #define sys_x86_darwin_80	1
! #define SYS_NAME		"x86_darwin_80"
! #define SYS_NAME_ID		SYS_NAME_ID_x86_darwin_80
! #define AFSLITTLE_ENDIAN	1
! #else
! #error Unsupported architecture
! #endif
  #define AFS_HAVE_FFS    1	/* Use system's ffs. */
  
  #define AFS_UIOSYS      UIO_SYSSPACE
Index: openafs/src/config/param.ppc_darwin_90.h
diff -c /dev/null openafs/src/config/param.ppc_darwin_90.h:1.1
*** /dev/null	Thu Apr 27 12:42:29 2006
--- openafs/src/config/param.ppc_darwin_90.h	Thu Mar  9 01:38:23 2006
***************
*** 0 ****
--- 1,184 ----
+ #ifndef UKERNEL
+ /* This section for kernel libafs compiles only */
+ 
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ #define AFS_ENV                 1
+ #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
+ #define AFS_64BIT_CLIENT        1
+ #define AFS_64BIT_IOPS_ENV	1
+ #if defined(__ppc__)
+ #define AFS_PPC_ENV		1
+ #elif defined(__i386__)
+ #define AFS_X86_ENV		1
+ #else
+ #error Unsupported architecture
+ #endif
+ #define AFS_VFSINCL_ENV		1
+ 
+ #include &lt;afs/afs_sysnames.h&gt;
+ 
+ #define AFS_DARWIN_ENV
+ #define AFS_DARWIN13_ENV
+ #define AFS_DARWIN14_ENV
+ #define AFS_DARWIN60_ENV
+ #define AFS_DARWIN70_ENV
+ #define AFS_DARWIN80_ENV
+ #define AFS_DARWIN90_ENV
+ #define AFS_NONFSTRANS
+ #define AFS_SYSCALL             230
+ #define AFS_NAMEI_ENV 1
+ #define DARWIN_REFBASE 3
+ 
+ /* File system entry (used if mount.h doesn't define MOUNT_AFS */
+ #define AFS_MOUNT_AFS    "afs"
+ 
+ /* Machine / Operating system information */
+ #if defined(__ppc__)
+ #define sys_ppc_darwin_12	1
+ #define sys_ppc_darwin_13	1
+ #define sys_ppc_darwin_14	1
+ #define sys_ppc_darwin_60	1
+ #define sys_ppc_darwin_70	1
+ #define sys_ppc_darwin_80	1
+ #define sys_ppc_darwin_90	1
+ #define SYS_NAME		"ppc_darwin_90"
+ #define SYS_NAME_ID		SYS_NAME_ID_ppc_darwin_90
+ #define AFSBIG_ENDIAN		1
+ #elif defined(__i386__)
+ #define sys_x86_darwin_12	1
+ #define sys_x86_darwin_13	1
+ #define sys_x86_darwin_14	1
+ #define sys_x86_darwin_60	1
+ #define sys_x86_darwin_70	1
+ #define sys_x86_darwin_80	1
+ #define sys_x86_darwin_90	1
+ #define SYS_NAME		"x86_darwin_90"
+ #define SYS_NAME_ID		SYS_NAME_ID_x86_darwin_90
+ #define AFSLITTLE_ENDIAN	1
+ #else
+ #error Unsupported architecture
+ #endif
+ #define AFS_HAVE_FFS    1	/* Use system's ffs. */
+ 
+ #define AFS_GCPAGS               0
+ #define RXK_LISTENER_ENV         1
+ 
+ #ifdef KERNEL
+ #undef MACRO_BEGIN
+ #undef MACRO_END
+ #include &lt;kern/macro_help.h&gt;
+ #define AFS_GLOBAL_SUNLOCK        1
+ #define AFS_VFS34       1	/* What is VFS34??? */
+ #define afsio_iov       uio_iov
+ #define afsio_iovcnt    uio_iovcnt
+ #define afsio_offset    uio_offset
+ #define afsio_seg       uio_segflg
+ #define afsio_resid     uio_resid
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ #define AFS_CLBYTES     CLBYTES
+ #define osi_GetTime(x)  microtime(x)
+ #define AFS_KALLOC(x)   _MALLOC(x, M_TEMP, M_WAITOK)
+ #define AFS_KFREE(x,y)  _FREE(x,M_TEMP)
+ #define v_count         v_usecount
+ #define v_vfsp          v_mount
+ #define vfs_bsize       mnt_stat.f_bsize
+ #define vfs_fsid        mnt_stat.f_fsid
+ #define va_nodeid       va_fileid
+ #define vfs_vnodecovered mnt_vnodecovered
+ #define direct          dirent
+ 
+ #define BIND_8_COMPAT
+ 
+ #endif
+ #endif /* AFS_PARAM_H */
+ 
+ #else /* !defined(UKERNEL) */
+ 
+ /* This section for user space compiles only */
+ 
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ #define AFS_VFSINCL_ENV 1	/* NOBODY uses this.... */
+ #define AFS_ENV                 1
+ #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
+ #if defined(__ppc__)
+ #define AFS_PPC_ENV		1
+ #elif defined(__i386__)
+ #define AFS_X86_ENV		1
+ #else
+ #error Unsupported architecture
+ #endif
+ 
+ #include &lt;afs/afs_sysnames.h&gt;
+ #define AFS_USERSPACE_ENV
+ #define AFS_USR_DARWIN_ENV
+ #define AFS_USR_DARWIN13_ENV
+ #define AFS_USR_DARWIN14_ENV
+ #define AFS_USR_DARWIN60_ENV
+ #define AFS_USR_DARWIN70_ENV
+ #define AFS_USR_DARWIN80_ENV
+ #define AFS_USR_DARWIN90_ENV
+ #define AFS_NONFSTRANS
+ #define AFS_SYSCALL             230
+ #define DARWIN_REFBASE 0
+ 
+ /* File system entry (used if mount.h doesn't define MOUNT_AFS */
+ #define AFS_MOUNT_AFS    "afs"
+ 
+ /* Machine / Operating system information */
+ #if defined(__ppc__)
+ #define sys_ppc_darwin_12	1
+ #define sys_ppc_darwin_13	1
+ #define sys_ppc_darwin_14	1
+ #define sys_ppc_darwin_60	1
+ #define sys_ppc_darwin_70	1
+ #define sys_ppc_darwin_80	1
+ #define sys_ppc_darwin_90	1
+ #define SYS_NAME		"ppc_darwin_90"
+ #define SYS_NAME_ID		SYS_NAME_ID_ppc_darwin_90
+ #define AFSBIG_ENDIAN		1
+ #elif defined(__i386__)
+ #define sys_x86_darwin_12	1
+ #define sys_x86_darwin_13	1
+ #define sys_x86_darwin_14	1
+ #define sys_x86_darwin_60	1
+ #define sys_x86_darwin_70	1
+ #define sys_x86_darwin_80	1
+ #define sys_x86_darwin_90	1
+ #define SYS_NAME		"x86_darwin_90"
+ #define SYS_NAME_ID		SYS_NAME_ID_x86_darwin_90
+ #define AFSLITTLE_ENDIAN	1
+ #else
+ #error Unsupported architecture
+ #endif
+ #define AFS_HAVE_FFS    1	/* Use system's ffs. */
+ 
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ 
+ #define AFS_GCPAGS                0	/* if nonzero, garbage collect PAGs */
+ #define RXK_LISTENER_ENV          1
+ 
+ #define AFS_VFS34       1	/* What is VFS34??? */
+ #define afsio_iov       uio_iov
+ #define afsio_iovcnt    uio_iovcnt
+ #define afsio_offset    uio_offset
+ #define afsio_seg       uio_segflg
+ #define afsio_resid     uio_resid
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ #define        VATTR_NULL      usr_vattr_null
+ 
+ #define AFS_DIRENT
+ #ifndef CMSERVERPREF
+ #define CMSERVERPREF
+ #endif
+ 
+ #define BIND_8_COMPAT
+ #endif /* AFS_PARAM_H */
+ 
+ #endif /* !defined(UKERNEL) */
Index: openafs/src/config/param.rs_aix51.h
diff -c openafs/src/config/param.rs_aix51.h:1.6 openafs/src/config/param.rs_aix51.h:1.7
*** openafs/src/config/param.rs_aix51.h:1.6	Fri Aug  8 17:54:39 2003
--- openafs/src/config/param.rs_aix51.h	Fri Mar 17 14:54:39 2006
***************
*** 25,32 ****
  #ifdef AFS_NAMEI_ENV
  #define AFS_64BIT_IOPS_ENV	1
  #endif
- #define BITMAP_LATER		1
- #define FAST_RESTART		1
  
  #define AFS_HAVE_FLOCK_SYSID    1
  
--- 25,30 ----
Index: openafs/src/config/param.rs_aix52.h
diff -c openafs/src/config/param.rs_aix52.h:1.1 openafs/src/config/param.rs_aix52.h:1.2
*** openafs/src/config/param.rs_aix52.h:1.1	Wed Mar 24 03:38:15 2004
--- openafs/src/config/param.rs_aix52.h	Fri Mar 17 14:54:39 2006
***************
*** 26,33 ****
  #ifdef AFS_NAMEI_ENV
  #define AFS_64BIT_IOPS_ENV	1
  #endif
- #define BITMAP_LATER		1
- #define FAST_RESTART		1
  
  #define AFS_HAVE_FLOCK_SYSID    1
  
--- 26,31 ----
Index: openafs/src/config/param.rs_aix53.h
diff -c openafs/src/config/param.rs_aix53.h:1.1 openafs/src/config/param.rs_aix53.h:1.2
*** openafs/src/config/param.rs_aix53.h:1.1	Sun Apr 24 10:24:57 2005
--- openafs/src/config/param.rs_aix53.h	Fri Mar 17 14:54:39 2006
***************
*** 27,34 ****
  #ifdef AFS_NAMEI_ENV
  #define AFS_64BIT_IOPS_ENV	1
  #endif
- #define BITMAP_LATER		1
- #define FAST_RESTART		1
  
  #define AFS_HAVE_FLOCK_SYSID    1
  
--- 27,32 ----
Index: openafs/src/config/param.s390_linux26.h
diff -c /dev/null openafs/src/config/param.s390_linux26.h:1.1
*** /dev/null	Thu Apr 27 12:42:29 2006
--- openafs/src/config/param.s390_linux26.h	Wed Mar 15 11:15:07 2006
***************
*** 0 ****
--- 1,162 ----
+ #ifndef UKERNEL
+ /* This section for kernel libafs compiles only */
+ 
+ /*
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ 
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ /* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel,
+  * it's a judgment call. If something is obviously s390 specific, use that
+  * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2"
+  * in the sysname is the current version of the client. This takes into
+  * account the perferred OS user space configuration as well as the kernel.
+  */
+ 
+ #define AFS_LINUX20_ENV 1
+ #define AFS_LINUX22_ENV	1
+ #define AFS_LINUX24_ENV	1
+ #define AFS_LINUX26_ENV	1
+ #define AFS_S390_LINUX20_ENV    1
+ #define AFS_S390_LINUX22_ENV	1
+ #define AFS_S390_LINUX24_ENV	1
+ #define AFS_S390_LINUX26_ENV	1
+ #define AFS_NONFSTRANS 1
+ 
+ #define AFS_MOUNT_AFS "afs"	/* The name of the filesystem type. */
+ #define AFS_SYSCALL 137
+ #define AFS_64BIT_ENV	1
+ #define AFS_64BIT_CLIENT	1
+ #define AFS_64BIT_IOPS_ENV  1
+ #define AFS_NAMEI_ENV     1	/* User space interface to file system */
+ 
+ #if defined(__KERNEL__) &amp;&amp; !defined(KDUMP_KERNEL)
+ #include &lt;linux/threads.h&gt;
+ 
+ #include &lt;linux/config.h&gt;
+ #ifdef CONFIG_SMP
+ #undef CONFIG_SMP
+ #endif
+ /* Using "AFS_SMP" to map to however many #define's are required to get
+  * MP to compile for Linux
+  */
+ #ifdef AFS_SMP
+ #define CONFIG_SMP 1
+ #ifndef CONFIG_S390_LOCAL_APIC
+ #define CONFIG_S390_LOCAL_APIC 1
+ #endif
+ #ifndef __SMP__
+ #define __SMP__
+ #endif
+ #endif
+ #define AFS_GLOBAL_SUNLOCK
+ #if defined(MODULE) &amp;&amp; defined(CONFIG_MODVERSIONS)
+ #define MODVERSIONS
+ // #include &lt;linux/modversions.h&gt;
+ #endif
+ #endif /* __KERNEL__  &amp;&amp; !DUMP_KERNEL */
+ 
+ #include &lt;afs/afs_sysnames.h&gt;
+ 
+ #define AFS_USERSPACE_IP_ADDR 1
+ #define RXK_LISTENER_ENV 1
+ #define AFS_GCPAGS       2	/* Set to Userdisabled, allow sysctl to override */
+ 
+ /* Machine / Operating system information */
+ #define SYS_NAME	"s390_linux26"
+ #define SYS_NAME_ID	SYS_NAME_ID_s390_linux26
+ #define AFSBIG_ENDIAN    1
+ #define AFS_HAVE_FFS        1	/* Use system's ffs. */
+ #define AFS_HAVE_STATVFS    0	/* System doesn't support statvfs */
+ #define AFS_VM_RDWR_ENV	    1	/* read/write implemented via VM */
+ #define AFS_USE_GETTIMEOFDAY       1	/* use gettimeofday to implement rx clock */
+ 
+ #ifdef KERNEL
+ #ifndef MIN
+ #define MIN(A,B) ((A) &lt; (B) ? (A) : (B))
+ #endif
+ #ifndef MAX
+ #define MAX(A,B) ((A) &gt; (B) ? (A) : (B))
+ #endif
+ #endif /* KERNEL */
+ 
+ #endif /* AFS_PARAM_H */
+ 
+ #else /* !defined(UKERNEL) */
+ 
+ /* This section for user space compiles only */
+ 
+ /* 
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ /* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel,
+  * it's a judgment call. If something is obviously s390 specific, use that
+  * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2"
+  * in the sysname is the current version of the client. This takes into
+  * account the perferred OS user space configuration as well as the kernel.
+  */
+ 
+ #define UKERNEL			1	/* user space kernel */
+ #define AFS_ENV			1
+ #define AFS_USR_LINUX20_ENV     1
+ #define AFS_USR_LINUX22_ENV	1
+ #define AFS_USR_LINUX24_ENV	1
+ #define AFS_USR_LINUX26_ENV	1
+ #define AFS_NONFSTRANS 1
+ 
+ #define AFS_MOUNT_AFS "afs"	/* The name of the filesystem type. */
+ #define AFS_SYSCALL 137
+ #define AFS_64BIT_IOPS_ENV  1
+ #define AFS_NAMEI_ENV     1	/* User space interface to file system */
+ #include &lt;afs/afs_sysnames.h&gt;
+ 
+ #define AFS_USERSPACE_IP_ADDR 1
+ #define RXK_LISTENER_ENV 1
+ #define AFS_GCPAGS		0	/* if nonzero, garbage collect PAGs */
+ 
+ 
+ /* Machine / Operating system information */
+ #define SYS_NAME	"s390_linux26"
+ #define SYS_NAME_ID	SYS_NAME_ID_s390_linux26
+ #define AFSBIG_ENDIAN    1
+ #define AFS_HAVE_FFS        1	/* Use system's ffs. */
+ #define AFS_HAVE_STATVFS    0	/* System doesn't support statvfs */
+ #define AFS_VM_RDWR_ENV	    1	/* read/write implemented via VM */
+ 
+ #define	afsio_iov	uio_iov
+ #define	afsio_iovcnt	uio_iovcnt
+ #define	afsio_offset	uio_offset
+ #define	afsio_seg	uio_segflg
+ #define	afsio_fmode	uio_fmode
+ #define	afsio_resid	uio_resid
+ #define	AFS_UIOSYS	1
+ #define	AFS_UIOUSER	UIO_USERSPACE
+ #define	AFS_CLBYTES	MCLBYTES
+ #define	AFS_MINCHANGE	2
+ #define	VATTR_NULL	usr_vattr_null
+ 
+ #define AFS_DIRENT
+ #ifndef CMSERVERPREF
+ #define CMSERVERPREF
+ #endif
+ 
+ #endif /* AFS_PARAM_H */
+ 
+ #endif /* !defined(UKERNEL) */
Index: openafs/src/config/param.x86_darwin_80.h
diff -c openafs/src/config/param.x86_darwin_80.h:1.1 openafs/src/config/param.x86_darwin_80.h:1.2
*** openafs/src/config/param.x86_darwin_80.h:1.1	Fri Oct 21 00:46:28 2005
--- openafs/src/config/param.x86_darwin_80.h	Thu Mar  9 01:34:35 2006
***************
*** 8,13 ****
--- 8,20 ----
  #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
  #define AFS_64BIT_CLIENT        1
  #define AFS_64BIT_IOPS_ENV	1
+ #if defined(__ppc__)
+ #define AFS_PPC_ENV		1
+ #elif defined(__i386__)
+ #define AFS_X86_ENV		1
+ #else
+ #error Unsupported architecture
+ #endif
  #define AFS_VFSINCL_ENV		1
  
  #include &lt;afs/afs_sysnames.h&gt;
***************
*** 27,41 ****
  #define AFS_MOUNT_AFS    "afs"
  
  /* Machine / Operating system information */
! #define sys_x86_darwin_12   1
! #define sys_x86_darwin_13   1
! #define sys_x86_darwin_14   1
! #define sys_x86_darwin_60   1
! #define sys_x86_darwin_70   1
! #define sys_x86_darwin_80   1
! #define SYS_NAME        "x86_darwin_80"
! #define SYS_NAME_ID     SYS_NAME_ID_x86_darwin_80
! #define AFSLITTLE_ENDIAN   1
  #define AFS_HAVE_FFS    1	/* Use system's ffs. */
  
  #define AFS_GCPAGS               0
--- 34,62 ----
  #define AFS_MOUNT_AFS    "afs"
  
  /* Machine / Operating system information */
! #if defined(__ppc__)
! #define sys_ppc_darwin_12	1
! #define sys_ppc_darwin_13	1
! #define sys_ppc_darwin_14	1
! #define sys_ppc_darwin_60	1
! #define sys_ppc_darwin_70	1
! #define sys_ppc_darwin_80	1
! #define SYS_NAME		"ppc_darwin_80"
! #define SYS_NAME_ID		SYS_NAME_ID_ppc_darwin_80
! #define AFSBIG_ENDIAN		1
! #elif defined(__i386__)
! #define sys_x86_darwin_12	1
! #define sys_x86_darwin_13	1
! #define sys_x86_darwin_14	1
! #define sys_x86_darwin_60	1
! #define sys_x86_darwin_70	1
! #define sys_x86_darwin_80	1
! #define SYS_NAME		"x86_darwin_80"
! #define SYS_NAME_ID		SYS_NAME_ID_x86_darwin_80
! #define AFSLITTLE_ENDIAN	1
! #else
! #error Unsupported architecture
! #endif
  #define AFS_HAVE_FFS    1	/* Use system's ffs. */
  
  #define AFS_GCPAGS               0
***************
*** 81,87 ****
  #define AFS_VFSINCL_ENV 1	/* NOBODY uses this.... */
  #define AFS_ENV                 1
  #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
! #define AFS_X86_ENV 1
  
  #include &lt;afs/afs_sysnames.h&gt;
  #define AFS_USERSPACE_ENV
--- 102,114 ----
  #define AFS_VFSINCL_ENV 1	/* NOBODY uses this.... */
  #define AFS_ENV                 1
  #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
! #if defined(__ppc__)
! #define AFS_PPC_ENV		1
! #elif defined(__i386__)
! #define AFS_X86_ENV		1
! #else
! #error Unsupported architecture
! #endif
  
  #include &lt;afs/afs_sysnames.h&gt;
  #define AFS_USERSPACE_ENV
***************
*** 99,113 ****
  #define AFS_MOUNT_AFS    "afs"
  
  /* Machine / Operating system information */
! #define sys_x86_darwin_12   1
! #define sys_x86_darwin_13   1
! #define sys_x86_darwin_14   1
! #define sys_x86_darwin_60   1
! #define sys_x86_darwin_70   1
! #define sys_x86_darwin_80   1
! #define SYS_NAME        "x86_darwin_80"
! #define SYS_NAME_ID     SYS_NAME_ID_x86_darwin_80
! #define AFSLITTLE_ENDIAN   1
  #define AFS_HAVE_FFS    1	/* Use system's ffs. */
  
  #define AFS_UIOSYS      UIO_SYSSPACE
--- 126,154 ----
  #define AFS_MOUNT_AFS    "afs"
  
  /* Machine / Operating system information */
! #if defined(__ppc__)
! #define sys_ppc_darwin_12	1
! #define sys_ppc_darwin_13	1
! #define sys_ppc_darwin_14	1
! #define sys_ppc_darwin_60	1
! #define sys_ppc_darwin_70	1
! #define sys_ppc_darwin_80	1
! #define SYS_NAME		"ppc_darwin_80"
! #define SYS_NAME_ID		SYS_NAME_ID_ppc_darwin_80
! #define AFSBIG_ENDIAN		1
! #elif defined(__i386__)
! #define sys_x86_darwin_12	1
! #define sys_x86_darwin_13	1
! #define sys_x86_darwin_14	1
! #define sys_x86_darwin_60	1
! #define sys_x86_darwin_70	1
! #define sys_x86_darwin_80	1
! #define SYS_NAME		"x86_darwin_80"
! #define SYS_NAME_ID		SYS_NAME_ID_x86_darwin_80
! #define AFSLITTLE_ENDIAN	1
! #else
! #error Unsupported architecture
! #endif
  #define AFS_HAVE_FFS    1	/* Use system's ffs. */
  
  #define AFS_UIOSYS      UIO_SYSSPACE
Index: openafs/src/config/param.x86_darwin_90.h
diff -c /dev/null openafs/src/config/param.x86_darwin_90.h:1.1
*** /dev/null	Thu Apr 27 12:42:29 2006
--- openafs/src/config/param.x86_darwin_90.h	Thu Mar  9 01:38:23 2006
***************
*** 0 ****
--- 1,184 ----
+ #ifndef UKERNEL
+ /* This section for kernel libafs compiles only */
+ 
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ #define AFS_ENV                 1
+ #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
+ #define AFS_64BIT_CLIENT        1
+ #define AFS_64BIT_IOPS_ENV	1
+ #if defined(__ppc__)
+ #define AFS_PPC_ENV		1
+ #elif defined(__i386__)
+ #define AFS_X86_ENV		1
+ #else
+ #error Unsupported architecture
+ #endif
+ #define AFS_VFSINCL_ENV		1
+ 
+ #include &lt;afs/afs_sysnames.h&gt;
+ 
+ #define AFS_DARWIN_ENV
+ #define AFS_DARWIN13_ENV
+ #define AFS_DARWIN14_ENV
+ #define AFS_DARWIN60_ENV
+ #define AFS_DARWIN70_ENV
+ #define AFS_DARWIN80_ENV
+ #define AFS_DARWIN90_ENV
+ #define AFS_NONFSTRANS
+ #define AFS_SYSCALL             230
+ #define AFS_NAMEI_ENV 1
+ #define DARWIN_REFBASE 3
+ 
+ /* File system entry (used if mount.h doesn't define MOUNT_AFS */
+ #define AFS_MOUNT_AFS    "afs"
+ 
+ /* Machine / Operating system information */
+ #if defined(__ppc__)
+ #define sys_ppc_darwin_12	1
+ #define sys_ppc_darwin_13	1
+ #define sys_ppc_darwin_14	1
+ #define sys_ppc_darwin_60	1
+ #define sys_ppc_darwin_70	1
+ #define sys_ppc_darwin_80	1
+ #define sys_ppc_darwin_90	1
+ #define SYS_NAME		"ppc_darwin_90"
+ #define SYS_NAME_ID		SYS_NAME_ID_ppc_darwin_90
+ #define AFSBIG_ENDIAN		1
+ #elif defined(__i386__)
+ #define sys_x86_darwin_12	1
+ #define sys_x86_darwin_13	1
+ #define sys_x86_darwin_14	1
+ #define sys_x86_darwin_60	1
+ #define sys_x86_darwin_70	1
+ #define sys_x86_darwin_80	1
+ #define sys_x86_darwin_90	1
+ #define SYS_NAME		"x86_darwin_90"
+ #define SYS_NAME_ID		SYS_NAME_ID_x86_darwin_90
+ #define AFSLITTLE_ENDIAN	1
+ #else
+ #error Unsupported architecture
+ #endif
+ #define AFS_HAVE_FFS    1	/* Use system's ffs. */
+ 
+ #define AFS_GCPAGS               0
+ #define RXK_LISTENER_ENV         1
+ 
+ #ifdef KERNEL
+ #undef MACRO_BEGIN
+ #undef MACRO_END
+ #include &lt;kern/macro_help.h&gt;
+ #define AFS_GLOBAL_SUNLOCK        1
+ #define AFS_VFS34       1	/* What is VFS34??? */
+ #define afsio_iov       uio_iov
+ #define afsio_iovcnt    uio_iovcnt
+ #define afsio_offset    uio_offset
+ #define afsio_seg       uio_segflg
+ #define afsio_resid     uio_resid
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ #define AFS_CLBYTES     CLBYTES
+ #define osi_GetTime(x)  microtime(x)
+ #define AFS_KALLOC(x)   _MALLOC(x, M_TEMP, M_WAITOK)
+ #define AFS_KFREE(x,y)  _FREE(x,M_TEMP)
+ #define v_count         v_usecount
+ #define v_vfsp          v_mount
+ #define vfs_bsize       mnt_stat.f_bsize
+ #define vfs_fsid        mnt_stat.f_fsid
+ #define va_nodeid       va_fileid
+ #define vfs_vnodecovered mnt_vnodecovered
+ #define direct          dirent
+ 
+ #define BIND_8_COMPAT
+ 
+ #endif
+ #endif /* AFS_PARAM_H */
+ 
+ #else /* !defined(UKERNEL) */
+ 
+ /* This section for user space compiles only */
+ 
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ #define AFS_VFSINCL_ENV 1	/* NOBODY uses this.... */
+ #define AFS_ENV                 1
+ #define AFS_64BIT_ENV           1	/* Defines afs_int32 as int, not long. */
+ #if defined(__ppc__)
+ #define AFS_PPC_ENV		1
+ #elif defined(__i386__)
+ #define AFS_X86_ENV		1
+ #else
+ #error Unsupported architecture
+ #endif
+ 
+ #include &lt;afs/afs_sysnames.h&gt;
+ #define AFS_USERSPACE_ENV
+ #define AFS_USR_DARWIN_ENV
+ #define AFS_USR_DARWIN13_ENV
+ #define AFS_USR_DARWIN14_ENV
+ #define AFS_USR_DARWIN60_ENV
+ #define AFS_USR_DARWIN70_ENV
+ #define AFS_USR_DARWIN80_ENV
+ #define AFS_USR_DARWIN90_ENV
+ #define AFS_NONFSTRANS
+ #define AFS_SYSCALL             230
+ #define DARWIN_REFBASE 0
+ 
+ /* File system entry (used if mount.h doesn't define MOUNT_AFS */
+ #define AFS_MOUNT_AFS    "afs"
+ 
+ /* Machine / Operating system information */
+ #if defined(__ppc__)
+ #define sys_ppc_darwin_12	1
+ #define sys_ppc_darwin_13	1
+ #define sys_ppc_darwin_14	1
+ #define sys_ppc_darwin_60	1
+ #define sys_ppc_darwin_70	1
+ #define sys_ppc_darwin_80	1
+ #define sys_ppc_darwin_90	1
+ #define SYS_NAME		"ppc_darwin_90"
+ #define SYS_NAME_ID		SYS_NAME_ID_ppc_darwin_90
+ #define AFSBIG_ENDIAN		1
+ #elif defined(__i386__)
+ #define sys_x86_darwin_12	1
+ #define sys_x86_darwin_13	1
+ #define sys_x86_darwin_14	1
+ #define sys_x86_darwin_60	1
+ #define sys_x86_darwin_70	1
+ #define sys_x86_darwin_80	1
+ #define sys_x86_darwin_90	1
+ #define SYS_NAME		"x86_darwin_90"
+ #define SYS_NAME_ID		SYS_NAME_ID_x86_darwin_90
+ #define AFSLITTLE_ENDIAN	1
+ #else
+ #error Unsupported architecture
+ #endif
+ #define AFS_HAVE_FFS    1	/* Use system's ffs. */
+ 
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ 
+ #define AFS_GCPAGS                0	/* if nonzero, garbage collect PAGs */
+ #define RXK_LISTENER_ENV          1
+ 
+ #define AFS_VFS34       1	/* What is VFS34??? */
+ #define afsio_iov       uio_iov
+ #define afsio_iovcnt    uio_iovcnt
+ #define afsio_offset    uio_offset
+ #define afsio_seg       uio_segflg
+ #define afsio_resid     uio_resid
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ #define        VATTR_NULL      usr_vattr_null
+ 
+ #define AFS_DIRENT
+ #ifndef CMSERVERPREF
+ #define CMSERVERPREF
+ #endif
+ 
+ #define BIND_8_COMPAT
+ #endif /* AFS_PARAM_H */
+ 
+ #endif /* !defined(UKERNEL) */
Index: openafs/src/config/stds.h
diff -c openafs/src/config/stds.h:1.22 openafs/src/config/stds.h:1.23
*** openafs/src/config/stds.h:1.22	Sun May  8 01:59:58 2005
--- openafs/src/config/stds.h	Fri Mar 17 14:54:39 2006
***************
*** 56,63 ****
  typedef long long afs_int64;
  typedef unsigned long long afs_uint64;
  #endif
! #define ZeroInt64(a)       (a) = 0
  #define AssignInt64(a, b) *(b) = (a) 
  #define AddInt64(a,b,c) *(c) = (afs_int64)(a) + (afs_int64)(b)
  #define AddUInt64(a,b,c) *(c) = (afs_uint64)(a) + (afs_uint64)(b)
  #define SubtractInt64(a,b,c) *(c) = (afs_int64)(a) - (afs_int64)(b)
--- 56,71 ----
  typedef long long afs_int64;
  typedef unsigned long long afs_uint64;
  #endif
! #define ZeroInt64(a)       (a = 0)
  #define AssignInt64(a, b) *(b) = (a) 
+ #define IncInt64(a) (*(a))++
+ #define IncUInt64(a) (*(a))++
+ #define DecInt64(a) (*(a))--
+ #define DecUInt64(a) (*(a))--
+ #define GTInt64(a,b) ((a) &gt; (b))
+ #define GEInt64(a,b) ((a) &gt;= (b))
+ #define LEInt64(a,b) ((a) &lt;= (b))
+ #define LTInt64(a,b) ((a) &lt; (b))
  #define AddInt64(a,b,c) *(c) = (afs_int64)(a) + (afs_int64)(b)
  #define AddUInt64(a,b,c) *(c) = (afs_uint64)(a) + (afs_uint64)(b)
  #define SubtractInt64(a,b,c) *(c) = (afs_int64)(a) - (afs_int64)(b)
***************
*** 83,90 ****
      afs_uint32 low;
  };
  typedef struct u_Int64 afs_uint64;
! #define ZeroInt64(a) (a).high = (a).low = 0
  #define AssignInt64(a, b) (b)-&gt;high = (a).high; (b)-&gt;low = (a).low
  #define CompareInt64(a,b) (((afs_int32)(a).high - (afs_int32)(b).high) || (((a).high == (b).high) &amp;&amp; ((a).low - (b).low))) 
  #define AddInt64(a, b, c) {  afs_int64 _a, _b; _a = a; _b = b; (c)-&gt;low = _a.low + _b.low; (c)-&gt;high = _a.high + _b.high + ((c)-&gt;low &lt; _b.low); } 
  #define SubtractInt64(a, b, c) { afs_int64 _a, _b; _a = a; _b = b; (c)-&gt;low = _a.low - _b.low;  (c)-&gt;high = _a.high - _b.high - (_a.low &lt; _b.low); } 
--- 91,106 ----
      afs_uint32 low;
  };
  typedef struct u_Int64 afs_uint64;
! #define ZeroInt64(a) ((a).high = (a).low = 0)
  #define AssignInt64(a, b) (b)-&gt;high = (a).high; (b)-&gt;low = (a).low
+ #define IncInt64(a) ((++((a)-&gt;low)) ? 0 : (a)-&gt;high++ )
+ #define IncUInt64(a) ((++((a)-&gt;low)) ? 0 : (a)-&gt;high++ )
+ #define DecInt64(a) (((a)-&gt;low)-- ? 0 : (a)-&gt;high-- )
+ #define DecUInt64(a) (((a)-&gt;low)-- ? 0 : (a)-&gt;high-- )
+ #define GTInt64(a,b) (((a).high &gt; (b).high) || (((a).high == (b).high) &amp;&amp; ((a).low &gt; (b).low)))
+ #define GEInt64(a,b) (((a).high &gt; (b).high) || (((a).high == (b).high) &amp;&amp; ((a).low &gt;= (b).low)))
+ #define LEInt64(a,b) (((a).high &lt; (b).high) || (((a).high == (b).high) &amp;&amp; ((a).low &lt;= (b).low)))
+ #define LTInt64(a,b) (((a).high &lt; (b).high) || (((a).high == (b).high) &amp;&amp; ((a).low &lt; (b).low)))
  #define CompareInt64(a,b) (((afs_int32)(a).high - (afs_int32)(b).high) || (((a).high == (b).high) &amp;&amp; ((a).low - (b).low))) 
  #define AddInt64(a, b, c) {  afs_int64 _a, _b; _a = a; _b = b; (c)-&gt;low = _a.low + _b.low; (c)-&gt;high = _a.high + _b.high + ((c)-&gt;low &lt; _b.low); } 
  #define SubtractInt64(a, b, c) { afs_int64 _a, _b; _a = a; _b = b; (c)-&gt;low = _a.low - _b.low;  (c)-&gt;high = _a.high - _b.high - (_a.low &lt; _b.low); } 
***************
*** 246,249 ****
--- 262,270 ----
  };
  typedef struct afsUUID afsUUID;
  
+ /* for now, demand attach fileserver is only support on unix pthreads builds */
+ #if defined(DEMAND_ATTACH_ENABLE) &amp;&amp; defined(AFS_PTHREAD_ENV) &amp;&amp; !defined(AFS_NT40_ENV)
+ #define AFS_DEMAND_ATTACH_FS 1
+ #endif
+ 
  #endif /* OPENAFS_CONFIG_AFS_STDS_H */
Index: openafs/src/config/venus.h
diff -c openafs/src/config/venus.h:1.11 openafs/src/config/venus.h:1.12
*** openafs/src/config/venus.h:1.11	Sun May  8 02:16:47 2005
--- openafs/src/config/venus.h	Thu Mar 30 12:13:39 2006
***************
*** 181,185 ****
--- 181,186 ----
  #define VIOC_NEWALIAS		_CVICEIOCTL(1)	/* create new cell alias */
  #define VIOC_GETALIAS		_CVICEIOCTL(2)	/* get alias info */
  #define VIOC_CBADDR		_CVICEIOCTL(3)	/* push callback addr */
+ #define VIOC_DISCON		_CVICEIOCTL(5)	/* set/get discon mode */
  
  #endif /* AFS_VENUS_H */
Index: openafs/src/des/andrew-conf.h
diff -c openafs/src/des/andrew-conf.h:1.17 openafs/src/des/andrew-conf.h:1.18
*** openafs/src/des/andrew-conf.h:1.17	Sat Oct 15 10:42:23 2005
--- openafs/src/des/andrew-conf.h	Thu Mar  9 01:34:36 2006
***************
*** 37,43 ****
  #error unknown osf
  #endif
  #else
! #if	defined(AFS_X86_ENV)
  #include "conf-bsd-ncr.h"
  #else
  #ifdef AFS_NT40_ENV
--- 37,43 ----
  #error unknown osf
  #endif
  #else
! #if	defined(AFS_X86_ENV) &amp;&amp; !defined(AFS_DARWIN_ENV)
  #include "conf-bsd-ncr.h"
  #else
  #ifdef AFS_NT40_ENV
Index: openafs/src/des/conf-darwin.h
diff -c openafs/src/des/conf-darwin.h:1.1 openafs/src/des/conf-darwin.h:1.2
*** openafs/src/des/conf-darwin.h:1.1	Fri Oct 21 00:46:30 2005
--- openafs/src/des/conf-darwin.h	Thu Mar  9 01:34:36 2006
***************
*** 9,11 ****
--- 9,16 ----
  #error "MSBFIRST or LSBFIRST undefined"
  #endif
  #define MUSTALIGN
+ #if !defined(KERNEL) &amp;&amp; defined(AFS_DARWIN80_ENV)
+ extern int _darwin_swap_long_bytes_bit_number(afs_uint32 x);
+ extern char *_darwin_whichstr[];
+ extern int _darwin_which;
+ #endif /* !KERNEL &amp;&amp; AFS_DARWIN80_ENV */
Index: openafs/src/des/make_fp.c
diff -c openafs/src/des/make_fp.c:1.6 openafs/src/des/make_fp.c:1.7
*** openafs/src/des/make_fp.c:1.6	Tue Jul 15 19:15:00 2003
--- openafs/src/des/make_fp.c	Thu Mar  9 01:34:36 2006
***************
*** 12,18 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/make_fp.c,v 1.6 2003/07/15 23:15:00 shadow Exp $");
  
  #include &lt;mit-cpyright.h&gt;
  #include &lt;stdio.h&gt;
--- 12,18 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/make_fp.c,v 1.7 2006/03/09 06:34:36 shadow Exp $");
  
  #include &lt;mit-cpyright.h&gt;
  #include &lt;stdio.h&gt;
***************
*** 27,32 ****
--- 27,37 ----
  gen(FILE * stream)
  {
      register int i;
+ #ifdef AFS_DARWIN80_ENV
+     int j;
+ 
+ #define swap_long_bytes_bit_number _darwin_swap_long_bytes_bit_number
+ #endif /* AFS_DARWIN80_ENV */
  
      /* clear the output */
      fprintf(stream, "    L2 = 0; R2 = 0;\n");
***************
*** 41,46 ****
--- 46,57 ----
  #define SWAP(i,j) \
      swap_long_bytes_bit_number(swap_bit_pos_0_to_ansi((unsigned)i)-j)
  
+ #ifdef AFS_DARWIN80_ENV
+   for(j = 0;; j++) {
+     fprintf(stream, _darwin_whichstr[j]);
+     if (j == 2)
+ 	break;
+ #endif /* AFS_DARWIN80_ENV */
      /* first setup FP */
      fprintf(stream, "/* FP operations */\n/* first left to left */\n");
  
***************
*** 67,70 ****
--- 78,85 ----
      for (i = 32; i &lt;= 63; i++)
  	if (FP[i] &gt;= 32)
  	    test_set(stream, "R1", FP[i] - 32, "R2", SWAP(i, 32));
+ #ifdef AFS_DARWIN80_ENV
+     _darwin_which = !_darwin_which;
+   }
+ #endif /* AFS_DARWIN80_ENV */
  }
Index: openafs/src/des/make_ip.c
diff -c openafs/src/des/make_ip.c:1.7 openafs/src/des/make_ip.c:1.8
*** openafs/src/des/make_ip.c:1.7	Tue Jul 15 19:15:00 2003
--- openafs/src/des/make_ip.c	Thu Mar  9 01:34:36 2006
***************
*** 12,18 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/make_ip.c,v 1.7 2003/07/15 23:15:00 shadow Exp $");
  
  #include &lt;mit-cpyright.h&gt;
  #include &lt;stdio.h&gt;
--- 12,18 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/make_ip.c,v 1.8 2006/03/09 06:34:36 shadow Exp $");
  
  #include &lt;mit-cpyright.h&gt;
  #include &lt;stdio.h&gt;
***************
*** 31,40 ****
--- 31,51 ----
  gen(FILE * stream)
  {
      register int i;
+ #ifdef AFS_DARWIN80_ENV
+     int j;
+ 
+ #define swap_long_bytes_bit_number _darwin_swap_long_bytes_bit_number
+ #endif /* AFS_DARWIN80_ENV */
  
      /* clear the output */
      fprintf(stream, "    L2 = 0; R2 = 0;\n");
  
+ #ifdef AFS_DARWIN80_ENV
+   for(j = 0;; j++) {
+     fprintf(stream, _darwin_whichstr[j]);
+     if (j == 2)
+ 	break;
+ #endif /* AFS_DARWIN80_ENV */
      /* first setup IP */
      fprintf(stream, "/* IP operations */\n/* first left to left */\n");
  
***************
*** 60,64 ****
--- 71,79 ----
      for (i = 32; i &lt;= 63; i++)
  	if (IP[i] &gt;= 32)
  	    test_set(stream, "R1", SWAP(IP[i] - 32), "R2", i - 32);
+ #ifdef AFS_DARWIN80_ENV
+     _darwin_which = !_darwin_which;
+   }
+ #endif /* AFS_DARWIN80_ENV */
      exit(0);
  }
Index: openafs/src/des/make_p.c
diff -c openafs/src/des/make_p.c:1.5 openafs/src/des/make_p.c:1.6
*** openafs/src/des/make_p.c:1.5	Tue Jul 15 19:15:00 2003
--- openafs/src/des/make_p.c	Thu Mar  9 01:34:36 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/make_p.c,v 1.5 2003/07/15 23:15:00 shadow Exp $");
  
  #include &lt;mit-cpyright.h&gt;
  #include &lt;stdio.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/make_p.c,v 1.6 2006/03/09 06:34:36 shadow Exp $");
  
  #include &lt;mit-cpyright.h&gt;
  #include &lt;stdio.h&gt;
***************
*** 39,44 ****
--- 39,57 ----
      fprintf(stream, "    P_temp = R1;\n");
      fprintf(stream, "    P_temp_p = (unsigned char *) &amp;P_temp;\n");
  
+ #ifdef AFS_DARWIN80_ENV
+     fprintf(stream, "#if defined(__i386__)\n");
+     fprintf(stream, "    R2 = P_prime[0][*P_temp_p++];\n");
+     fprintf(stream, "    R2 |= P_prime[1][*P_temp_p++];\n");
+     fprintf(stream, "    R2 |= P_prime[2][*P_temp_p++];\n");
+     fprintf(stream, "    R2 |= P_prime[3][*P_temp_p];\n");
+     fprintf(stream, "#elif defined(__ppc__)\n");
+     fprintf(stream, "    R2 = P_prime[3][*P_temp_p++];\n");
+     fprintf(stream, "    R2 |= P_prime[2][*P_temp_p++];\n");
+     fprintf(stream, "    R2 |= P_prime[1][*P_temp_p++];\n");
+     fprintf(stream, "    R2 |= P_prime[0][*P_temp_p];\n");
+     fprintf(stream, "#else\n#error Unsupported architecture\n#endif\n");
+ #else /* !AFS_DARWIN80_ENV */
  #ifdef	LSBFIRST
      fprintf(stream, "    R2 = P_prime[0][*P_temp_p++];\n");
      fprintf(stream, "    R2 |= P_prime[1][*P_temp_p++];\n");
***************
*** 50,54 ****
--- 63,68 ----
      fprintf(stream, "    R2 |= P_prime[1][*P_temp_p++];\n");
      fprintf(stream, "    R2 |= P_prime[0][*P_temp_p];\n");
  #endif /* MSBFIRST */
+ #endif /* !AFS_DARWIN80_ENV */
  #endif /* BIG */
  }
Index: openafs/src/des/misc.c
diff -c openafs/src/des/misc.c:1.7 openafs/src/des/misc.c:1.8
*** openafs/src/des/misc.c:1.7	Tue Jul 15 19:15:00 2003
--- openafs/src/des/misc.c	Thu Mar  9 01:34:36 2006
***************
*** 14,20 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/misc.c,v 1.7 2003/07/15 23:15:00 shadow Exp $");
  
  #include &lt;mit-cpyright.h&gt;
  #ifndef KERNEL
--- 14,20 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/des/misc.c,v 1.8 2006/03/09 06:34:36 shadow Exp $");
  
  #include &lt;mit-cpyright.h&gt;
  #ifndef KERNEL
***************
*** 270,275 ****
--- 270,304 ----
  #endif /* MSBFIRST */
  }
  
+ #if !defined(KERNEL) &amp;&amp; defined(AFS_DARWIN80_ENV)
+ char *_darwin_whichstr[] = {
+     "#if defined(__ppc__)\n",
+     "#elif defined(__i386__)\n",
+     "#else\n#error architecture unsupported\n#endif\n"
+ };
+ int _darwin_which = 1;
+ 
+ int
+ _darwin_swap_long_bytes_bit_number(afs_uint32 x)
+ {
+     /*
+      * given a bit number (0-31) from a vax, swap the byte part of the
+      * bit number to change the byte ordering to mSBFIRST type
+      */
+ 
+     afs_uint32 y, z;
+ 
+     if (!_darwin_which)
+ 	return x;
+ 
+     y = x / 8;			/* initial byte component */
+     z = x % 8;			/* bit within byte */
+ 
+     x = (3 - y) * 8 + z;
+     return x;
+ }
+ #endif /* !KERNEL &amp;&amp; AFS_DARWIN80_ENV */
+ 
  void
  test_set(FILE * stream, const char *src, int testbit, const char *dest,
  	 int setbit)
Index: openafs/src/des/stats.h
diff -c openafs/src/des/stats.h:1.9 openafs/src/des/stats.h:1.10
*** openafs/src/des/stats.h:1.9	Tue May 31 09:23:54 2005
--- openafs/src/des/stats.h	Thu Mar  9 10:27:19 2006
***************
*** 106,111 ****
--- 106,112 ----
          } \
          rxkad_stats-&gt;stats_elem--; \
      END
+ #ifndef AFS_OBSD38_ENV
  #define ADD_RXKAD_STATS(stats_elem, inc_value) \
      BEGIN \
          rxkad_stats_t * rxkad_stats; \
***************
*** 124,129 ****
--- 125,135 ----
          } \
          rxkad_stats-&gt;stats_elem -= dec_value; \
      END
+ #else /* AFS_OBSD38_ENV */
+ /* segfaults but we don't know why */
+ #define ADD_RXKAD_STATS(stats_elem, inc_value)
+ #define SUB_RXKAD_STATS(stats_elem, dec_value)
+ #endif /* AFS_OBSD38_ENV */
  #else /* AFS_PTHREAD_ENV */
  #define INC_RXKAD_STATS(stats_elem) rxkad_stats.stats_elem++
  #define DEC_RXKAD_STATS(stats_elem) rxkad_stats.stats_elem--
Index: openafs/src/des/test/Makefile.in
diff -c openafs/src/des/test/Makefile.in:1.8 openafs/src/des/test/Makefile.in:1.9
*** openafs/src/des/test/Makefile.in:1.8	Tue Oct 15 23:58:36 2002
--- openafs/src/des/test/Makefile.in	Thu Mar  9 01:34:36 2006
***************
*** 1,7 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=-g -I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
  
  #  Test programs
  PROGS = \
--- 1,7 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=-g -I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS}
  
  #  Test programs
  PROGS = \
***************
*** 9,15 ****
  	testit \
  	verify
  
! LDFLAGS = ${XLDFLAGS}
  
  LIBS=\
  	${TOP_LIBDIR}/libdes.a \
--- 9,15 ----
  	testit \
  	verify
  
! LDFLAGS = ${XLDFLAGS} ${ARCHFLAGS}
  
  LIBS=\
  	${TOP_LIBDIR}/libdes.a \
Index: openafs/src/dir/test/Makefile.in
diff -c openafs/src/dir/test/Makefile.in:1.6 openafs/src/dir/test/Makefile.in:1.7
*** openafs/src/dir/test/Makefile.in:1.6	Mon Nov 11 16:23:15 2002
--- openafs/src/dir/test/Makefile.in	Thu Mar  9 01:34:37 2006
***************
*** 9,15 ****
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  LIBS = ${srcdir}/lib/libdir.a ${srcdir}/lib/util.a  ${srcdir}/lib/liblwp.a
! CFLAGS=${OPTMZ} -I${TOP_INCDIR} -I${srcdir} -I${TOP_OBJDIR}/src/config ${XCFLAGS}
  
  OBJS=test-salvage.o physio.o dtest.o
  
--- 9,15 ----
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  LIBS = ${srcdir}/lib/libdir.a ${srcdir}/lib/util.a  ${srcdir}/lib/liblwp.a
! CFLAGS=${OPTMZ} -I${TOP_INCDIR} -I${srcdir} -I${TOP_OBJDIR}/src/config ${XCFLAGS} ${ARCHFLAGS}
  
  OBJS=test-salvage.o physio.o dtest.o
  
Index: openafs/src/fsint/common.xg
diff -c openafs/src/fsint/common.xg:1.7 openafs/src/fsint/common.xg:1.8
*** openafs/src/fsint/common.xg:1.7	Sun Dec 18 00:41:19 2005
--- openafs/src/fsint/common.xg	Thu Mar  9 11:25:52 2006
***************
*** 143,148 ****
--- 143,149 ----
  const AFS_XSTATSCOLL_CALL_INFO = 0;	 /*FS call counting &amp; info*/
  const AFS_XSTATSCOLL_PERF_INFO = 1;	 /*FS performance info*/
  const AFS_XSTATSCOLL_FULL_PERF_INFO = 2; /*Full FS performance info*/
+ const AFS_XSTATSCOLL_CBSTATS = 3;	 /*Callback package counters */
  
  typedef afs_uint32 VolumeId;
  typedef afs_uint32 VolId;
Index: openafs/src/fsprobe/fsprobe_test.c
diff -c openafs/src/fsprobe/fsprobe_test.c:1.8 openafs/src/fsprobe/fsprobe_test.c:1.9
*** openafs/src/fsprobe/fsprobe_test.c:1.8	Tue Jul 15 19:15:09 2003
--- openafs/src/fsprobe/fsprobe_test.c	Thu Mar  9 01:34:38 2006
***************
*** 17,23 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/fsprobe/fsprobe_test.c,v 1.8 2003/07/15 23:15:09 shadow Exp $");
  
  #ifdef HAVE_STRING_H
  #include &lt;string.h&gt;
--- 17,23 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/fsprobe/fsprobe_test.c,v 1.9 2006/03/09 06:34:38 shadow Exp $");
  
  #ifdef HAVE_STRING_H
  #include &lt;string.h&gt;
***************
*** 171,177 ****
--- 171,181 ----
      /*
       * Fill in the socket array for bigbird, vice1, and vice2.
       */
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+     FSSktArray[0].sin_family = AF_INET;		/*Internet family */
+ #else
      FSSktArray[0].sin_family = htons(AF_INET);	/*Internet family */
+ #endif
      FSSktArray[0].sin_port = htons(7000);	/*FileServer port */
      he = hostutil_GetHostByName("servername1");
      if (he == NULL) {
***************
*** 180,186 ****
--- 184,194 ----
      }
      memcpy(&amp;(FSSktArray[0].sin_addr.s_addr), he-&gt;h_addr, 4);
  
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+     FSSktArray[1].sin_family = AF_INET;		/*Internet address family */
+ #else
      FSSktArray[1].sin_family = htons(AF_INET);	/*Internet address family */
+ #endif
      FSSktArray[1].sin_port = htons(7000);	/*FileServer port */
      he = hostutil_GetHostByName("servername2");
      if (he == NULL) {
***************
*** 189,195 ****
--- 197,207 ----
      }
      memcpy(&amp;(FSSktArray[1].sin_addr.s_addr), he-&gt;h_addr, 4);
  
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+     FSSktArray[2].sin_family = AF_INET;		/*Internet address family */
+ #else
      FSSktArray[2].sin_family = htons(AF_INET);	/*Internet address family */
+ #endif
      FSSktArray[2].sin_port = htons(7000);	/*FileServer port */
      he = hostutil_GetHostByName("servername3");
      if (he == NULL) {
Index: openafs/src/kauth/rebuild.c
diff -c openafs/src/kauth/rebuild.c:1.11 openafs/src/kauth/rebuild.c:1.13
*** openafs/src/kauth/rebuild.c:1.11	Tue Jul 15 19:15:17 2003
--- openafs/src/kauth/rebuild.c	Tue Apr  4 16:51:16 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/rebuild.c,v 1.11 2003/07/15 23:15:17 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;sys/stat.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/kauth/rebuild.c,v 1.13 2006/04/04 20:51:16 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;sys/stat.h&gt;
***************
*** 123,128 ****
--- 123,132 ----
      int i;
      char Time[100];
      struct tm *tm_p;
+     time_t tt;
+     time_t modification_time = entry-&gt;modification_time;
+     time_t change_password_time = entry-&gt;change_password_time;
+     time_t max_ticket_lifetime = entry-&gt;max_ticket_lifetime;
  
      printf("\n");
  
***************
*** 171,177 ****
      if (entry-&gt;flags &amp; KAFOLDKEYS)
  	return;
  
!     tm_p = localtime((time_t *) &amp; entry-&gt;user_expiration);
      if (tm_p)
  	strftime(Time, 100, "%m/%d/%Y %H:%M", tm_p);
  
--- 175,182 ----
      if (entry-&gt;flags &amp; KAFOLDKEYS)
  	return;
  
!     tt = entry-&gt;user_expiration;
!     tm_p = localtime(&amp;tt);
      if (tm_p)
  	strftime(Time, 100, "%m/%d/%Y %H:%M", tm_p);
  
***************
*** 202,213 ****
  	   (!entry-&gt;pwsums[0] &amp;&amp; !entry-&gt;pwsums[1]) ? "yes" : "no");
  
      printf("   Mod Time = %u: %s", entry-&gt;modification_time,
! 	   ctime((time_t *) &amp; entry-&gt;modification_time));
      printf("   Mod ID = %u\n", entry-&gt;modification_id);
      printf("   Change Password Time = %u: %s", entry-&gt;change_password_time,
! 	   ctime((time_t *) &amp; entry-&gt;change_password_time));
      printf("   Ticket lifetime = %u: %s", entry-&gt;max_ticket_lifetime,
! 	   ctime((time_t *) &amp; entry-&gt;max_ticket_lifetime));
      printf("   Key Version = %d\n", entry-&gt;key_version);
  
      printf("   Key = ");
--- 207,218 ----
  	   (!entry-&gt;pwsums[0] &amp;&amp; !entry-&gt;pwsums[1]) ? "yes" : "no");
  
      printf("   Mod Time = %u: %s", entry-&gt;modification_time,
! 	   ctime(&amp;modification_time));
      printf("   Mod ID = %u\n", entry-&gt;modification_id);
      printf("   Change Password Time = %u: %s", entry-&gt;change_password_time,
! 	   ctime(&amp;change_password_time));
      printf("   Ticket lifetime = %u: %s", entry-&gt;max_ticket_lifetime,
! 	   ctime(&amp;max_ticket_lifetime));
      printf("   Key Version = %d\n", entry-&gt;key_version);
  
      printf("   Key = ");
***************
*** 285,292 ****
      if (strcmp(flags, "") != 0)
  	fprintf(out, " -flags %s", &amp;flags[1]);
      if (entryp-&gt;user_expiration != 0xffffffff) {
! 	strftime(Time, 50, "%m/%d/%Y %H:%M",
! 		 localtime((time_t *) &amp; entryp-&gt;user_expiration));
  	fprintf(out, " -expiration '%s'", Time);
      }
      fprintf(out, " -lifetime %u", entryp-&gt;max_ticket_lifetime);
--- 290,297 ----
      if (strcmp(flags, "") != 0)
  	fprintf(out, " -flags %s", &amp;flags[1]);
      if (entryp-&gt;user_expiration != 0xffffffff) {
! 	time_t tt = entryp-&gt;user_expiration;
! 	strftime(Time, 50, "%m/%d/%Y %H:%M",localtime(&amp;tt));
  	fprintf(out, " -expiration '%s'", Time);
      }
      fprintf(out, " -lifetime %u", entryp-&gt;max_ticket_lifetime);
Index: openafs/src/kauth/test/Makefile.in
diff -c openafs/src/kauth/test/Makefile.in:1.6 openafs/src/kauth/test/Makefile.in:1.7
*** openafs/src/kauth/test/Makefile.in:1.6	Wed Oct 31 23:59:53 2001
--- openafs/src/kauth/test/Makefile.in	Thu Mar  9 01:34:39 2006
***************
*** 12,18 ****
  LDIRS= -L${DESTDIR}/lib -L${DESTDIR}/lib/afs -L..
  LIBS= -llwp -ldes -lrxkad -lauth -lcmd -lubik -lprot -lsys -lrx -lcom_err -lkauth
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS}
  
  
  # the only tests _known_ to work are multiklog and the tcl scripts.
--- 12,18 ----
  LDIRS= -L${DESTDIR}/lib -L${DESTDIR}/lib/afs -L..
  LIBS= -llwp -ldes -lrxkad -lauth -lcmd -lubik -lprot -lsys -lrx -lcom_err -lkauth
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS} ${ARCHFLAGS}
  
  
  # the only tests _known_ to work are multiklog and the tcl scripts.
Index: openafs/src/libacl/acl.h
diff -c openafs/src/libacl/acl.h:1.4 openafs/src/libacl/acl.h:1.5
*** openafs/src/libacl/acl.h:1.4	Fri Mar 25 12:58:47 2005
--- openafs/src/libacl/acl.h	Thu Feb 23 10:52:23 2006
***************
*** 62,65 ****
--- 62,77 ----
  
  typedef struct acl_accessList AL_AccessList;
  
+ extern int acl_NewACL(int nEntries, struct acl_accessList **acl);
+ extern int acl_FreeACL(struct acl_accessList **acl);
+ extern int acl_NewExternalACL(int nEntries, char **r);
+ extern int acl_FreeExternalACL(char **r);
+ extern int acl_Externalize(struct acl_accessList *acl, char **elist);
+ extern int acl_Internalize(char *elist, struct acl_accessList **acl);
+ extern int acl_Initialize(char *version);
+ #ifdef	_RXGEN_PTINT_
+ extern int acl_CheckRights(struct acl_accessList *acl, prlist *groups, int *rights);
+ extern int acl_IsAMember(afs_int32 aid, prlist *cps);
+ #endif
+ 
  #endif
Index: openafs/src/libacl/aclprocs.c
diff -c openafs/src/libacl/aclprocs.c:1.13 openafs/src/libacl/aclprocs.c:1.14
*** openafs/src/libacl/aclprocs.c:1.13	Sun Apr 18 02:13:49 2004
--- openafs/src/libacl/aclprocs.c	Thu Feb 23 10:52:23 2006
***************
*** 17,23 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/libacl/aclprocs.c,v 1.13 2004/04/18 06:13:49 kolya Exp $");
  
  #include &lt;sys/types.h&gt;
  #ifdef AFS_NT40_ENV
--- 17,23 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/libacl/aclprocs.c,v 1.14 2006/02/23 15:52:23 rees Exp $");
  
  #include &lt;sys/types.h&gt;
  #ifdef AFS_NT40_ENV
***************
*** 86,94 ****
  
  
  int
! acl_NewACL(nEntries, acl)
!      int nEntries;
!      struct acl_accessList **acl;
  {
      /* Creates an access list capable of holding at least nEntries entries.
       * Returns 0 on success; aborts if we run out of memory. */
--- 86,92 ----
  
  
  int
! acl_NewACL(int nEntries, struct acl_accessList **acl)
  {
      /* Creates an access list capable of holding at least nEntries entries.
       * Returns 0 on success; aborts if we run out of memory. */
***************
*** 119,126 ****
  
  
  int
! acl_FreeACL(acl)
!      struct acl_accessList **acl;
  {
      /* Releases the access list defined by acl.  Returns 0 always. */
      struct freeListEntry *x;
--- 117,123 ----
  
  
  int
! acl_FreeACL(struct acl_accessList **acl)
  {
      /* Releases the access list defined by acl.  Returns 0 always. */
      struct freeListEntry *x;
***************
*** 132,140 ****
  }
  
  int
! acl_NewExternalACL(nEntries, r)
!      int nEntries;
!      char **r;
  {
      /* Puts an external acl big enough to hold nEntries in r.  Returns 0 on success, aborts if insufficient memory. */
  
--- 129,135 ----
  }
  
  int
! acl_NewExternalACL(int nEntries, char **r)
  {
      /* Puts an external acl big enough to hold nEntries in r.  Returns 0 on success, aborts if insufficient memory. */
  
***************
*** 161,168 ****
  }
  
  int
! acl_FreeExternalACL(r)
!      char **r;
  {
      /* Releases the external access list defined by r.  Returns 0 always.  */
  
--- 156,162 ----
  }
  
  int
! acl_FreeExternalACL(char **r)
  {
      /* Releases the external access list defined by r.  Returns 0 always.  */
  
***************
*** 176,184 ****
  
  
  int
! acl_Externalize(acl, elist)
!      struct acl_accessList *acl;
!      char **elist;
  {
      /* Converts the access list defined by acl into the external access list in elist.  Non-translatable id's are converted to their ASCII string representations.  Returns 0 on success, -1 if number of entries exceeds ACL_MAXENTRIES, or a failure code from the protection server if the problem occured there. */
  
--- 170,176 ----
  
  
  int
! acl_Externalize(struct acl_accessList *acl, char **elist)
  {
      /* Converts the access list defined by acl into the external access list in elist.  Non-translatable id's are converted to their ASCII string representations.  Returns 0 on success, -1 if number of entries exceeds ACL_MAXENTRIES, or a failure code from the protection server if the problem occured there. */
  
***************
*** 236,244 ****
  
  
  int
! acl_Internalize(elist, acl)
!      char *elist;
!      struct acl_accessList **acl;
  {
      /* Converts the external access list elist into the access list acl.  Returns 0 on success, -1 if ANY name is not translatable, or if the number of entries exceeds al_maxExtEntries. */
      register int i;
--- 228,234 ----
  
  
  int
! acl_Internalize(char *elist, struct acl_accessList **acl)
  {
      /* Converts the external access list elist into the access list acl.  Returns 0 on success, -1 if ANY name is not translatable, or if the number of entries exceeds al_maxExtEntries. */
      register int i;
***************
*** 338,347 ****
  
  
  int
! acl_CheckRights(acl, groups, rights)
!      struct acl_accessList *acl;
!      prlist *groups;
!      int *rights;
  {
      /* Returns the rights given by acl to groups */
  
--- 328,334 ----
  
  
  int
! acl_CheckRights(struct acl_accessList *acl, prlist *groups, int *rights)
  {
      /* Returns the rights given by acl to groups */
  
***************
*** 412,419 ****
  }
  
  int
! acl_Initialize(version)
!      char *version;
  {
      /* I'm sure we need to do some initialization, I'm just not quite sure what yet! */
      if (strcmp(version, ACL_VERSION) != 0) {
--- 399,405 ----
  }
  
  int
! acl_Initialize(char *version)
  {
      /* I'm sure we need to do some initialization, I'm just not quite sure what yet! */
      if (strcmp(version, ACL_VERSION) != 0) {
***************
*** 428,436 ****
  }
  
  int
! acl_IsAMember(aid, cps)
!      afs_int32 aid;
!      prlist *cps;
  {
      afs_int32 i;
  
--- 414,420 ----
  }
  
  int
! acl_IsAMember(afs_int32 aid, prlist *cps)
  {
      afs_int32 i;
  
Index: openafs/src/libacl/test/Makefile.in
diff -c openafs/src/libacl/test/Makefile.in:1.6 openafs/src/libacl/test/Makefile.in:1.7
*** openafs/src/libacl/test/Makefile.in:1.6	Wed Oct 31 23:59:54 2001
--- openafs/src/libacl/test/Makefile.in	Thu Mar  9 01:34:40 2006
***************
*** 12,18 ****
  LDIRS=-L${TOP_LIBDIR} -L${DESTDIR}/lib/afs -L..
  LIBS= -lacl -lprot -lubik -lrx -llwp -lauth -lrxkad -lsys ${XLIBS}
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS}
  
  all: acltest
  
--- 12,18 ----
  LDIRS=-L${TOP_LIBDIR} -L${DESTDIR}/lib/afs -L..
  LIBS= -lacl -lprot -lubik -lrx -llwp -lauth -lrxkad -lsys ${XLIBS}
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS} ${ARCHFLAGS}
  
  all: acltest
  
Index: openafs/src/libafs/Makefile.common.in
diff -c openafs/src/libafs/Makefile.common.in:1.23 openafs/src/libafs/Makefile.common.in:1.24
*** openafs/src/libafs/Makefile.common.in:1.23	Sun Apr  3 15:02:32 2005
--- openafs/src/libafs/Makefile.common.in	Thu Mar  9 01:34:40 2006
***************
*** 47,55 ****
  	$(CC) $(COMMON_INCLUDE) $(CFLAGS) -P -c $&lt;
  
  .c.o:
! 	$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(KERN_DBG) -c $&lt;
! CRULE_NOOPT=	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(CFLAGS) -c $?
! CRULE_OPT=	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(KERN_OPTMZ) $(CFLAGS) -c $?
  
  system:	all
  
--- 47,55 ----
  	$(CC) $(COMMON_INCLUDE) $(CFLAGS) -P -c $&lt;
  
  .c.o:
! 	$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(CFLAGS-$@) $(KERN_DBG) -c $&lt;
! CRULE_NOOPT=	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(CFLAGS) $(CFLAGS-$@) -o $@ -c $?
! CRULE_OPT=	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(KERN_OPTMZ) $(CFLAGS) $(CFLAGS-$@) -o $@ -c $?
  
  system:	all
  
***************
*** 254,260 ****
  rx_rdwr.o: $(TOP_SRC_RX)/rx_rdwr.c
  	$(CRULE_OPT)
  afs_uuid.o: $(TOP_SRCDIR)/util/uuid.c
! 	$(CRULE_OPT) -o afs_uuid.o
  xdr_afsuuid.o: $(TOP_SRCDIR)/rx/xdr_afsuuid.c
  	$(CRULE_OPT)
  
--- 254,260 ----
  rx_rdwr.o: $(TOP_SRC_RX)/rx_rdwr.c
  	$(CRULE_OPT)
  afs_uuid.o: $(TOP_SRCDIR)/util/uuid.c
! 	$(CRULE_OPT)
  xdr_afsuuid.o: $(TOP_SRCDIR)/rx/xdr_afsuuid.c
  	$(CRULE_OPT)
  
***************
*** 268,274 ****
  afs_daemons.o: $(TOP_SRC_AFS)/afs_daemons.c
  	$(CRULE_NOOPT)
  afs_dir.o: 	$(TOP_SRCDIR)/dir/dir.c
! 	$(CRULE_NOOPT) -o afs_dir.o
  AFS_component_version_number.o: AFS_component_version_number.c
  	$(CRULE_NOOPT)
  afs_lock.o: $(TOP_SRC_AFS)/afs_lock.c
--- 268,274 ----
  afs_daemons.o: $(TOP_SRC_AFS)/afs_daemons.c
  	$(CRULE_NOOPT)
  afs_dir.o: 	$(TOP_SRCDIR)/dir/dir.c
! 	$(CRULE_NOOPT)
  AFS_component_version_number.o: AFS_component_version_number.c
  	$(CRULE_NOOPT)
  afs_lock.o: $(TOP_SRC_AFS)/afs_lock.c
***************
*** 337,344 ****
  	$(CRULE_NOOPT)
  Kvldbint.cs.o: ${TOP_OBJ_VLSERVER}/Kvldbint.cs.c
  	$(CRULE_NOOPT)
  Kvldbint.xdr.o: ${TOP_OBJ_VLSERVER}/Kvldbint.xdr.c
! 	$(CRULE_NOOPT) -DAFS_UUID_XG
  rx_kmutex.o: $(TOP_SRC_RX)/${MKAFS_OSTYPE}/rx_kmutex.c
  	$(CRULE_NOOPT)
  rx_knet.o: $(TOP_SRC_RX)/${MKAFS_OSTYPE}/rx_knet.c
--- 337,345 ----
  	$(CRULE_NOOPT)
  Kvldbint.cs.o: ${TOP_OBJ_VLSERVER}/Kvldbint.cs.c
  	$(CRULE_NOOPT)
+ CFLAGS-Kvldbint.xdr.o= -DAFS_UUID_XG
  Kvldbint.xdr.o: ${TOP_OBJ_VLSERVER}/Kvldbint.xdr.c
! 	$(CRULE_NOOPT)
  rx_kmutex.o: $(TOP_SRC_RX)/${MKAFS_OSTYPE}/rx_kmutex.c
  	$(CRULE_NOOPT)
  rx_knet.o: $(TOP_SRC_RX)/${MKAFS_OSTYPE}/rx_knet.c
***************
*** 347,362 ****
  	$(CRULE_NOOPT)
  
  # Files which do not contain NFS translator code.
  afs_call.o: $(TOP_SRC_AFS)/afs_call.c
! 	$(CRULE_NOOPT) -DAFS_NONFSTRANS
  afs_pioctl.o: $(TOP_SRC_AFS)/afs_pioctl.c
! 	$(CRULE_NOOPT) -DAFS_NONFSTRANS
  
  # NFS Translator versions of the above code.
  afs_call_nfs.o:	$(TOP_SRC_AFS)/afs_call.c
! 	$(CRULE_NOOPT) -o afs_call_nfs.o
  afs_pioctl_nfs.o:	$(TOP_SRC_AFS)/afs_pioctl.c
! 	$(CRULE_NOOPT) -o afs_pioctl_nfs.o
  
  # Files which are specific to particular architectures/targets
  # but have common build rules. Place here instead of duplicating
--- 348,365 ----
  	$(CRULE_NOOPT)
  
  # Files which do not contain NFS translator code.
+ CFLAGS-afs_call.o= -DAFS_NONFSTRANS
  afs_call.o: $(TOP_SRC_AFS)/afs_call.c
! 	$(CRULE_NOOPT)
! CFLAGS-afs_pioctl.o= -DAFS_NONFSTRANS
  afs_pioctl.o: $(TOP_SRC_AFS)/afs_pioctl.c
! 	$(CRULE_NOOPT)
  
  # NFS Translator versions of the above code.
  afs_call_nfs.o:	$(TOP_SRC_AFS)/afs_call.c
! 	$(CRULE_NOOPT)
  afs_pioctl_nfs.o:	$(TOP_SRC_AFS)/afs_pioctl.c
! 	$(CRULE_NOOPT)
  
  # Files which are specific to particular architectures/targets
  # but have common build rules. Place here instead of duplicating
***************
*** 371,384 ****
  	$(CRULE_NOOPT)
  osi_misc.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_misc.c
  	$(CRULE_NOOPT)
  osi_vfsops_nfs.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_vfsops.c
! 	$(CRULE_NOOPT) -o osi_vfsops_nfs.o \
! 	-DAFS_WRAPPER=${LIBAFS}_wrapper \
! 	-DAFS_CONF_DATA=${LIBAFS}_conf_data
  osi_vfsops.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_vfsops.c
! 	$(CRULE_NOOPT) -DAFS_NONFSTRANS \
! 	-DAFS_WRAPPER=${LIBAFSNONFS}_wrapper \
! 	-DAFS_CONF_DATA=${LIBAFSNONFS}_conf_data
  osi_vm.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_vm.c
  	$(CRULE_NOOPT)
  osi_vnodeops.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_vnodeops.c
--- 374,385 ----
  	$(CRULE_NOOPT)
  osi_misc.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_misc.c
  	$(CRULE_NOOPT)
+ CFLAGS-osi_vfsops_nfs.o= -DAFS_WRAPPER=${LIBAFS}_wrapper -DAFS_CONF_DATA=${LIBAFS}_conf_data
  osi_vfsops_nfs.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_vfsops.c
! 	$(CRULE_NOOPT)
! CFLAGS-osi_vfsops.o= -DAFS_NONFSTRANS -DAFS_WRAPPER=${LIBAFSNONFS}_wrapper -DAFS_CONF_DATA=${LIBAFSNONFS}_conf_data
  osi_vfsops.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_vfsops.c
! 	$(CRULE_NOOPT)
  osi_vm.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_vm.c
  	$(CRULE_NOOPT)
  osi_vnodeops.o: $(TOP_SRCDIR)/afs/$(MKAFS_OSTYPE)/osi_vnodeops.c
Index: openafs/src/libafs/MakefileProto.DARWIN.in
diff -c openafs/src/libafs/MakefileProto.DARWIN.in:1.26 openafs/src/libafs/MakefileProto.DARWIN.in:1.27
*** openafs/src/libafs/MakefileProto.DARWIN.in:1.26	Sat Oct 15 10:42:25 2005
--- openafs/src/libafs/MakefileProto.DARWIN.in	Thu Mar  9 01:34:40 2006
***************
*** 4,10 ****
  # This software has been released under the terms of the IBM Public
  # License.  For details, see the LICENSE file in the top-level source
  # directory or online at http://www.openafs.org/dl/license10.html
! # $Header: /cvs/openafs/src/libafs/MakefileProto.DARWIN.in,v 1.26 2005/10/15 14:42:25 shadow Exp $
  # 
  # MakefileProto for Digital Unix systems
  #
--- 4,10 ----
  # This software has been released under the terms of the IBM Public
  # License.  For details, see the LICENSE file in the top-level source
  # directory or online at http://www.openafs.org/dl/license10.html
! # $Header: /cvs/openafs/src/libafs/MakefileProto.DARWIN.in,v 1.27 2006/03/09 06:34:40 shadow Exp $
  # 
  # MakefileProto for Digital Unix systems
  #
***************
*** 33,46 ****
  KDEFS=
  DBUG = 
  DEFINES= -D_KERNEL -DKERNEL -DKERNEL_PRIVATE -DDIAGNOSTIC -DUSE_SELECT -DMACH_USER_API -DMACH_KERNEL
! &lt;x86_darwin_80&gt;
! KOPTS=-static -g -nostdinc -nostdlib -no-cpp-precomp -fno-builtin -finline -fno-keep-inline-functions -msoft-float -mlong-branch -fsigned-bitfields -arch i386 -Di386 -DI386 -D__I386__ -DPAGE_SIZE_FIXED -march=i686 -mpreferred-stack-boundary=2 -falign-functions=4
! MODLD=$(CC) $(KOPTS)
! &lt;ppc_darwin_80&gt;
! KOPTS=-static -g -nostdinc -nostdlib -no-cpp-precomp -fno-builtin -finline -fno-keep-inline-functions -msoft-float -mlong-branch -fsigned-bitfields -arch ppc -Dppc -DPPC -D__PPC__ -DPAGE_SIZE_FIXED -O2 -mcpu=750 -mmultiple -fschedule-insns
! MODLD=$(CC) $(KOPTS)
! &lt;all -ppc_darwin_80 -x86_darwin_80&gt;
  MODLD=$(LD)
  &lt;ppc_darwin_70&gt;
  KOPTS=-static -fno-common -finline -fno-keep-inline-functions -force_cpusubtype_ALL -msoft-float -mlong-branch 
  &lt;ppc_darwin_60&gt;
--- 33,67 ----
  KDEFS=
  DBUG = 
  DEFINES= -D_KERNEL -DKERNEL -DKERNEL_PRIVATE -DDIAGNOSTIC -DUSE_SELECT -DMACH_USER_API -DMACH_KERNEL
! &lt;ppc_darwin_80 x86_darwin_80 ppc_darwin_90 x86_darwin_90&gt;
! KOPTS_ppc=-static -g -nostdinc -nostdlib -fno-builtin -finline -fno-keep-inline-functions -msoft-float -mlong-branch -fsigned-bitfields -arch ppc -Dppc -DPPC -D__PPC__ -DPAGE_SIZE_FIXED -mcpu=750 -mmultiple -fschedule-insns
! KOPTS_x86=-static -g -nostdinc -nostdlib -fno-builtin -finline -fno-keep-inline-functions -msoft-float -mlong-branch -fsigned-bitfields -arch i386 -Di386 -DI386 -D__I386__ -DPAGE_SIZE_FIXED -march=i686 -mpreferred-stack-boundary=2 -falign-functions=4
! ARCH_ppc=$(shell echo "${ARCHFLAGS}" | grep -q -w ppc &amp;&amp; echo yes)
! ARCH_x86=$(shell echo "${ARCHFLAGS}" | grep -q -w i386 &amp;&amp; echo yes)
! ifeq ($(ARCH_ppc),yes)
! ifeq ($(ARCH_x86),yes)
! MODLD=$(CC) -static -g -nostdlib -arch ppc -arch i386
! CFLAGS_ppc=${KINCLUDES} -I. -I.. -I${TOP_OBJDIR}/src/config $(DEFINES) $(KDEFS) $(KOPTS_ppc)
! CFLAGS_x86=${KINCLUDES} -I. -I.. -I${TOP_OBJDIR}/src/config $(DEFINES) $(KDEFS) $(KOPTS_x86)
! else
! MODLD=$(CC) -static -g -nostdlib -arch ppc
! KOPTS=$(KOPTS_ppc)
! CFLAGS=${KINCLUDES} -I. -I.. -I${TOP_OBJDIR}/src/config $(DEFINES) $(KDEFS) $(KOPTS)
! endif
! else
! ifeq ($(ARCH_x86),yes)
! MODLD=$(CC) -static -g -nostdlib -arch i386
! KOPTS=$(KOPTS_x86)
! else
! _ARCH=$(shell arch)
! MODLD=$(CC) -static -g -nostdlib -arch $(_ARCH)
! KOPTS=$(KOPTS_$(shell echo $(_ARCH) | sed 's/i386/x86/'))
! endif
! CFLAGS=${KINCLUDES} -I. -I.. -I${TOP_OBJDIR}/src/config $(DEFINES) $(KDEFS) $(KOPTS)
! endif
! &lt;all -ppc_darwin_80 -x86_darwin_80 -ppc_darwin_90 -x86_darwin_90&gt;
  MODLD=$(LD)
+ CFLAGS=${KINCLUDES} -I. -I.. -I${TOP_OBJDIR}/src/config $(DEFINES) $(KDEFS) $(KOPTS)
  &lt;ppc_darwin_70&gt;
  KOPTS=-static -fno-common -finline -fno-keep-inline-functions -force_cpusubtype_ALL -msoft-float -mlong-branch 
  &lt;ppc_darwin_60&gt;
***************
*** 48,54 ****
  &lt;ppc_darwin_14 ppc_darwin_13 ppc_darwin_12&gt;
  KOPTS=-no-precomp -static -fno-common -finline -fno-keep-inline-functions -force_cpusubtype_ALL -msoft-float -mlong-branch 
  &lt;all&gt;
- CFLAGS=${KINCLUDES} -I. -I.. -I${TOP_OBJDIR}/src/config $(DEFINES) $(KDEFS) $(KOPTS) ${DBUG} ${OPTMZ}
  KINCLUDES=-I${KROOT}/System/Library/Frameworks/Kernel.framework/Headers
  
  
--- 69,74 ----
***************
*** 62,67 ****
--- 82,107 ----
  
  include Makefile.common
  
+ &lt;ppc_darwin_80 x86_darwin_80 ppc_darwin_90 x86_darwin_90&gt;
+ ifeq ($(ARCH_ppc),yes)
+ ifeq ($(ARCH_x86),yes)
+ # override suffix rule; unfortunately, this causes a warning message
+ .c.o:
+ 	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(CFLAGS_ppc) $(CFLAGS-$@) -o $(patsubst %.o,%.ppc.o,$@) -c $&lt;
+ 	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(CFLAGS_x86) $(CFLAGS-$@) -o $(patsubst %.o,%.x86.o,$@) -c $&lt;
+ 	lipo -create $(patsubst %.o,%.ppc.o,$@) $(patsubst %.o,%.x86.o,$@) -output $@
+ CRULE_NOOPT= \
+ 	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(CFLAGS_ppc) $(CFLAGS-$@) -o $(patsubst %.o,%.ppc.o,$@) -c $? &amp;&amp; \
+ 	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(CFLAGS_x86) $(CFLAGS-$@) -o $(patsubst %.o,%.x86.o,$@) -c $? &amp;&amp; \
+ 	lipo -create $(patsubst %.o,%.ppc.o,$@) $(patsubst %.o,%.x86.o,$@) -output $@
+ CRULE_OPT= \
+ 	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(KERN_OPTMZ) $(CFLAGS_ppc) $(CFLAGS-$@) -o $(patsubst %.o,%.ppc.o,$@) -c $? &amp;&amp; \
+ 	$(CC) $(COMMON_INCLUDE) $(KERN_DBG) $(KERN_OPTMZ) $(CFLAGS_x86) $(CFLAGS-$@) -o $(patsubst %.o,%.x86.o,$@) -c $? &amp;&amp; \
+ 	lipo -create $(patsubst %.o,%.ppc.o,$@) $(patsubst %.o,%.x86.o,$@) -output $@
+ endif
+ endif
+ &lt;all&gt;
+ 
  setup:
  	-mkdir $(KOBJ)
  	-$(RM) $(KOBJ)/Makefile $(KOBJ)/Makefile.common $(KOBJ)/config
Index: openafs/src/libafs/afs.ppc_darwin_90.plist.in
diff -c /dev/null openafs/src/libafs/afs.ppc_darwin_90.plist.in:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/libafs/afs.ppc_darwin_90.plist.in	Thu Mar  9 01:38:36 2006
***************
*** 0 ****
--- 1,33 ----
+ &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ &lt;!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"&gt;
+ &lt;plist version="0.9"&gt;
+ &lt;dict&gt;
+ 	&lt;key&gt;CFBundleDevelopmentRegion&lt;/key&gt;
+ 	&lt;string&gt;English&lt;/string&gt;
+ 	&lt;key&gt;CFBundleExecutable&lt;/key&gt;
+ 	&lt;string&gt;afs&lt;/string&gt;
+ 	&lt;key&gt;CFBundleIdentifier&lt;/key&gt;
+ 	&lt;string&gt;org.openafs.filesystems.afs&lt;/string&gt;
+ 	&lt;key&gt;CFBundleInfoDictionaryVersion&lt;/key&gt;
+ 	&lt;string&gt;8.0&lt;/string&gt;
+ 	&lt;key&gt;CFBundleName&lt;/key&gt;
+ 	&lt;string&gt;afs&lt;/string&gt;
+ 	&lt;key&gt;CFBundlePackageType&lt;/key&gt;
+ 	&lt;string&gt;KEXT&lt;/string&gt;
+ 	&lt;key&gt;CFBundleShortVersionString&lt;/key&gt;
+ 	&lt;string&gt;1.4.0&lt;/string&gt;
+ 	&lt;key&gt;CFBundleSignature&lt;/key&gt;
+ 	&lt;string&gt;????&lt;/string&gt;
+ 	&lt;key&gt;CFBundleVersion&lt;/key&gt;
+ 	&lt;string&gt;1.4.0&lt;/string&gt;
+ 	&lt;key&gt;OSBundleLibraries&lt;/key&gt;
+ 	&lt;dict&gt;
+ 		&lt;key&gt;com.apple.kpi.bsd&lt;/key&gt;
+ 		&lt;string&gt;8.0.0&lt;/string&gt;
+ 		&lt;key&gt;com.apple.kpi.mach&lt;/key&gt;
+ 		&lt;string&gt;8.0.0&lt;/string&gt;
+ 		&lt;key&gt;com.apple.kpi.libkern&lt;/key&gt;
+ 		&lt;string&gt;8.0&lt;/string&gt;
+ 	&lt;/dict&gt;
+ &lt;/dict&gt;
+ &lt;/plist&gt;
Index: openafs/src/libafs/afs.x86_darwin_90.plist.in
diff -c /dev/null openafs/src/libafs/afs.x86_darwin_90.plist.in:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/libafs/afs.x86_darwin_90.plist.in	Thu Mar  9 01:38:36 2006
***************
*** 0 ****
--- 1,33 ----
+ &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ &lt;!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"&gt;
+ &lt;plist version="0.9"&gt;
+ &lt;dict&gt;
+ 	&lt;key&gt;CFBundleDevelopmentRegion&lt;/key&gt;
+ 	&lt;string&gt;English&lt;/string&gt;
+ 	&lt;key&gt;CFBundleExecutable&lt;/key&gt;
+ 	&lt;string&gt;afs&lt;/string&gt;
+ 	&lt;key&gt;CFBundleIdentifier&lt;/key&gt;
+ 	&lt;string&gt;org.openafs.filesystems.afs&lt;/string&gt;
+ 	&lt;key&gt;CFBundleInfoDictionaryVersion&lt;/key&gt;
+ 	&lt;string&gt;8.0&lt;/string&gt;
+ 	&lt;key&gt;CFBundleName&lt;/key&gt;
+ 	&lt;string&gt;afs&lt;/string&gt;
+ 	&lt;key&gt;CFBundlePackageType&lt;/key&gt;
+ 	&lt;string&gt;KEXT&lt;/string&gt;
+ 	&lt;key&gt;CFBundleShortVersionString&lt;/key&gt;
+ 	&lt;string&gt;1.3.82&lt;/string&gt;
+ 	&lt;key&gt;CFBundleSignature&lt;/key&gt;
+ 	&lt;string&gt;????&lt;/string&gt;
+ 	&lt;key&gt;CFBundleVersion&lt;/key&gt;
+ 	&lt;string&gt;1.3.82&lt;/string&gt;
+ 	&lt;key&gt;OSBundleLibraries&lt;/key&gt;
+ 	&lt;dict&gt;
+ 		&lt;key&gt;com.apple.kpi.bsd&lt;/key&gt;
+ 		&lt;string&gt;8.0.0&lt;/string&gt;
+ 		&lt;key&gt;com.apple.kpi.mach&lt;/key&gt;
+ 		&lt;string&gt;8.0.0&lt;/string&gt;
+ 		&lt;key&gt;com.apple.kpi.libkern&lt;/key&gt;
+ 		&lt;string&gt;8.0&lt;/string&gt;
+ 	&lt;/dict&gt;
+ &lt;/dict&gt;
+ &lt;/plist&gt;
Index: openafs/src/libafsauthent/afsauthent.def
diff -c openafs/src/libafsauthent/afsauthent.def:1.4 openafs/src/libafsauthent/afsauthent.def:1.5
*** openafs/src/libafsauthent/afsauthent.def:1.4	Wed Dec  7 20:13:35 2005
--- openafs/src/libafsauthent/afsauthent.def	Thu Apr 20 13:19:22 2006
***************
*** 81,86 ****
      	pr_CreateUser                   		@80
      	pr_SNameToId                    		@81
  
- 
  	DISK_function_names				@83 DATA
  	VOTE_function_names				@84 DATA
--- 81,125 ----
      	pr_CreateUser                   		@80
      	pr_SNameToId                    		@81
  
  	DISK_function_names				@83 DATA
  	VOTE_function_names				@84 DATA
+ 
+         pr_End                                          @85
+         PR_INewEntry					@86
+         PR_WhereIsIt					@87
+         PR_DumpEntry					@88
+         PR_AddToGroup					@89
+         PR_NameToID					@90
+         PR_IDToName					@91
+         PR_Delete					@92
+         PR_RemoveFromGroup				@93
+         PR_GetCPS					@94
+         PR_NewEntry					@95
+         PR_ListMax					@96
+         PR_SetMax					@97
+         PR_ListEntry					@98
+         PR_ChangeEntry					@99
+         PR_ListElements					@100
+         PR_IsAMemberOf					@101
+         PR_SetFieldsEntry				@102
+         PR_ListOwned					@103
+         PR_GetCPS2					@104
+         PR_GetHostCPS					@105
+         PR_UpdateEntry					@106
+         PR_ListEntries					@107
+         PR_ListSuperGroups				@108
+ 	ka_AuthSpecificServersConn			@109
+ 	ka_KeyCheckSum					@110
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
Index: openafs/src/libuafs/MakefileProto.DARWIN.in
diff -c openafs/src/libuafs/MakefileProto.DARWIN.in:1.9 openafs/src/libuafs/MakefileProto.DARWIN.in:1.10
*** openafs/src/libuafs/MakefileProto.DARWIN.in:1.9	Sun Apr 18 02:10:33 2004
--- openafs/src/libuafs/MakefileProto.DARWIN.in	Thu Mar  9 01:34:41 2006
***************
*** 13,24 ****
  CC = cc
  DEFINES= -D_REENTRANT -DKERNEL -DUKERNEL
  KOPTS=
! CFLAGS=-I. -I.. -I${TOP_OBJDIR}/src/config ${FSINCLUDES} $(DEFINES) $(KOPTS) ${DBG} $(XCFLAGS)
! OPTF=-O
  # WEBOPTS = -I../nsapi -DNETSCAPE_NSAPI -DNET_SSL -DXP_UNIX -DMCC_HTTPD
  
! TEST_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV
! TEST_LDFLAGS=
  TEST_LIBS=
  
  LIBUAFS = libuafs.a
--- 13,24 ----
  CC = cc
  DEFINES= -D_REENTRANT -DKERNEL -DUKERNEL
  KOPTS=
! CFLAGS=-I. -I.. -I${TOP_OBJDIR}/src/config ${FSINCLUDES} $(DEFINES) $(KOPTS) ${DBG} $(XCFLAGS) $(ARCHFLAGS)
! OPTF=-Os
  # WEBOPTS = -I../nsapi -DNETSCAPE_NSAPI -DNET_SSL -DXP_UNIX -DMCC_HTTPD
  
! TEST_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV $(XCFLAGS) $(ARCHFLAGS)
! TEST_LDFLAGS=$(XLDFLAGS) $(ARCHFLAGS)
  TEST_LIBS=
  
  LIBUAFS = libuafs.a
Index: openafs/src/log/tokens.c
diff -c openafs/src/log/tokens.c:1.7 openafs/src/log/tokens.c:1.8
*** openafs/src/log/tokens.c:1.7	Sat Jun 18 19:20:35 2005
--- openafs/src/log/tokens.c	Wed Mar 15 13:27:43 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/log/tokens.c,v 1.7 2005/06/18 23:20:35 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #ifdef	AFS_AIX32_ENV
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/log/tokens.c,v 1.8 2006/03/15 18:27:43 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #ifdef	AFS_AIX32_ENV
***************
*** 54,60 ****
      time_t current_time;	/*Current time of day */
      time_t tokenExpireTime;	/*When token expires */
      char *expireString;		/*Char string of expiration time */
!     char UserName[16];		/*Printable user name */
      struct ktc_principal serviceName, clientName;	/* service name for ticket */
      struct ktc_token token;	/* the token we're printing */
  
--- 54,60 ----
      time_t current_time;	/*Current time of day */
      time_t tokenExpireTime;	/*When token expires */
      char *expireString;		/*Char string of expiration time */
!     char UserName[MAXKTCNAMELEN * 2 + 2]; /*Printable user name */
      struct ktc_principal serviceName, clientName;	/* service name for ticket */
      struct ktc_token token;	/* the token we're printing */
  
Index: openafs/src/log/test/Makefile.in
diff -c openafs/src/log/test/Makefile.in:1.6 openafs/src/log/test/Makefile.in:1.7
*** openafs/src/log/test/Makefile.in:1.6	Thu Nov  1 00:00:15 2001
--- openafs/src/log/test/Makefile.in	Thu Mar  9 01:34:42 2006
***************
*** 14,20 ****
  LDIRS=-L${TOP_LIBDIR} -L${DESTDIR}/lib/afs -L..
  LIBS= -lauth -lrxkad -ldes -lsys -lrx -llwp -lcmd -lafsutil ${XLIBS}
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS}
  
  all: testlog gettoktest
  
--- 14,20 ----
  LDIRS=-L${TOP_LIBDIR} -L${DESTDIR}/lib/afs -L..
  LIBS= -lauth -lrxkad -ldes -lsys -lrx -llwp -lcmd -lafsutil ${XLIBS}
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${LIBS} ${XCFLAGS} ${ARCHFLAGS}
  
  all: testlog gettoktest
  
Index: openafs/src/lwp/Makefile.in
diff -c openafs/src/lwp/Makefile.in:1.34 openafs/src/lwp/Makefile.in:1.35
*** openafs/src/lwp/Makefile.in:1.34	Sat Oct 15 10:42:27 2005
--- openafs/src/lwp/Makefile.in	Thu Mar  9 01:34:43 2006
***************
*** 10,16 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${LWP_DBG} ${LWP_OPTMZ} ${XCFLAGS} ${COMMON_INCL}
  
  LIBOBJS=lwp.o process.o lock.o iomgr.o timer.o fasttime.o preempt.o \
  	waitkey.o threadname.o AFS_component_version_number.o
--- 10,16 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${LWP_DBG} ${LWP_OPTMZ} ${XCFLAGS} ${ARCHFLAGS} ${COMMON_INCL}
  
  LIBOBJS=lwp.o process.o lock.o iomgr.o timer.o fasttime.o preempt.o \
  	waitkey.o threadname.o AFS_component_version_number.o
***************
*** 29,39 ****
  
  # This is required so sgi_64+ does not try to build this file.
  process.s:
! 	echo Nothing to be done for process.s
  
  # Making process.o for $(SYS_NAME)
  process.o	: process.s process.i386.s process.c
! 	@case "$(SYS_NAME)" in \
  	pmax_he1) \
  		$(CCOBJ) ${LWP_DBG} ${LWP_OPTMZ} -c -I${TOP_INCDIR} process.s;; \
  	sun4c_51 | sun4c_52 | sun4m_51 | sun4m_52 | sun4c_53 | sun4m_53  | sun4_53 | sun4_52 | sun4_54 | sun4c_54 | sun4m_54 | sun4x_5* ) \
--- 29,39 ----
  
  # This is required so sgi_64+ does not try to build this file.
  process.s:
! 	@echo Nothing to be done for process.s
  
  # Making process.o for $(SYS_NAME)
  process.o	: process.s process.i386.s process.c
! 	@set -x; case "$(SYS_NAME)" in \
  	pmax_he1) \
  		$(CCOBJ) ${LWP_DBG} ${LWP_OPTMZ} -c -I${TOP_INCDIR} process.s;; \
  	sun4c_51 | sun4c_52 | sun4m_51 | sun4m_52 | sun4c_53 | sun4m_53  | sun4_53 | sun4_52 | sun4_54 | sun4c_54 | sun4m_54 | sun4x_5* ) \
***************
*** 43,49 ****
  	sgi_5* ) \
  		$(CCOBJ) ${LWP_DBG} ${LWP_OPTMZ} -c -I${TOP_INCDIR} -KPIC -G0  ${srcdir}/process.s;; \
  	sgi_61 | sgi_62 | sgi_63 ) \
! 		$(CCOBJ) ${LWP_DBG} ${LWP_OPTMZ} -c ${XCFLAGS} -I${TOP_INCDIR} -KPIC -G0  ${srcdir}/process.s;; \
  	s390_*) \
  		/lib/cpp -P -I${TOP_INCDIR} ${srcdir}/process.s390.s &gt;process.ss; \
  		${AS} -ahlns process.ss -o process.o &gt;process.lst; \
--- 43,49 ----
  	sgi_5* ) \
  		$(CCOBJ) ${LWP_DBG} ${LWP_OPTMZ} -c -I${TOP_INCDIR} -KPIC -G0  ${srcdir}/process.s;; \
  	sgi_61 | sgi_62 | sgi_63 ) \
! 		$(CCOBJ) ${LWP_DBG} ${LWP_OPTMZ} -c ${XCFLAGS} ${ARCHFLAGS} -I${TOP_INCDIR} -KPIC -G0  ${srcdir}/process.s;; \
  	s390_*) \
  		/lib/cpp -P -I${TOP_INCDIR} ${srcdir}/process.s390.s &gt;process.ss; \
  		${AS} -ahlns process.ss -o process.o &gt;process.lst; \
***************
*** 52,63 ****
  		/lib/cpp -P -I${TOP_INCDIR} ${srcdir}/process.s390x.s &gt;process.ss; \
  		${AS} -ahlns process.ss -o process.o &gt;process.lst; \
  		$(RM) process.ss ;; \
! 	ppc_darwin* ) \
! 		$(CC) ${LWP_DBG} ${LWP_OPTMZ} -c ${XCFLAGS} -I${TOP_INCDIR} ${srcdir}/process.s;; \
! 	x86_darwin*) \
! 		/usr/bin/cpp -P -I${TOP_INCDIR} -I${srcdir} ${srcdir}/process.i386.s process.ss; \
! 		${AS} process.ss -o process.o; \
! 		$(RM) process.ss ;; \
  	i386_*bsd*) \
  		cp ${srcdir}/process.i386.s process.S ; \
  		${CCOBJ} -DIGNORE_STDS_H -E -I${srcdir} -I${TOP_INCDIR} process.S &gt; process.ss ; \
--- 52,82 ----
  		/lib/cpp -P -I${TOP_INCDIR} ${srcdir}/process.s390x.s &gt;process.ss; \
  		${AS} -ahlns process.ss -o process.o &gt;process.lst; \
  		$(RM) process.ss ;; \
! 	*_darwin* ) \
! 		ppc=`echo "${ARCHFLAGS}" | grep -q -w ppc &amp;&amp; echo yes` ; \
! 		i386=`echo "${ARCHFLAGS}" | grep -q -w i386 &amp;&amp; echo yes` ; \
! 		if [ -z "$${ppc}" -a -z "$${i386}" ] ; then \
! 			if [ `arch` = ppc ] ; then \
! 				ppc=yes ; \
! 			else \
! 				i386=yes ; \
! 			fi ; \
! 		fi ; \
! 		if [ -n "$${ppc}" ] ; then \
! 			$(CC) ${LWP_DBG} ${LWP_OPTMZ} -c -arch ppc -I${TOP_INCDIR} ${srcdir}/process.s -o process.ppc.o ; \
! 			if [ -z "$${i386}" ] ; then \
! 				${MV} process.ppc.o process.o ; \
! 			fi ; \
! 		fi ; \
! 		if [ -n "$${i386}" ] ; then \
! 			$(CC) -x assembler-with-cpp -c -arch i386 -I${TOP_INCDIR} -I${srcdir} ${srcdir}/process.i386.s -o process.i386.o ; \
! 			if [ -z "$${ppc}" ] ; then \
! 				${MV} process.i386.o process.o ; \
! 			fi ; \
! 		fi ; \
! 		if [ -n "$${ppc}" -a -n "$${i386}" ] ; then \
! 			lipo -create process.ppc.o process.i386.o -output process.o ;\
! 		fi ;; \
  	i386_*bsd*) \
  		cp ${srcdir}/process.i386.s process.S ; \
  		${CCOBJ} -DIGNORE_STDS_H -E -I${srcdir} -I${TOP_INCDIR} process.S &gt; process.ss ; \
Index: openafs/src/lwp/lwp.c
diff -c openafs/src/lwp/lwp.c:1.33 openafs/src/lwp/lwp.c:1.34
*** openafs/src/lwp/lwp.c:1.33	Sat Jun 18 19:20:45 2005
--- openafs/src/lwp/lwp.c	Thu Mar  9 01:34:43 2006
***************
*** 17,23 ****
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
! RCSID("$Header: /cvs/openafs/src/lwp/lwp.c,v 1.33 2005/06/18 23:20:45 shadow Exp $");
  
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
--- 17,23 ----
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
! RCSID("$Header: /cvs/openafs/src/lwp/lwp.c,v 1.34 2006/03/09 06:34:43 shadow Exp $");
  
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
***************
*** 80,85 ****
--- 80,87 ----
  #ifdef __s390__
  #define MINFRAME    96
  #define STACK_ALIGN 8
+ #elif defined(AFS_DARWIN_ENV)
+ #define STACK_ALIGN 16
  #else
  #define STACK_ALIGN 4
  #endif
***************
*** 297,303 ****
--- 299,309 ----
  	    return LWP_ENOMEM;
  	}
  	if (stacksize &lt; MINSTACK)
+ #ifdef AFS_DARWIN_ENV
+ 	    stacksize = 1008;
+ #else /* !AFS_DARWIN_ENV */
  	    stacksize = 1000;
+ #endif /* !AFS_DARWIN_ENV */
  	else
  	    stacksize =
  		STACK_ALIGN * ((stacksize + STACK_ALIGN - 1) / STACK_ALIGN);
***************
*** 342,353 ****
  	stackptr -= stacksize;
  	stackmemory = stackptr;
  #else
! 	if ((stackmemory = (char *)malloc(stacksize + 7)) == NULL) {
  	    Set_LWP_RC();
  	    return LWP_ENOMEM;
  	}
  	/* Round stack pointer to byte boundary */
  	stackptr = (char *)(8 * (((long)stackmemory + 7) / 8));
  #endif
  	if (priority &lt; 0 || priority &gt;= MAX_PRIORITIES) {
  	    Set_LWP_RC();
--- 348,368 ----
  	stackptr -= stacksize;
  	stackmemory = stackptr;
  #else
! #ifdef AFS_DARWIN_ENV
! 	if ((stackmemory = (char *)malloc(stacksize + STACK_ALIGN - 1)) == NULL)
! #else /* !AFS_DARWIN_ENV */
! 	if ((stackmemory = (char *)malloc(stacksize + 7)) == NULL)
! #endif /* !AFS_DARWIN_ENV */
! 	{
  	    Set_LWP_RC();
  	    return LWP_ENOMEM;
  	}
  	/* Round stack pointer to byte boundary */
+ #ifdef AFS_DARWIN_ENV
+ 	stackptr = (char *)(STACK_ALIGN * (((long)stackmemory + STACK_ALIGN - 1) / STACK_ALIGN));
+ #else /* !AFS_DARWIN_ENV */
  	stackptr = (char *)(8 * (((long)stackmemory + 7) / 8));
+ #endif /* !AFS_DARWIN_ENV */
  #endif
  	if (priority &lt; 0 || priority &gt;= MAX_PRIORITIES) {
  	    Set_LWP_RC();
***************
*** 372,379 ****
--- 387,398 ----
  		    stackptr + MINFRAME);
  #else
  #if defined(AFS_SGI62_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+ #ifdef sys_x86_darwin_80
+ 	savecontext(Create_Process_Part2, &amp;temp2-&gt;context, stackptr + stacksize - 16 - sizeof(void *));	/* 16 = 2 * jmp_buf_type */
+ #else /* !sys_x86_darwin_80 */
  	/* Need to have the sp on an 8-byte boundary for storing doubles. */
  	savecontext(Create_Process_Part2, &amp;temp2-&gt;context, stackptr + stacksize - 16);	/* 16 = 2 * jmp_buf_type */
+ #endif /* !sys_x86_darwin_80 */
  #else
  #if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV)
  	savecontext(Create_Process_Part2, &amp;temp2-&gt;context, stackptr + stacksize - 0x40);	/* lomgjmp does something
Index: openafs/src/lwp/process.c
diff -c openafs/src/lwp/process.c:1.21 openafs/src/lwp/process.c:1.23
*** openafs/src/lwp/process.c:1.21	Tue Feb  3 01:23:38 2004
--- openafs/src/lwp/process.c	Fri Mar 31 00:51:07 2006
***************
*** 13,19 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/lwp/process.c,v 1.21 2004/02/03 06:23:38 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;assert.h&gt;
--- 13,19 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/lwp/process.c,v 1.23 2006/03/31 05:51:07 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;assert.h&gt;
***************
*** 33,60 ****
  afs_int32
  savecontext(char (*ep) (), struct lwp_context *savearea, char *newsp)
  {
! #if defined(AFS_IA64_LINUX20_ENV)
!     register unsigned long sp __asm__("r12");
! #elif defined(AFS_AMD64_LINUX24_ENV)
!     register unsigned long sp __asm__("sp");
! #elif defined(AFS_HPUX1122_ENV)
! /* don't need anything special, will use
!  * ucontext.uc_stack.ss_sp as it matches r12.
!  * This should also work for Linux,
!  * but dont have system to test DEE
!  */
! #else
! #error	"You need to update stack pointer register for this platform"
  #endif
  
      PRE_Block = 1;
  
      savearea-&gt;state = 0;
      getcontext(&amp;savearea-&gt;ucontext);
! #if defined(AFS_HPUX1122_ENV)
!     savearea-&gt;topstack = savearea-&gt;ucontext.uc_stack.ss_sp;
  #else
!     savearea-&gt;topstack = sp;
  #endif
      switch (savearea-&gt;state) {
      case 0:
--- 33,51 ----
  afs_int32
  savecontext(char (*ep) (), struct lwp_context *savearea, char *newsp)
  {
! #if defined(AFS_LINUX20_ENV)
!     /* getcontext does not export stack info */
!     int stackvar;
  #endif
  
      PRE_Block = 1;
  
      savearea-&gt;state = 0;
      getcontext(&amp;savearea-&gt;ucontext);
! #if defined(AFS_LINUX20_ENV)
!     savearea-&gt;topstack = &amp;stackvar;
  #else
!     savearea-&gt;topstack = savearea-&gt;ucontext.uc_stack.ss_sp;
  #endif
      switch (savearea-&gt;state) {
      case 0:
***************
*** 98,104 ****
  # else
  #  define LWP_SP JB_SP
  # endif
! #elif	defined(AFS_HPUX_ENV)
  #define	LWP_SP	1
  #elif	defined(AFS_LINUX20_ENV)
  #if defined(AFS_PPC_LINUX20_ENV) || defined(AFS_PPC64_LINUX20_ENV)
--- 89,95 ----
  # else
  #  define LWP_SP JB_SP
  # endif
! #elif	defined(AFS_HPUX_ENV) || defined(AFS_PARISC_LINUX24_ENV)
  #define	LWP_SP	1
  #elif	defined(AFS_LINUX20_ENV)
  #if defined(AFS_PPC_LINUX20_ENV) || defined(AFS_PPC64_LINUX20_ENV)
Index: openafs/src/lwp/test/Makefile.in
diff -c openafs/src/lwp/test/Makefile.in:1.3 openafs/src/lwp/test/Makefile.in:1.4
*** openafs/src/lwp/test/Makefile.in:1.3	Thu Nov  1 00:00:20 2001
--- openafs/src/lwp/test/Makefile.in	Thu Mar  9 01:34:45 2006
***************
*** 11,17 ****
  INCDIRS= -I.. -I${DESTDIR}/include 
  LIBS= ../liblwp.a
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${XCFLAGS}
  
  system noversion: test
  
--- 11,17 ----
  INCDIRS= -I.. -I${DESTDIR}/include 
  LIBS= ../liblwp.a
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${LDIRS} ${XCFLAGS} ${ARCHFLAGS}
  
  system noversion: test
  
Index: openafs/src/lwp/test/selsubs.c
diff -c openafs/src/lwp/test/selsubs.c:1.8 openafs/src/lwp/test/selsubs.c:1.9
*** openafs/src/lwp/test/selsubs.c:1.8	Tue Jul 15 19:15:47 2003
--- openafs/src/lwp/test/selsubs.c	Mon Mar 20 08:41:03 2006
***************
*** 29,35 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/lwp/test/selsubs.c,v 1.8 2003/07/15 23:15:47 shadow Exp $");
  
  
  #include "lwp.h"
--- 29,35 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/lwp/test/selsubs.c,v 1.9 2006/03/20 13:41:03 jaltman Exp $");
  
  
  #include "lwp.h"
***************
*** 150,155 ****
--- 150,156 ----
      struct timeval now;
      struct timezone tz;
      struct tm *ltime;
+     time_t tt;
      int code;
      PROCESS pid;
      extern char *program;
***************
*** 157,163 ****
      code = gettimeofday(&amp;now, &amp;tz);
      assert(code == 0);
  
!     ltime = localtime((time_t *) &amp; now.tv_sec);
  
      LWP_CurrentProcess(&amp;pid);
      fprintf(stderr, "%s 0x%x %02d:%02d:%02d.%d: ", program ? program : "",
--- 158,165 ----
      code = gettimeofday(&amp;now, &amp;tz);
      assert(code == 0);
  
!     tt = now.tv_sec;
!     ltime = localtime(&amp;tt);
  
      LWP_CurrentProcess(&amp;pid);
      fprintf(stderr, "%s 0x%x %02d:%02d:%02d.%d: ", program ? program : "",
Index: openafs/src/package/update.c
diff -c openafs/src/package/update.c:1.4 openafs/src/package/update.c:1.5
*** openafs/src/package/update.c:1.4	Wed Jun 23 10:27:40 2004
--- openafs/src/package/update.c	Tue Apr  4 16:51:17 2006
***************
*** 382,389 ****
      tm[0].tv_usec = tm[1].tv_usec = 0;
      if (!opt_silent) {
  	char *date;
  
! 	date = ctime((time_t *) &amp; np-&gt;mtime);
  	date[24] = 0;
  	loudonly_message("utimes %s [%s]", path, date);
      }
--- 382,390 ----
      tm[0].tv_usec = tm[1].tv_usec = 0;
      if (!opt_silent) {
  	char *date;
+ 	time_t mtime = np-&gt;mtime;
  
! 	date = ctime(&amp;mtime);
  	date[24] = 0;
  	loudonly_message("utimes %s [%s]", path, date);
      }
Index: openafs/src/packaging/Debian/CellServDB
diff -c /dev/null openafs/src/packaging/Debian/CellServDB:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/CellServDB	Thu Mar 23 15:19:06 2006
***************
*** 0 ****
--- 1,559 ----
+ &gt;grand.central.org      #GCO Public CellServDB 15 Oct 2005
+ 18.7.14.88                      #grand-opening.mit.edu
+ 128.2.191.224                   #penn.central.org
+ 130.237.48.87                   #andrew.e.kth.se
+ &gt;wu-wien.ac.at          #University of Economics, Vienna, Austria
+ 137.208.3.33                    #afsdb1.wu-wien.ac.at
+ 137.208.8.12                    #caesar.wu-wien.ac.at
+ 137.208.127.33                  #buddy.wu-wien.ac.at
+ &gt;hephy.at               #hephy-vienna
+ 193.170.243.10                  #mowgli.oeaw.ac.at
+ 193.170.243.12                  #baloo.oeaw.ac.at
+ 193.170.243.14                  #akela.oeaw.ac.at
+ &gt;itp.tugraz.at          #Institute for Theoretical Physics, TU Graz, Austria
+ 129.27.157.6                    #fubphsv2.tu-graz.ac.at
+ 129.27.161.7                    #faepsv01.tu-graz.ac.at
+ 129.27.161.15                   #faepsv02.tu-graz.ac.at
+ &gt;cern.ch                #European Laboratory for Particle Physics, Geneva
+ 137.138.128.148                 #afsdb1.cern.ch
+ 137.138.246.50                  #afsdb3.cern.ch
+ 137.138.246.51                  #afsdb2.cern.ch
+ &gt;ams.cern.ch            #AMS Experiment
+ 137.138.206.77                  #pcamsf2.cern.ch
+ 137.138.206.123                 #pcamsf4.cern.ch
+ &gt;epfl.ch                #Swiss Federal Institute of Technology at Lausanne
+ 128.178.2.6                     #kd1.epfl.ch
+ 128.178.2.7                     #kd2.epfl.ch
+ 128.178.2.8                     #kd3.epfl.ch
+ &gt;ethz.ch                #Swiss Federal Inst. of Tech. - Zurich, Switzerland
+ 129.132.97.19                   #amalthea.ethz.ch
+ 129.132.97.27                   #nethzafs-001.ethz.ch
+ 129.132.115.3                   #himalia.ethz.ch
+ 129.132.115.37                  #nethzafs-005.ethz.ch
+ 129.132.115.38                  #nethzafs-006.ethz.ch
+ &gt;psi.ch                 #Paul Scherrer Institut - Villigen, Switzerland
+ 129.129.190.140                 #afs00.psi.ch
+ 129.129.190.141                 #afs01.psi.ch
+ 129.129.190.142                 #afs02.psi.ch
+ &gt;extundo.com            #Simon Josefsson's cell
+ 195.42.214.241                  #slipsten.extundo.com
+ &gt;mekinok.com            #Mekinok, Inc.
+ 4.36.43.98                      #loggerhead.mekinok.com
+ &gt;membrain.com           #membrain.com
+ 66.93.118.125                   #stormy
+ 130.85.24.11                    #weasel
+ 130.85.24.13                    #straykitten
+ &gt;midnightlinux.com      #Midnight Linux, Pittsburgh PA
+ 208.10.142.82                   #outpost.midnightlinux.com
+ &gt;setfilepointer.com     #SetFilePointer.com
+ 63.224.10.2                     #hamlet.SetFilePointer.com
+ 63.224.10.4                     #troilus.SetFilePointer.com
+ &gt;sodre.cx               #Sodre.cx
+ 128.8.140.165                   #greed.sodre.cx
+ &gt;desy.de                #Deutsches Elektronen-Synchrotron
+ 131.169.40.62                   #vayu.desy.de
+ 131.169.244.60                  #solar00.desy.de
+ &gt;gppc.de                #GPP Chemnitz mbH
+ 213.187.92.33                   #gpp1.gppc.de
+ 213.187.92.34                   #paulchen.gppc.de
+ 213.187.92.35                   #lotus.gppc.de
+ &gt;ifh.de                 #DESY Zeuthen
+ 141.34.22.10                    #romulus.ifh.de
+ 141.34.22.11                    #remus.ifh.de
+ 141.34.22.29                    #hekate.ifh.de
+ &gt;lrz-muenchen.de        #Leibniz Computing Centre, Germany
+ 129.187.10.36                   #afs1.lrz-muenchen.de
+ 129.187.10.56                   #afs3.lrz-muenchen.de
+ 129.187.10.57                   #afs2.lrz-muenchen.de
+ &gt;ipp-garching.mpg.de    #Institut fuer Plasmaphysik
+ 130.183.9.5                     #afs-db1.rzg.mpg.de
+ 130.183.100.10                  #afs-db2.aug.ipp-garching.mpg.de
+ 130.183.100.23                  #afs-db3.aug.ipp-garching.mpg.de
+ &gt;mpe.mpg.de             #MPE cell
+ 130.183.130.7                   #irafs1.mpe-garching.mpg.de
+ 130.183.134.20                  #irafs2.mpe-garching.mpg.de
+ &gt;i1.informatik.rwth-aachen.de #Informatik I, RWTH Aachen
+ 137.226.244.79                  #remus.informatik.rwth-aachen.de
+ &gt;tu-bs.de               #Technical University of Braunschweig, Germany
+ 134.169.1.1                     #rzafs1.rz.tu-bs.de
+ 134.169.1.5                     #rzafs2.rz.tu-bs.de
+ 134.169.1.6                     #rzafs3.rz.tu-bs.de
+ &gt;tu-chemnitz.de         #Technische Universitaet Chemnitz, Germany
+ 134.109.2.1                     #zuse.hrz.tu-chemnitz.de
+ 134.109.2.15                    #phoenix.hrz.tu-chemnitz.de
+ 134.109.200.7                   #aetius.hrz.tu-chemnitz.de
+ &gt;e18.ph.tum.de          #Experimental Physics, TU Munich, Germany
+ 129.187.154.223                 #hamlet.e18.physik.tu-muenchen.de
+ &gt;uni-bonn.de            #University of Bonn, Computing Center
+ 131.220.14.198                  #work15-eth.rhrz.uni-bonn.de
+ 131.220.14.205                  #node05.rhrz.uni-bonn.de
+ 131.220.15.197                  #afs-db1.rhrz.uni-bonn.de
+ &gt;atlass01.physik.uni-bonn.de #Bonn ATLAS
+ 131.220.165.43                  #atlass01.physik.uni-bonn.de
+ &gt;uni-freiburg.de        #Albert-Ludwigs-Universitat Freiburg
+ 132.230.6.235                   #sv6.ruf.uni-freiburg.de
+ 132.230.6.236                   #sv7.ruf.uni-freiburg.de
+ 132.230.6.237                   #sv8.ruf.uni-freiburg.de
+ &gt;physik.uni-freiburg.de #institute of physics, university Freiburg, Germany
+ 132.230.77.16                   #hepafs.physik.uni-freiburg.de
+ &gt;urz.uni-heidelberg.de  #Uni Heidelberg (Rechenzentrum)
+ 129.206.119.10                  #afsdb.urz.uni-heidelberg.de
+ 129.206.119.16                  #afsdb1.urz.uni-heidelberg.de
+ 129.206.119.17                  #afsdb2.urz.uni-heidelberg.de
+ &gt;uni-hohenheim.de       #University of Hohenheim
+ 144.41.2.2                      #rs13.serv.uni-hohenheim.de
+ 144.41.2.3                      #rs14.serv.uni-hohenheim.de
+ 144.41.2.4                      #rs15.serv.uni-hohenheim.de
+ &gt;rz.uni-jena.de         #Rechenzentrum University of Jena, Germany
+ 141.35.2.160                    #lc00.rz.uni-jena.de
+ 141.35.7.9                      #fsuj01.rz.uni-jena.de
+ 141.35.7.10                     #zaphod.rz.uni-jena
+ &gt;meteo.uni-koeln.de     #Univ. of Cologne - Inst. for Geophysics &amp; Meteorology
+ 134.95.144.22                   #afs1.meteo.uni-koeln.de
+ 134.95.144.24                   #afs2.meteo.uni-koeln.de
+ &gt;rrz.uni-koeln.de       #University of Cologne - Reg Comp Center
+ 134.95.19.3                     #afsdb1.rrz.uni-koeln.de
+ 134.95.19.30                    #fileserv3.rrz.uni-koeln.de
+ 134.95.67.97                    #afs.thp.uni-koeln.de
+ 134.95.140.190                  #rzkbserv.rrz.uni-koeln.de
+ &gt;physik.uni-mainz.de    #institute of physics, university Mainz, Germany
+ 134.93.130.93                   #hardy.physik.uni-mainz.de
+ &gt;uni-mannheim.de        #Uni Mannheim (Rechenzentrum)
+ 134.155.97.204                  #afsdb1.uni-mannheim.de
+ 134.155.97.205                  #afsdb2.uni-mannheim.de
+ 134.155.97.206                  #afsdb3.uni-mannheim.de
+ &gt;uni-paderborn.de       #University of Paderborn, Germany
+ 131.234.137.10                  #afsdb1.uni-paderborn.de
+ 131.234.137.11                  #afsdb2.uni-paderborn.de
+ 131.234.137.12                  #afsdb3.uni-paderborn.de
+ &gt;physik.uni-wuppertal.de #Physics department of Bergische Universität Wuppertal
+ 132.195.104.3                   #afs1.physik.uni-wuppertal.de
+ 132.195.104.230                 #afs2.physik.uni-wuppertal.de
+ &gt;s-et.aau.dk            #Aalborg Univ., The Student Society, Denmark
+ 130.225.196.22                  #afs.s-et.aau.dk
+ &gt;ies.auc.dk             #Aalborg Univ., Inst. of Electronic Systems, Denmark
+ 130.225.51.73                   #afsdb1.kom.auc.dk
+ 130.225.51.74                   #afsdb2.kom.auc.dk
+ 130.225.51.85                   #afsdb3.kom.auc.dk
+ &gt;asu.edu                #Arizona State University
+ 129.219.10.69                   #authen2.asu.edu
+ 129.219.10.70                   #authen1.asu.edu
+ 129.219.10.72                   #authen3.asu.edu
+ 129.219.100.16                  #authen4.asu.edu
+ &gt;hep.caltech.edu        #CalTech High Energy Physics
+ 131.215.126.150                 #afs.hep.caltech.edu
+ &gt;clarkson.edu           #Clarkson University, Potsdam, New York USA
+ 128.153.1.111                   #arthur.clarkson.edu
+ 128.153.9.111                   #lancelot.clarkson.edu
+ 128.153.17.111                  #uther.clarkson.edu
+ &gt;andrew.cmu.edu         #Carnegie Mellon University - Computing Services Cell
+ 128.2.10.2                      #vice2.fs.andrew.cmu.edu
+ 128.2.10.7                      #vice7.fs.andrew.cmu.edu
+ 128.2.10.11                     #vice11.fs.andrew.cmu.edu
+ 128.2.10.28                     #vice28.fs.andrew.cmu.edu
+ 128.2.32.44                     #new-vice12.fs.andrew.cmu.edu
+ &gt;club.cc.cmu.edu        #Carnegie Mellon University Computer Club
+ 128.237.157.11                  #sodium.club.cc.cmu.edu
+ 128.237.157.13                  #potassium.club.cc.cmu.edu
+ &gt;chem.cmu.edu           #Carnegie Mellon University - Chemistry Dept.
+ 128.2.40.134                    #afs.chem.cmu.edu
+ 128.2.40.140                    #afs2.chem.cmu.edu
+ &gt;cs.cmu.edu             #Carnegie Mellon University - School of Comp. Sci.
+ 128.2.194.178                   #cherry.srv.cs.cmu.edu
+ 128.2.194.179                   #pumpkin.srv.cs.cmu.edu
+ 128.2.194.180                   #strawberry.srv.cs.cmu.edu
+ &gt;ece.cmu.edu            #Carnegie Mellon University - Elec. Comp. Eng. Dept.
+ 128.2.129.7                     #porok.ece.cmu.edu
+ 128.2.129.8                     #vicio.ece.cmu.edu
+ 128.2.129.9                     #e-xing.ece.cmu.edu
+ &gt;scotch.ece.cmu.edu     #CMU ECE CALCM research group
+ 128.2.134.82                    #lagavulin.ece.cmu.edu
+ &gt;qatar.cmu.edu          #Carnegie Mellon University - Qatar Campus Cell
+ 204.194.25.7                    #afs1.qatar.cmu.edu
+ 204.194.25.8                    #afs2.qatar.cmu.edu
+ &gt;sbp.ri.cmu.edu         #Carnegie Mellon University - Sensor Based Planning Lab
+ 128.2.56.129                    #nihao.sbp.ri.cmu.edu
+ 128.2.56.136                    #youtheman.sbp.ri.cmu.edu
+ &gt;msc.cornell.edu        #Cornell University Materials Science Center
+ 128.84.231.242                  #miranda.ccmr.cornell.edu
+ 128.84.241.35                   #co.ccmr.cornell.edu
+ 128.84.249.78                   #dax.ccmr.cornell.edu
+ &gt;dbic.dartmouth.edu     #Dartmouth Brain Imaging Center
+ 129.170.30.143                  #dbicafs1.dartmouth.edu
+ 129.170.30.144                  #dbicafs2.dartmouth.edu
+ 129.170.30.145                  #dbicafs3.dartmouth.edu
+ &gt;northstar.dartmouth.edu #Dartmouth College Research Computing
+ 129.170.16.22                   #halley.dartmouth.edu
+ 129.170.16.42                   #oort.dartmouth.edu
+ 129.170.16.43                   #cygnusx1.dartmouth.edu
+ &gt;eecs.harvard.edu       #Harvard - EECS
+ 140.247.60.61                   #zermelo.eecs.harvard.edu
+ 140.247.60.83                   #corfu.eecs.harvard.edu
+ &gt;iastate.edu            #Iowa State University
+ 129.186.1.243                   #afsdb-1.iastate.edu
+ 129.186.6.243                   #afsdb-2.iastate.edu
+ 129.186.142.243                 #afsdb-3.iastate.edu
+ &gt;athena.mit.edu         #MIT/Athena cell
+ 18.7.1.66                       #paris.mit.edu.
+ 18.7.1.74                       #chimera.mit.edu.
+ 18.158.0.37                     #prill.mit.edu.
+ &gt;dev.mit.edu            #MIT/IS Development cell
+ 18.7.1.70                       #wham.mit.edu.
+ 18.7.15.89                      #rattle.mit.edu.
+ 18.7.15.93                      #hum.mit.edu.
+ &gt;net.mit.edu            #MIT/Network Group cell
+ 18.7.7.73                       #gracie.mit.edu
+ 18.7.21.95                      #george.mit.edu
+ &gt;sipb.mit.edu           #MIT/SIPB cell
+ 18.181.0.19                     #reynelda.mit.edu.
+ 18.181.0.22                     #rosebud.mit.edu.
+ 18.181.0.23                     #ronald-ann.mit.edu.
+ &gt;soap.mit.edu           #MIT School Of Architecture &amp; Planning
+ 18.89.1.204                     #crypt.mit.edu
+ 18.89.1.209                     #grotto.mit.edu
+ 18.89.2.156                     #ac.mit.edu
+ &gt;msu.edu                #Michigan State University Main Cell
+ 35.9.7.10                       #afsdb0.cl.msu.edu
+ &gt;nd.edu                 #University of Notre Dame
+ 129.74.223.17                   #john.helios.nd.edu
+ 129.74.223.33                   #lizardo.helios.nd.edu
+ 129.74.223.65                   #buckaroo.helios.nd.edu
+ &gt;pitt.edu               #University of Pittsburgh
+ 136.142.8.15                    #afs09.srv.cis.pitt.edu
+ 136.142.8.20                    #afs10.srv.cis.pitt.edu
+ 136.142.8.21                    #afs11.srv.cis.pitt.edu
+ &gt;cs.pitt.edu            #University of Pittsburgh - Computer Science
+ 130.49.220.11                   #afs01.cs.pitt.edu
+ 130.49.220.12                   #afs02.cs.pitt.edu
+ 130.49.220.13                   #afs03.cs.pitt.edu
+ &gt;psc.edu                #PSC (Pittsburgh Supercomputing Center)
+ 128.182.59.182                  #shaggy.psc.edu
+ 128.182.66.184                  #velma.psc.edu
+ 128.182.66.185                  #daphne.psc.edu
+ &gt;scoobydoo.psc.edu      #PSC Test Cell
+ 128.182.59.181                  #scooby.psc.edu
+ &gt;cede.psu.edu           #Penn State - Center for Engr. Design &amp; Entrepeneurship
+ 146.186.218.10                  #greenly.cede.psu.edu
+ 146.186.218.60                  #b50.cede.psu.edu
+ 146.186.218.246                 #stalin.cede.psu.edu
+ &gt;rose-hulman.edu        #Rose-Hulman Institute of Technology
+ 137.112.7.11                    #afs1.rose-hulman.edu
+ 137.112.7.12                    #afs2.rose-hulman.edu
+ 137.112.7.13                    #afs3.rose-hulman.edu
+ &gt;cs.rose-hulman.edu     #Rose-Hulman CS Department
+ 137.112.40.10                   #galaxy.cs.rose-hulman.edu
+ &gt;rpi.edu                #Rensselaer Polytechnic Institute
+ 128.113.22.11                   #saul.server.rpi.edu
+ 128.113.22.12                   #joab.server.rpi.edu
+ 128.113.22.13                   #korah.server.rpi.edu
+ 128.113.22.14                   #achan.server.rpi.edu
+ &gt;hep.sc.edu             #University of South Carolina, Dept. of Physics
+ 129.252.78.77                   #cpeven.physics.sc.edu
+ &gt;cs.stanford.edu        #Stanford University Computer Science Department
+ 171.64.64.10                    #cs-afs-1.Stanford.EDU
+ 171.64.64.66                    #cs-afs-2.stanford.edu
+ 171.64.64.69                    #cs-afs-3.stanford.edu
+ &gt;ir.stanford.edu        #Stanford University
+ 171.64.7.222                    #afsdb1.stanford.edu
+ 171.64.7.234                    #afsdb2.stanford.edu
+ 171.64.7.246                    #afsdb3.stanford.edu
+ &gt;slac.stanford.edu      #Stanford Linear Accelerator Center
+ 134.79.18.25                    #afsdb1.slac.stanford.edu
+ 134.79.18.26                    #afsdb2.slac.stanford.edu
+ 134.79.18.27                    #afsdb3.slac.stanford.edu
+ &gt;cats.ucsc.edu          #UC Santa Cruz, Comm. and Tech. Services, California U.S.A
+ 128.114.129.14                  #elan.ucsc.edu
+ 128.114.129.15                  #ichabod.ucsc.edu
+ 128.114.129.18                  #maneki.ucsc.edu
+ &gt;acm.uiuc.edu           #ACM at the University of Illinois
+ 128.174.251.8                   #alnitak.acm.uiuc.edu
+ 128.174.251.9                   #alnilam.acm.uiuc.edu
+ 128.174.251.10                  #mintaka.acm.uiuc.edu
+ &gt;ncsa.uiuc.edu          #University of Illinois
+ 141.142.3.5                     #congo.ncsa.uiuc.edu
+ 141.142.3.8                     #nile.ncsa.uiuc.edu
+ 141.142.3.9                     #kaskaskia.ncsa.uiuc.edu
+ &gt;umbc.edu               #University of Maryland, Baltimore County
+ 130.85.24.23                    #db2.afs.umbc.edu
+ 130.85.24.87                    #db3.afs.umbc.edu
+ 130.85.24.101                   #db1.afs.umbc.edu
+ &gt;glue.umd.edu           #University of Maryland - Project Glue
+ 128.8.70.11                     #olmec.umd.edu
+ 128.8.236.4                     #egypt.umd.edu
+ 128.8.236.230                   #babylon.umd.edu
+ &gt;wam.umd.edu            #University of Maryland Network WAM Project
+ 128.8.70.9                      #csc-srv.wam.umd.edu
+ 128.8.236.5                     #avw-srv.wam.umd.edu
+ 128.8.236.231                   #ptx-srv.wam.umd.edu
+ &gt;umich.edu              #University of Michigan - Campus
+ 141.211.1.32                    #fear.ifs.umich.edu
+ 141.211.1.33                    #surprise.ifs.umich.edu
+ 141.211.1.34                    #ruthless.ifs.umich.edu
+ &gt;atlas.umich.edu        #ATLAS group cell in physics at University of Michigan
+ 141.211.43.102                  #linat02.grid.umich.edu
+ 141.211.43.106                  #linat06.grid.umich.edu
+ 141.211.43.109                  #atgrid.grid.umich.edu
+ &gt;citi.umich.edu         #Center for Information Technology Integration
+ 141.211.133.5                   #babylon.citi.umich.edu
+ &gt;lsa.umich.edu          #University of Michigan - College of LS&amp;A
+ 141.211.211.53                  #gerow.lsa.umich.edu
+ 141.211.211.72                  #collines.lsa.umich.edu
+ 141.211.211.153                 #hodges.lsa.umich.edu
+ &gt;umr.edu                #University of Missouri - Rolla
+ 131.151.1.59                    #afsdb1.umr.edu
+ 131.151.1.70                    #afsdb3.umr.edu
+ 131.151.1.146                   #afsdb2.umr.edu
+ &gt;physics.unc.edu        #Univ. of NC at Chapel Hill, Dept. of Physics
+ 152.2.4.1                       #who.physics.unc.edu
+ 152.2.4.3                       #what.physics.unc.edu
+ 152.2.4.5                       #when.physics.unc.edu
+ &gt;uncc.edu               #University of NC at Charlotte Mosaic AFS Cell
+ 152.15.10.70                    #as-sm1.uncc.edu
+ 152.15.13.7                     #as-sm2.uncc.edu
+ 152.15.30.27                    #fs-kenn3.uncc.edu
+ &gt;eng.utah.edu           #University of Utah - Engineering
+ 155.99.222.9                    #lenny.eng.utah.edu
+ 155.99.222.10                   #carl.eng.utah.edu
+ &gt;cs.uwm.edu             #University of Wisconsin--Milwaukee
+ 129.89.38.124                   #solomons.cs.uwm.edu
+ &gt;cs.wisc.edu            #Univ. of Wisconsin-Madison, Computer Sciences Dept.
+ 128.105.132.14                  #timon.cs.wisc.edu
+ 128.105.132.15                  #pumbaa.cs.wisc.edu
+ 128.105.132.16                  #zazu.cs.wisc.edu
+ &gt;engr.wisc.edu          #University of Wisconsin-Madison, College of Engineering
+ 144.92.13.14                    #larry.cae.wisc.edu
+ 144.92.13.15                    #curly.cae.wisc.edu
+ 144.92.13.16                    #moe.cae.wisc.edu
+ &gt;hep.wisc.edu           #University of Wisconsin -- High Energy Physics
+ 128.104.28.219                  #anise.hep.wisc.edu
+ &gt;physics.wisc.edu       #Univ. of Wisconsin-Madison, Physics Department
+ 128.104.160.13                  #kendra.physics.wisc.edu
+ 128.104.160.14                  #fray.physics.wisc.edu
+ 128.104.160.15                  #buffy.physics.wisc.edu
+ &gt;ciemat.es              #Ciemat, Madrid, Spain
+ 130.206.11.42                   #afsdb1.ciemat.es
+ 130.206.11.217                  #afsdb2.ciemat.es
+ 130.206.11.247                  #afsdb3.ciemat.es
+ &gt;ifca.unican.es         #Instituto de Fisica de Cantabria (IFCA), Santander, Spain
+ 193.144.209.20                  #gridwall.ifca.unican.es
+ &gt;ific.uv.es             #Instituto de Fisica Corpuscular, Valencia, Spain
+ 147.156.163.11                  #alpha.ific.uv.es
+ &gt;biocenter.helsinki.fi  #University of Helsinki, Institute of Biotechnology
+ 128.214.58.174                  #afsdb1.biocenter.helsinki.fi
+ 128.214.88.114                  #afsdb2.biocenter.helsinki.fi
+ &gt;dapnia.saclay.cea.fr   #CEA DAPNIA
+ 132.166.32.7                    #dphrsg.saclay.cea.fr
+ 132.166.32.12                   #dphrsl.saclay.cea.fr
+ &gt;in2p3.fr               #IN2P3 production cell
+ 134.158.232.11                  #ccafsdb1.in2p3.fr
+ 134.158.232.12                  #ccafsdb2.in2p3.fr
+ 134.158.232.13                  #ccafsdb3.in2p3.fr
+ &gt;anl.gov                #Argonne National Laboratory
+ 146.137.96.33                   #arteus.ctd.anl.gov
+ 146.137.162.88                  #agamemnon.ctd.anl.gov
+ 146.137.194.80                  #antenor.ctd.anl.gov
+ &gt;rhic.bnl.gov           #Relativistic Heavy Ion Collider
+ 130.199.6.51                    #rafs03.rcf.bnl.gov
+ 130.199.6.52                    #rafs02.rcf.bnl.gov
+ 130.199.6.69                    #rafs01.rcf.bnl.gov
+ &gt;usatlas.bnl.gov        #US Atlas Tier 1 Facility at BNL
+ 130.199.48.32                   #aafs01.usatlas.bnl.gov
+ 130.199.48.33                   #aafs02.usatlas.bnl.gov
+ 130.199.48.34                   #aafs03.usatlas.bnl.gov
+ &gt;fnal.gov               #Fermi National Acclerator Laboratory
+ 131.225.68.1                    #fsus01.fnal.gov
+ 131.225.68.4                    #fsus03.fnal.gov
+ 131.225.68.14                   #fsus04.fnal.gov
+ &gt;ic-afs.arc.nasa.gov    #Code IC, Ames Research Center
+ 128.102.105.62                  #udanax.arc.nasa.gov
+ &gt;jpl.nasa.gov           #Jet Propulsion Laboratory
+ 137.78.160.21                   #afsdb08.jpl.nasa.gov
+ 137.78.160.22                   #afsdb09.jpl.nasa.gov
+ 137.78.160.23                   #afsdb10.jpl.nasa.gov
+ &gt;nersc.gov              #National Energy Research Supercomputer Center
+ 128.55.128.250                  #mars.nersc.gov
+ 128.55.128.252                  #alfred.nersc.gov
+ 128.55.128.254                  #lurch.nersc.gov
+ &gt;bme.hu                 #Budapest University of Technology and Economics
+ 152.66.241.6                    #afs.iit.bme.hu
+ &gt;kfki.hu                #Research Institute for Nuclear and Particle Physics - Budapest,H
+ 148.6.8.14                      #afs.kfki.hu
+ &gt;caspur.it              #CASPUR Inter-University Computing Consortium, Rome
+ 193.204.5.45                    #pomodoro.caspur.it
+ 193.204.5.46                    #banana.caspur.it
+ 193.204.5.50                    #maslo.caspur.it
+ &gt;enea.it                #ENEA New Tech. Energy &amp; Environment Agency, Italy
+ 192.107.54.5                    #aixfs.frascati.enea.it
+ 192.107.54.11                   #rs2ced.frascati.enea.it
+ 192.107.54.12                   #43p.frascati.enea.it
+ 192.107.61.235                  #serverinfo02.bologna.enea.it
+ 192.107.71.6                    #glauco.casaccia.enea.it
+ 192.107.96.233                  #riscdb.trisaia.enea.it
+ &gt;fusione.it             #Assoz. FUSIONE/Euratom, ENEA, Frascati-Italy
+ 192.107.90.2                    #fusafs1.frascati.enea.it
+ 192.107.90.3                    #fusafs2.frascati.enea.it
+ 192.107.90.4                    #fusafs3.frascati.enea.it
+ &gt;icemb.it               #ICEMB, Universita' La Sapienza - Rome - Italy
+ 193.204.6.130                   #icembfs.caspur.it
+ &gt;infn.it                #Istituto Nazionale di Fisica Nucleare (INFN), Italia
+ 131.154.1.7                     #afscnaf.infn.it
+ 141.108.26.75                   #afsrm1.roma1.infn.it
+ 192.84.134.75                   #afsna.na.infn.it
+ &gt;ba.infn.it             #INFN, Sezione di Bari
+ 193.206.185.235                 #baafsserver.ba.infn.it
+ &gt;kloe.infn.it           #INFN, KLOE experiment at Laboratori di Frascati
+ 192.135.25.111                  #kloeafs1.lnf.infn.it
+ 192.135.25.112                  #kloeafs2.lnf.infn.it
+ &gt;le.infn.it             #INFN, Sezione di Lecce
+ 192.84.152.40                   #afs01.le.infn.it
+ 192.84.152.148                  #afs02.le.infn.it
+ &gt;lnf.infn.it            #INFN, Laboratori Nazionali di Frascati
+ 193.206.84.121                  #afs1.lnf.infn.it
+ 193.206.84.122                  #afs2.lnf.infn.it
+ 193.206.84.123                  #afs3.lnf.infn.it
+ &gt;lngs.infn.it           #INFN, Laboratori Nazionali di Gran Sasso
+ 192.84.135.21                   #rsgs05.lngs.infn.it
+ &gt;pi.infn.it             #INFN, Sezione di Pisa
+ 131.114.134.26                  #unknownhost.pi.infn.it
+ 192.84.133.50                   #aix1.pi.infn.it
+ &gt;psm.it                 #Progetto San Marco, Universita' di Roma-1
+ 151.100.1.65                    #atlante.psm.uniroma1.it
+ &gt;tgrid.it               #CASPUR-CILEA-CINECA Grid Cell
+ 193.204.5.33                    #cccgrid.caspur.it
+ &gt;ictp.trieste.it        #The Abdus Salam International Centre for Theoretical Physics (IC
+ 140.105.16.8                    #fs1.ictp.trieste.it
+ 140.105.16.9                    #fs2.ictp.trieste.it
+ &gt;math.unifi.it          #math.unifi.it
+ 150.217.34.182                  #xeno.math.unifi.it
+ &gt;ing.uniroma1.it        #Universita' La Sapienza, Fac. Ingeneria
+ 151.100.85.253                  #alfa.ing.uniroma1.it
+ &gt;dia.uniroma3.it        #University Roma Tre - DIA
+ 193.204.161.79                  #plm.dia.uniroma3.it
+ 193.204.161.118                 #afs.dia.uniroma3.it
+ &gt;vn.uniroma3.it         #University of Rome 3, Area Vasca Navale
+ 193.204.161.136                 #alfa.dia.uniroma3.it
+ 193.204.161.137                 #beta.dia.uniroma3.it
+ 193.204.161.138                 #gamma.dia.uniroma3.it
+ &gt;italia                 #Italian public AFS cell
+ 193.204.5.9                     #afs.caspur.it
+ &gt;cmf.nrl.navy.mil       #Naval Research Lab - CCS
+ 134.207.10.68                   #picard.cmf.nrl.navy.mil
+ 134.207.10.69                   #riker.cmf.nrl.navy.mil
+ 134.207.10.70                   #kirk.cmf.nrl.navy.mil
+ &gt;lcp.nrl.navy.mil       #Naval Research Lab - Lab for Computational Physics
+ 132.250.114.2                   #afs1.lcp.nrl.navy.mil
+ 132.250.114.4                   #afs2.lcp.nrl.navy.mil
+ 132.250.114.6                   #afs3.lcp.nrl.navy.mil
+ &gt;es.net                 #Energy Sciences Net
+ 198.128.3.21                    #fs1.es.net
+ 198.128.3.22                    #fs2.es.net
+ 198.128.3.23                    #fs3.es.net
+ &gt;laroia.net             #Laroia Networks
+ 66.66.102.254                   #supercore.laroia.net
+ &gt;sinenomine.net         #Sine Nomine Associates
+ 66.92.236.139                   #afs.sinenomine.net
+ &gt;slackers.net           #The Slackers' Network
+ 63.201.48.27                    #alexandria.slackers.net
+ &gt;tproa.net              #The People's Republic of Ames
+ 209.234.76.70                   #service-3.tproa.net
+ &gt;nikhef.nl              #The Dutch National Institute for High Energy Physics
+ 192.16.185.26                   #afs1.nikhef.nl
+ 192.16.185.27                   #afs2.nikhef.nl
+ &gt;1ts.org                #1TS.ORG, Cambridge, MA
+ 4.36.43.102                     #dol-guldur.1ts.org
+ 69.25.196.51                    #pancake.1ts.org
+ &gt;bazquux.org            #Baz Quux Organization
+ 66.207.142.196                  #baxquux.org
+ &gt;coed.org               #Adam Pennington's Cell
+ 66.93.61.184                    #vice1.coed.org
+ 128.237.157.35                  #vice3.coed.org
+ &gt;dementia.org           #Dementia Unlimited
+ 128.2.12.45                     #alycia.dementia.org
+ 128.2.120.216                   #meredith.dementia.org
+ &gt;hackish.org            #Hackish.org
+ 24.167.65.213                   #avatar.sys.hackish.org
+ 128.2.120.138                   #kurma.sys.hackish.org
+ &gt;idahofuturetruck.org   #University of Idaho hybrid vehicle development
+ 12.18.238.210                   #dsle210.fsr.net
+ &gt;nimlabs.org            #Nimlabs, Ink. Cell.
+ 18.238.1.103                    #olfin.nimlabs.org
+ 18.238.1.105                    #caerbanog.nimlabs.org
+ &gt;nomh.org               #nomh.org
+ 204.29.154.12                   #iota.nomh.org
+ 204.29.154.32                   #adversity.xi.nomh.org
+ &gt;oc7.org                #The OC7 Project
+ 128.2.122.140                   #knife.oc7.org
+ 207.22.77.170                   #spoon.oc7.org
+ &gt;openafs.org            #OpenAFS Project
+ 18.7.14.88                      #grand-opening.mit.edu
+ 128.2.191.224                   #penn.central.org
+ 130.237.48.87                   #andrew.e.kth.se
+ &gt;e.kth.se               #Royal Institute of Technology, Elektro
+ 130.237.32.145                  #sonen.e.kth.se
+ 130.237.48.7                    #anden.e.kth.se
+ 130.237.48.244                  #fadern.e.kth.se
+ &gt;hallf.kth.se           #Royal Institute of Technology, HALLF
+ 130.237.24.141                  #rasmus13.hallf.kth.se
+ 130.237.24.152                  #rasmus3.hallf.kth.se
+ 130.237.24.177                  #rasmus29.hallf.kth.se
+ &gt;isk.kth.se             #Royal Institute of Technology, ISK
+ 130.237.202.12                  #afsdb2.isk.kth.se
+ 130.237.206.13                  #afsdb1.isk.kth.se
+ 130.237.209.141                 #afsdb3.isk.kth.se
+ &gt;it.kth.se              #Royal Institute of Technology, IT
+ 130.237.212.15                  #ptah.it.kth.se
+ 130.237.212.16                  #toth.it.kth.se
+ 130.237.215.7                   #isis.it.kth.se
+ &gt;md.kth.se              #Royal Institute of Technology, MMK
+ 130.237.57.68                   #trinity.md.kth.se
+ 130.237.57.72                   #morpheus.md.kth.se
+ 130.237.67.230                  #neo.speech.kth.se
+ &gt;mech.kth.se            #Royal Institute of Technology, MECH
+ 130.237.233.142                 #matterhorn.mech.kth.se
+ 130.237.233.143                 #castor.mech.kth.se
+ 130.237.233.144                 #pollux.mech.kth.se
+ &gt;nada.kth.se            #Royal Institute of Technology, NADA
+ 130.237.222.20                  #kosmos.nada.kth.se
+ 130.237.223.12                  #sputnik.nada.kth.se
+ 130.237.224.78                  #mir.nada.kth.se
+ 130.237.227.23                  #gagarin.nada.kth.se
+ 130.237.228.28                  #laika.nada.kth.se
+ &gt;pdc.kth.se             #Royal Institute of Technology, PDC
+ 130.237.232.29                  #crab.pdc.kth.se
+ 130.237.232.112                 #anna.pdc.kth.se
+ 130.237.232.114                 #hokkigai.pdc.kth.se
+ &gt;stacken.kth.se         #Stacken Computer Club
+ 130.237.234.3                   #milko.stacken.kth.se
+ 130.237.234.43                  #hot.stacken.kth.se
+ 130.237.237.230                 #fishburger.stacken.kth.se
+ &gt;syd.kth.se             #Royal Institute of Technology, KTH-Syd
+ 130.237.83.23                   #afs.haninge.kth.se
+ &gt;physto.se              #Physics department Stockholm University
+ 130.237.205.36                  #sysafs1.physto.se
+ 130.237.205.72                  #sysafs2.physto.se
+ &gt;sanchin.se             #Sanchin Consulting AB, Sweden
+ 192.195.148.10                  #sesan.sanchin.se
+ &gt;su.se                  #Stockholm University
+ 130.237.162.81                  #afsdb1.su.se
+ 130.237.162.82                  #afsdb2.su.se
+ 130.237.162.230                 #afsdb3.su.se
+ &gt;f9.ijs.si              #F9, Jozef Stefan Institue
+ 194.249.156.1                   #brenta.ijs.si
+ &gt;p-ng.si                #Nova Gorica Polytechnic
+ 193.2.120.2                     #solkan.p-ng.si
+ &gt;phy.bris.ac.uk         #Bristol University - phyics
+ 137.222.58.9                    #afs1.phy.bris.ac.uk
+ &gt;hep.man.ac.uk          #Manchester HEP
+ 194.36.2.3                      #afs1.hep.man.ac.uk
+ 194.36.2.4                      #afs2.hep.man.ac.uk
+ 194.36.2.5                      #afs3.hep.man.ac.uk
+ &gt;rl.ac.uk               #Rutherford Appleton Lab, England
+ 130.246.183.164                 #wallace.cc.rl.ac.uk
+ openafs-fileserver: non-standard-dir-perm
+ openafs-fileserver: non-standard-dir-perm
+ openafs-fileserver: non-standard-dir-perm
+ openafs-fileserver: non-standard-dir-perm
+ openafs-fileserver: non-standard-dir-perm
+ openafs-fileserver: non-standard-dir-perm
+ openafs-fileserver: non-standard-dir-perm
+ openafs-fileserver: non-standard-dir-perm
Index: openafs/src/packaging/Debian/ConfigUtils.pm
diff -c openafs/src/packaging/Debian/ConfigUtils.pm:1.1 openafs/src/packaging/Debian/ConfigUtils.pm:1.2
*** openafs/src/packaging/Debian/ConfigUtils.pm:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/ConfigUtils.pm	Thu Mar 23 15:19:06 2006
***************
*** 24,26 ****
--- 24,34 ----
  	 }
  
  1;
+ openafs-dbserver: non-standard-dir-perm
+ openafs-dbserver: non-standard-dir-perm
+ openafs-dbserver: non-standard-dir-perm
+ openafs-dbserver: non-standard-dir-perm
+ openafs-dbserver: non-standard-dir-perm
+ openafs-dbserver: non-standard-dir-perm
+ openafs-dbserver: non-standard-dir-perm
+ openafs-dbserver: non-standard-dir-perm
Index: openafs/src/packaging/Debian/README.Debian
diff -c openafs/src/packaging/Debian/README.Debian:1.1 openafs/src/packaging/Debian/README.Debian:1.2
*** openafs/src/packaging/Debian/README.Debian:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/README.Debian	Thu Mar 23 15:19:06 2006
***************
*** 1,25 ****
! openafs for Debian
! ----------------------
  
! * No manual pages are included.  I need to find out if versions exist
!   that are OK for copyright reasons.
  
! * Documentation can be found at http://www.openafs.org.  If want to
! set up a new cell, read the docs there and then look at the example
! session in configuration-transcript.txt.gz in this directory.  You
! should also read README.servers.  The procedure outlined in these two
! files is much simpler and more secure than the one in the Openafs
! documentation, but the Openafs documentation provides useful
! background.
  
! *  AFS users may be confused by the directory layout.  The files that
!    normally go in /usr/vice/etc go in /etc/openafs.  The cache should
!    be mounted on /var/cache/openafs.
! 
! * The libopenafs-dev package only includes static libraries because
!   AFS does not build shared libs.
! 
! 
! 
! 
!  -- Sam Hartman &lt;hartmans@mit.edu&gt;, Fri,  3 Nov 2000 23:41:41 -0500
--- 1,126 ----
!                             OpenAFS for Debian
  
! Introduction
  
!   For an OpenAFS client system, install openafs-client and a kernel
!   module.  See README.modules for information on how to build the kernel
!   module for your system.  Then, read /etc/openafs/afs.conf to understand
!   the client configuration options.  The openafs-client package will
!   attempt to guess at a good cache configuration based on the size of your
!   cache, but you may want to tune it further.  There are also other
!   options configured in that file you may want to consider.
! 
!   The AFS client cache must be on an ext2 or ext3 partition.  Other file
!   systems often do not support the semantics required by the AFS kernel
!   module and will cause afsd to abort (to avoid kernel panics).  In
!   particular, XFS, ReiserFS, and tmpfs will NOT work.  If you are using
!   one of those file systems and don't have a spare partition for a
!   separate file system for the cache, you need to use the -memcache option
!   to afsd (although this is not always stable) or create a large file with
!   dd, create an ext2 file system in it with mkfs, and then mount it with
!   mount -o loop for use as a cache partition.
! 
!   FAM does not work correctly with AFS except for directories that are
!   world-readable since it does not run in the user's security context and
!   therefore doesn't have the user's AFS tokens.  If you are using FAM,
!   you'll encounter errors from file managers such as Nautilus that use it
!   if you browse restricted AFS directories.  Instead of FAM, install
!   gamin, which runs in the user's security context and works correctly
!   with AFS.
! 
!   For information on how to set up an OpenAFS server, read README.servers.
!   You will want the openafs-fileserver package for a file server and,
!   additionally, the openafs-dbserver package for a database server.
! 
! Documentation
! 
!   For the complete OpenAFS manual, install openafs-doc.  This is the same
!   documentation as found at &lt;http://www.openafs.org/&gt;, and is
!   unfortunately outdated in several respects, but it's the best that we
!   have at present.
! 
!   If want to set up a new cell, read README.servers and then look at the
!   example session in configuration-transcript.txt.gz in this directory.
!   The procedure outlined in these two files is much simpler and more
!   secure than the one in the OpenAFS documentation, but the OpenAFS
!   documentation provides useful background.
! 
! Changes Relative to Stock OpenAFS
! 
!   Long-time AFS users may be confused by the directory layout.  The files
!   that normally go in /usr/vice/etc go in /etc/openafs.  The cache should
!   be mounted on /var/cache/openafs.  The server files have been moved
!   around even more; see README.servers for the details.
! 
!   The OpenAFS kernel module is named openafs, not libafs, to better match
!   normal Linux kernel module naming standards.  The Debian source package
!   only builds one kernel module that matches the kernel source tree it is
!   built against and does not attempt to build separate SMP and non-SMP
!   modules against the same tree.  Doing so does not work on all platforms.
!   To distinguish between an SMP and a non-SMP kernel module package, use
!   --append_to_version; see README.modules for more information.
! 
!   The AFS up utility is installed as afs-up, since the standard name is
!   rather generic.
! 
!   The libopenafs-dev package only includes static libraries and there are
!   no shared library packages.  The shared libraries built by AFS are not
!   compatible with Debian policy.  They do not have a stable ABI or an
!   appropriate SONAME.
! 
!   kaserver is not included.  New AFS cells should use Kerberos v5 rather
!   than the old K4-based kaserver KDC.
! 
!   The OpenAFS PAM modules have been built with pthreads rather than the
!   standard LWP AFS libraries for compatibility with a threaded sshd.
! 
! PAM Authentication
! 
!   Any new OpenAFS cell is strongly encouraged to use Kerberos v5 for
!   authentication.  If you want PAM to automatically obtain AFS credentials
!   and you are using Kerberos v5, you will want to install the libpam-krb5
!   and libpam-openafs-session packages and then put something like the
!   following in /etc/pam.d/common-auth:
! 
!       auth    [success=ok default=1]  pam_krb5.so ignore_root
!       auth    [default=done]          pam_openafs_session.so
!       auth    required                pam_unix.so nullok_secure try_first_pass
! 
!   and something like the following in /etc/pam.d/common-session:
! 
!       session optional        pam_krb5.so ignore_root
!       session optional        pam_openafs_session.so
!       session required        pam_unix.so
! 
!   You'll probably also want the following in /etc/pam.d/common-account:
! 
!       account required        pam_krb5.so ignore_root
!       account required        pam_unix.so
! 
!   There are, of course, many variations depending on what different
!   mechanism you want to use and how you want to handle fallbacks.
! 
!   If you are still using Kerberos v4 and the OpenAFS kaserver (or a KDC
!   that understands the same protocol) for authentication, you can instead
!   use the libpam-openafs-kaserver package and a configuration like:
! 
!       auth    sufficient      pam_afs.so ignore_root
!       auth    required        pam_unix.so nullok_secure try_first_pass
! 
!   in /etc/pam.d/common-auth and:
! 
!       session optional        pam_afs.so
!       session required        pam_unix.so
! 
!   in /etc/pam.d/common-session.  Use pam_afs.krb.so instead of pam_afs.so
!   if you also want the PAM module to acquire a ticket cache for you.  If
!   using this configuration with sshd, you may need to disable privilege
!   separation to get everything working properly.  I've had mixed results
!   with that.  Obviously, converting to Kerberos v5 authentication is
!   strongly preferred.
! 
!   If you are using the kaserver as your KDC, you may also want to install
!   the openafs-kpasswd package to get the administrative utilities for
!   managing those Kerberos accounts.
  
!  -- Russ Allbery &lt;rra@debian.org&gt;, Tue Dec 27 15:53:28 2005
Index: openafs/src/packaging/Debian/README.modules
diff -c openafs/src/packaging/Debian/README.modules:1.1 openafs/src/packaging/Debian/README.modules:1.2
*** openafs/src/packaging/Debian/README.modules:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/README.modules	Thu Mar 23 15:19:06 2006
***************
*** 1,35 ****
! 		       Building Kernel Modules
! ----------------------------------------
  
  
!  The easiest way to get AFS modules is to install prebuilt modules.
! Fore example if you are running kernel 2.2.18 you might try
  
! apt-get install openafs-modules-2.2.18
  
! If this doesn't work, then you will need to build your own modules.
! This means having kernel sources available.  You should install a
! kernel sources package and untar it in /usr/src.  Then, install
! openafs-modules-source.
  
! apt-get install openafs-modules-source
  
! Next, unpack openafs-modules-source
  
! cd /usr/src
! tar xzf openafs.tar.gz
  
! Now, change into your kernel source tree.  You should then create a
! .config file; the easiest way to do this is to run make menuconfig or
! to copy in a kernel configuration from the same version of the kernel.
! Debian kernel packages store a copy of their kernel configuration in
! /boot/config.version_number.  Finally build the modules
  
! make-kpkg configure
! make-kpkg modules_image
  
! You may need to use the --append_to_version switch to add version suffixes
! like -686 if your modules install into /lib/modules/version-686.
! Ignore any errors about genchanges.sh failing.  An openafs-modules deb
! should be created.  Use dpkg -i to install this version.
  
--- 1,93 ----
!                          Building Kernel Modules
  
+ Introduction
  
!   The easiest way to get AFS modules is to install prebuilt modules.  For
!   example, if you are running kernel 2.4.27-2-686-smp, you might try:
  
!       apt-get install openafs-modules-2.4.27-2-686-smp
  
!   Pre-built modules are not provided with Debian (building and maintaining
!   them in Debian proper poses too many problems), but many organizations
!   that use OpenAFS build their own and provide them locally.
  
!   If this doesn't work, you will need to build your own modules.  There
!   are two methods for doing this.
  
!   When following either method, be aware that the Debian package creates a
!   module named openafs, not libafs as is used by upstream.  It also
!   prefers not to add the .mp extension for modules built for SMP kernels;
!   the indication of whether the module is for an SMP kernel should go into
!   the package name via something like --append_to_version, not into the
!   file name of the module.
  
! module-assistant
  
!   This method is the best one to use when using the kernels that come with
!   Debian, since module-assistant knows how to get the right header files
!   to build modules for your currently running kernel.
  
!   First, install module-assistant and then prepare the kernel headers and
!   install openafs-modules-source:
  
!       apt-get install module-assistant
!       module-assistant prepare openafs-modules
  
+   (If you want to build modules for a different kernel than your currently
+   running one, pass the -l flag to module-assistant.  See the man page.)
+   module-assistant may be able to find the right packages itself or it may
+   tell you to install particular packages.  Once you've finished with
+   that, build the module with:
+ 
+       module-assistant auto-build openafs-modules
+ 
+   You may prefer to pass module-assistant the -t flag to get more
+   conventional output.  If everything works correctly, the openafs-modules
+   deb should be created in /usr/src.  You can use dpkg -i to install it.
+ 
+   module-assistant will take care of naming the openafs-modules package
+   correctly so that it matches the name of the kernel-image package and
+   installs its modules into the correct directory.
+ 
+ make-kpkg
+ 
+   This method works well when you're also building your own kernel, rather
+   than using the pre-packaged Debian one.
+ 
+   Install a kernel source package and untar it in /usr/src.  Then, install
+   openafs-modules-source.
+ 
+       apt-get install openafs-modules-source
+ 
+   Next, unpack openafs-modules-source:
+ 
+       cd /usr/src
+       tar xzf openafs.tar.gz
+ 
+   Now, change into your kernel source tree.  You should then create a
+   .config file; the easiest way to do this is to run make menuconfig or to
+   copy in a kernel configuration from the same version of the kernel.
+   Debian kernel packages store a copy of their kernel configuration in
+   /boot/config.version_number.
+ 
+   The kernel configuration needs to be identical to the configuration that
+   produced the kernel that you're using.  Ideally, you would build the
+   kernel image you're going to use with make-kpkg kernel_image and install
+   that along with the module image, although as long as the configuration
+   is identical, you may be able to get away with using a pre-built kernel.
+   (A better approach, if you're using pre-built kernels, may be to use
+   module-assistant as described above.)
+ 
+   Finally, build the modules:
+ 
+       make-kpkg modules_image
+ 
+   You may need to use the --append_to_version switch to add version
+   suffixes like -686 or -smp to match your kernel and install the OpenAFS
+   module into a directory like /lib/modules/version-686.  Be aware that
+   the Debian OpenAFS packages build either a regular module or an SMP
+   module, not both, so the generated package will only work with a kernel
+   with the same SMP configuration.
+ 
+   An openafs-modules deb should be created in /usr/src.  Use dpkg -i to
+   install this package.
Index: openafs/src/packaging/Debian/README.servers
diff -c openafs/src/packaging/Debian/README.servers:1.1 openafs/src/packaging/Debian/README.servers:1.2
*** openafs/src/packaging/Debian/README.servers:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/README.servers	Thu Mar 23 15:19:06 2006
***************
*** 1,47 ****
! 		 Setting up a Debian OpenAFS Server
  
! These packages include binaries with FHS-compatible path names.  Here
! is a map from AFS paths to FHS paths:
  
! /usr/afs/etc		/etc/openafs/server
! /usr/afs/local		/etc/openafs/server-local
! /usr/afs/db		/var/lib/openafs/db
! /usr/afs/logs		/var/log/openafs
! /usr/afs/bin		/usr/lib/openafs
! 
! 
! Scripts are provided to configure a single database/file server.  The
! afs-newcell script sets up the initial databases and configures
! bosserver.  After running this script, get tokens in the cell and run
! the afs-rootvol script to populate the root volume and root.cell.  A
! sample transcript of configuring an AFS cell can be found in
! /usr/share/doc/openafs-dbserver/configuration-transcript.txt.gz.  This
! transcript assumes you are using MIT Kerberos and the openafs-krb5
! package.  Similar steps could be taken with Heimdal.
! 
! Another issue is upgrades.  It is likely that future versions of this
! package will install for example /usr/lib/openafs/fileserver.package
! instead of /usr/lib/openafs/fileserver.  The postinst script will
! create links the actual binaries.  Upgrades will not replace the old
! binaries, but a script will be provided to roll the links forward to
! the new versions.  The intent is that people could install the new
! package on all their servers and then quickly move the links before
! restarting the bosserver.
! 
! 		      Adding Additional Servers
! 
! If you decide one server is not enough, here is roughly what needs to
! happen:
! 
! 1) Copy securely (using scp , encrypted Kerberized rcp or some other
!    secure method) /etc/openafs/server to the new server.
! 
! 2) Start a bosserver.
! 
! 3) If the machine is to be a file server, create an fs instance using
!    bos create.  For file servers this is all you need to do.
! 
! 4) For database servers, you also need to do a bos addhost on all
!    servers (including the new server) to add the new server to
!    /etc/openafs/server/CellServDB.  Then create ptserver and vlserver
!    instances.
--- 1,392 ----
!                     Setting up a Debian OpenAFS Server
  
! Introduction
  
!   This document describes how to set up an OpenAFS server using the Debian
!   packages.  If you are not already familiar with the basic concepts of
!   OpenAFS, you should review the documentation at:
! 
!       &lt;http://www.openafs.org/doc/index.htm&gt;
! 
!   particularly the AFS Administrator's Guide.  This documentation is
!   somewhat out of date (it doesn't talk about how to use a Kerberos v5 KDC
!   instead of the AFS kaserver, for example), but it's a good introduction
!   to the basic concepts and servers you will need to run.
! 
!   The Debian OpenAFS packages follow the FHS and therefore use different
!   paths than the standard AFS documentation or the paths that experienced
!   AFS administrators may be used to.  In the first column below are the
!   traditional paths, and in the second column, the Debian paths:
! 
!       /usr/afs/etc        /etc/openafs/server
!       /usr/afs/local      /etc/openafs/server-local
!       /usr/afs/db         /var/lib/openafs/db
!       /usr/afs/logs       /var/log/openafs
!       /usr/afs/bin        /usr/lib/openafs
!       /usr/vice/etc       /etc/openafs
! 
!   The AFS kaserver (a Kerberos v4 KDC) is not packaged for Debian.  Any
!   new OpenAFS installation should use Kerberos v5 for authentication in
!   conjunction with either the tools packaged in the openafs-krb5 package
!   or the Heimdal KDC.  When setting up a new cell, you should therefore
!   not set up a kaserver as described in the AFS Administrator's Guide, and
!   you will need to follow a slightly different method of setting the cell
!   key.
! 
! Creating a New Cell
! 
!   For documentation on adding a server to an existing cell, see below.
! 
!   These instructions assume that you are using MIT Kerberos and the
!   openafs-krb5 package.  If you are using Heimdal instead, some of the
!   steps will be slightly different (Heimdal can write the AFS KeyFile
!   directly, for example, so you don't have to use asetkey).  The
!   afs-newcell and afs-rootvol scripts are the same, however.
! 
!   /usr/share/doc/openafs-dbserver/configuration-transcript.txt.gz has a
!   transcript of the results of these directions, which you may want to
!   follow along with as you do this.
! 
!   1.  If you do not already have a Kerberos KDC (Key Distribution Center,
!       the daemon that handles Kerberos authentication) configured, do so.
!       You can run the KDC on the same system as your OpenAFS db server,
!       although if you plan on using Kerberos for other things, you may
!       eventually want to use separate systems.  If you do not have a
!       Kerberos realm set up already, you can do so in Debian with:
! 
!           apt-get install krb5-admin-server
!           krb5_newrealm
! 
!       This will install a KDC and kadmind server (the server that handles
!       password changes and account creations) on the local system.  Please
!       be aware that the security of everything that uses Kerberos for
!       authentication, including AFS, depends on the security of the KDC.
! 
!       The name of your Kerberos realm should, for various reasons, be in
!       all uppercase and be a domain name that you control, although
!       neither is technically required.
! 
!       Right now, for the aklog from openafs-krb5 to work, you need to
!       enable krb4 support (either full or nopreauth) and run krb524d.
!       Eventually this will no longer be necessary.
! 
!   2.  It is traditional (and recommended) in AFS (and for Kerberos) to
!       give administrators two separate Kerberos principals, one regular
!       principal to use for regular purposes and a separate admin principal
!       to use for privileged actions.  This is similar to the distinction
!       between a regular user and the root user in Unix, except that
!       everyone can have their own separate root identity.  Kerberos
!       recommends username/admin as the admin principal for username, and
!       this will work for AFS as well.
! 
!       If you have not already created such an admin principal for yourself
!       in your Kerberos realm, do so now (using kadmin.local on your KDC,
!       unless you have a local method that you prefer).  Also create a
!       regular (non-admin) principal for yourself if you have not already;
!       this is the identity that you'll use for regular operations, like
!       storing files or reading mail.  To do this with kadmin.local, run
!       that program and then run the commands:
! 
!           addprinc username/admin
!           addprinc username
! 
!       at the kadmin prompt.  You'll be prompted for passwords for both
!       accounts.
! 
!       If the KDC is not on the same system that the OpenAFS db server will
!       be on, you will also need to give your admin principal the rights to
!       download the afs keytab in /etc/krb5kdc/kadm5.acl by adding a lines
!       like:
! 
!           username/admin@REALM    *
! 
!       where REALM is your Kerberos realm and username/admin is the admin
!       principal that you created.  That line gives you full admin access
!       to the Kerberos v5 realm.  You can be more restrictive if you want;
!       see the kadmind man page for the syntax.
! 
!   3.  Install the OpenAFS db server package on an appropriate system with:
! 
!           apt-get install openafs-dbserver openafs-krb5
! 
!       The openafs-krb5 package will be used to create the AFS KeyFile.
! 
!       As part of this installation, you will need to configure
!       openafs-client with the cell you are creating as the local cell name
!       and the server on which you're working as the db server.  This name
!       is technically arbitrary but should, for various reasons, be a valid
!       domain name that you control; unlike Kerberos realms, it should be
!       in all lowercase.  Enter the name of the local system when prompted
!       for the names of your OpenAFS db servers.  Don't start the client;
!       that will happen below.  For right now, say that you don't want it
!       to start at boot.  You can change that later with dpkg-reconfigure
!       openafs-client.
! 
!       If you have already installed openafs-client and configured it for
!       some other cell, you do need to configure it to point to your new
!       cell for these instructions to work.  Stop the AFS client on the
!       system with /etc/init.d/openafs-client stop and then run:
! 
!            dpkg-reconfigure openafs-client
! 
!       pointing it to the new cell you're about to create instead.
!       Remember, your cell name should be in lowercase.  If you have had to
!       do this several times, double-check /etc/openafs/CellServDB when
!       you're done and make sure that there is only one entry for your new
!       cell at the top of that file and that it lists the correct IP
!       address for your new db server.
! 
!       In order to complete the AFS installation, you will also need a
!       working AFS client installed on that system, which means that you
!       need to install an OpenAFS kernel module.  Please see:
! 
!           /usr/share/doc/openafs-client/README.modules
! 
!       for information on how to do that.
! 
!   4.  Create an AFS principal in Kerberos.  This is the AFS service
!       principal, used by clients to authenticate to AFS and for AFS
!       servers to authenticate to each other.  It *must* be a DES key; AFS
!       does not support any other encryption type.  Run kadmin.local on
!       your KDC and then, at the kadmin.local prompt, run:
! 
!           addprinc -randkey -e des-cbc-crc:v4 afs
! 
!       If your Kerberos realm name does not match your AFS cell name (if,
!       for instance, you have one Kerberos realm with multiple AFS cells),
!       use "afs/cell.name" as the name of the principal above instead of
!       just "afs", where cell.name is the name of your new AFS cell.
! 
!   5.  On the db server, download this key into a keytab.  If this is the
!       same system as the KDC, you can use kadmin.local again.  If not, you
!       should use kadmin (make sure that krb5-user is installed), and you
!       may need to pass -p username/admin to kadmin to tell it what
!       principal to authenticate as.  Whichever way you get into kadmin,
!       run:
! 
!           ktadd -k /tmp/afs.keytab -e des-cbc-crc:v4 afs
! 
!       (or afs/cell.name if you used that instead).  In the message that
!       results, note the kvno number reported, since you'll need it later
!       (it will normally be 3).
! 
!       Don't forget the -e des-cbc-crc:v4 to force the afs key to be DES.
!       You can verify this with:
! 
!           getprinc afs
! 
!       and checking to be sure that the only key listed is a DES key.  If
!       there are multiple keys listed, delprinc the afs principal, delete
!       the /tmp/afs.keytab file, and then start over with addprinc, making
!       sure not to forget the -e option.
! 
!   6.  Create the AFS KeyFile with:
! 
!           asetkey add &lt;kvno&gt; /tmp/afs.keytab afs
! 
!       (or afs/cell.name if you used that instead).  &lt;kvno&gt; should be
!       replaced by the kvno number reported by kadmin.  This tells AFS the
!       Kerberos key that it should use, making it match the key in the
!       Kerberos KDC.
! 
!   7.  If the name of your Kerberos realm does not match the name of your
!       AFS cell, tell AFS what Kerberos realm to use with:
! 
!           echo REALM &gt; /etc/openafs/server/krb.conf
! 
!       where REALM is the name of your Kerberos realm.  If your AFS cell
!       and Kerberos realm have the same name, this is unnecessary.
! 
!   8.  Create some space to use for AFS volumes.  You can set up a separate
!       AFS file server on a different system from the Kerberos KDC and AFS
!       db server, and for a larger cell you will want to do so, but when
!       getting started you can make the db server a file server as well.
!       For a production cell, you will want to create a separate partition
!       devoted to AFS and mount it as /vicepa (and may want to make
!       multiple partitions mounted as /vicepb, /vicepc, etc.), but for
!       testing purposes, you can use the commands below to create a
!       zero-filled file, create a file system in it, and then mount it:
! 
!           dd if=/dev/zero of=/var/lib/openafs/vicepa bs=1024k count=32
!           mke2fs /var/lib/openafs/vicepa
!           mkdir /vicepa
!           mount -oloop /var/lib/openafs/vicepa /vicepa
! 
!       mke2fs will ask you if you're sure you want to create a file system
!       on a non-block device; say yes.
! 
!   9.  Run afs-newcell.  This will prompt you to be sure that the above
!       steps have been complete and will ask you for the Kerberos principal
!       to use for AFS administrative access.  You should use the
!       username/admin principal discussed above.  afs-newcell sets up the
!       initial protection database (which stores users and groups),
!       configures the AFS database and file server daemons, and creates the
!       root volume for AFS clients.
! 
!       At the completion of this step, you should see bosserver and several
!       other AFS server processes running, and you should be able to see
!       the status of those processes with:
! 
!           bos status localhost -local
! 
!       bosserver is a master server that starts and monitors all the
!       individual AFS servers, and bos is the program used to send it
!       commands.
! 
!       Now, you should be able to run:
! 
!           kinit username/admin@REALM
!           aklog cell.name -k REALM
! 
!       where username/admin is the admin principal discussed above, REALM
!       is the name of your Kerberos realm, and cell.name is the name of
!       your AFS cell.  This will obtain Kerberos tickets and AFS tokens in
!       your Kerberos realm and new AFS cell.  You should be able to see
!       your AFS tokens by running:
! 
!           tokens
! 
!       Finally, you should be able to see the status of the AFS server
!       processes with:
! 
!           bos status &lt;hostname&gt;
! 
!       where &lt;hostname&gt; is the hostname of the local system, once you've
!       done the above.  This tests authenticated bos access as your admin
!       principal (rather than using the local KeyFile to authenticate).
! 
!   10. Run afs-rootvol.  This creates the basic AFS volume structure for
!       your new cell, including the top-level volume, the mount point for
!       your cell in the AFS root volume, and the mount points for all known
!       public cells.  It will prompt you to be sure that the above steps
!       are complete and then will ask you what file server and partition to
!       create the volume on.  If you were following the above instructions,
!       use the local hostname and "a" as the partition (without the
!       quotes), which will use /vicepa.
! 
!       After this command completes, you should be able to /bin/ls /afs and
!       see your local cell (and, if you aren't using dynroot, mount points
!       for several other cells).  Note that if you're not using fakestat,
!       run /bin/ls rather than just ls to be sure that ls isn't aliased to
!       ls -F, ls --color, or some other option that would stat each file in
!       /afs, since this would require contacting lots of foreign cells and
!       could take a very long time.
! 
!       You should now be able to cd to /afs/cell.name where cell.name is
!       the AFS cell name that you used.  Currently, there isn't anything in
!       your cell except two volumes, user and service, created by
!       afs-rootvol.  To make modifications, cd to /afs/.cell.name (note the
!       leading period) and make changes there.  To make those changes show
!       up at /afs/cell.name, run vos release root.cell.  For more details
!       on what you can do now, see the AFS Administrator's Reference.
! 
!   11. While this is optional, you probably want to add AFSDB records to
!       DNS for your new AFS cell.  These special DNS records let AFS
!       clients find the db servers for your cell without requiring local
!       configuration.  To do this, create a DNS record like:
! 
!           &lt;cell&gt;.        3600    IN      AFSDB   1 &lt;server&gt;.
! 
!       where &lt;cell&gt; is the name of your AFS cell and &lt;server&gt; is the name
!       of your db server.  Note the trailing periods to prevent the DNS
!       server from appending the origin.  You can, of course, choose what
!       you prefer for the lifetime.  The 1 is not a priority; it's a
!       special indicator saying that this record is for an AFS database
!       server.
! 
!       If you have multiple db servers (see below for adding new ones), you
!       should create multiple records of this type, one per db server.
! 
!   Congratulations!  You now have an AFS cell.  If any of the above steps
!   failed, please check the steps carefully and make sure that you've done
!   them all in order.  If that doesn't reveal the cause of the problem,
!   please feel free to submit a bug report with reportbug.  Include as many
!   details as possible on exactly what you typed and exactly what you saw
!   as a result, particularly any error messages.
! 
! Adding Additional Servers
! 
!   If you decide one server is not enough, or if you're adding a server to
!   an existing cell, here is roughly what you should do:
! 
!   1.  Copy securely (using scp, encrypted Kerberos rcp, or some other
!       secure method) all of /etc/openafs/server to the new server.
! 
!   2.  Install the openafs-fileserver package on the new server.
! 
!   3.  If the machine is to be a file server, create an fs instance using
!       bos create:
! 
!           bos create &lt;host&gt; fs fs -cmd /usr/lib/openafs/fileserver \
!               -cmd /usr/lib/openafs/volserver \
!               -cmd /usr/lib/openafs/salvager -localauth
! 
!       For a file server, this is all you have to do.
! 
!   4.  For database servers, also install openafs-dbserver and then use bos
!       addhost to add the new server to /etc/openafs/server/CellServDB:
! 
!           bos addhost &lt;server&gt; &lt;new-server&gt;
! 
!       for each db server &lt;server&gt; in your cell (including the new one).
!       Then, restart the ptserver and vlserver instances on each of your
!       existing servers with:
! 
!           bos restart &lt;server&gt; ptserver
!           bos restart &lt;server&gt; vlserver
! 
!       It's best to wait a few seconds after doing this for each server
!       before doing the next server so that voting finishes and you never
!       lose a quorum.
! 
!       Only after ptserver and vlserver have been restarted on each of your
!       existing servers, create ptserver and vlserver instances on the new
!       server:
! 
!           bos create &lt;host&gt; ptserver simple /usr/lib/openafs/ptserver \
!               -localauth
!           bos create &lt;host&gt; vlserver simple /usr/lib/openafs/vlserver \
!               -localauth
! 
!       The existing servers should then propagate the database to the new
!       server.  If you are using buserver, you will need to do the same
!       thing for it as with ptserver and vlserver.
! 
!       Note that you do not need to run a file server on a db server if you
!       don't want to (and larger sites probably will not want to), but you
!       always need to have the openafs-fileserver package installed on db
!       servers.  It contains the bosserver binary and some of the shared
!       infrastructure.
! 
!   5.  If you added a new db server, configure your clients to use it.  If
!       you are using AFSDB records in DNS, you can just add a new record
!       (see point 10 in the instructions for creating a new cell).
!       Otherwise, clients will need to have the new server IP address added
!       to their /etc/openafs/CellServDB file (or /usr/vice/etc/CellServDB
!       for non-Debian clients using the standard AFS paths), and the client
!       will have to be restarted before it will know about the new db
!       server.
! 
!   The standard rule of thumb is that all of your database servers and file
!   servers should ideally be running the same version of OpenAFS.  However,
!   in practice OpenAFS is fairly good at backward compatibility and you can
!   generally mix and match different versions.  Be careful, though, to
!   ensure that all of your database servers are built the same when it
!   comes to options like --enable-supergroups (enabled in the Debian
!   packages).
! 
! Upgrades
! 
!   Currently, during an upgrade of the openafs-fileserver package, all
!   services will be stopped and restarted.  If openafs-dbserver is upgraded
!   without upgrading openafs-fileserver, those server binaries will not be
!   stopped and restarted; that restart will have to be done by hand.
! 
!   It is possible that future versions of this package will install for
!   example /usr/lib/openafs/fileserver.package instead of
!   /usr/lib/openafs/fileserver and then create links to the actual binaries
!   in postinst.  Upgrades would then not replace the old binaries, but
!   instead a script will be provided to roll the links forward to the new
!   versions.  The intent is that people could install the new package on
!   all their servers and then quickly move the links before restarting the
!   bosserver.  This has not yet been implemented.
Index: openafs/src/packaging/Debian/TODO
diff -c openafs/src/packaging/Debian/TODO:1.1 openafs/src/packaging/Debian/TODO:1.2
*** openafs/src/packaging/Debian/TODO:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/TODO	Thu Mar 23 15:19:06 2006
***************
*** 1 ****
! * Get bos restrict working
--- 1,13 ----
! * Get bos restrict working.
! 
! * The configuration transcript and the README.servers file would be best
!   read together, but preferrably with some nicer formatting (such as HTML
!   with a style sheet to set off the transcript in a different background
!   color).
! 
! * Consider including the kdump executable in the kernel module package.
!   openafs-client would have to provide a wrapper script to run the
!   appropriate kdump and the kernel module package would need to install
!   the kdump executable, maybe in /usr/lib/openafs, named after the kernel
!   image installed.
! 
Index: openafs/src/packaging/Debian/afs-newcell
diff -c openafs/src/packaging/Debian/afs-newcell:1.1 openafs/src/packaging/Debian/afs-newcell:1.2
*** openafs/src/packaging/Debian/afs-newcell:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/afs-newcell	Thu Mar 23 15:19:07 2006
***************
*** 1,19 ****
  #!/usr/bin/perl -w
  # Copyright (C) 2000 by Sam Hartman
! # This file may be copied either under the terms of the GNU GPL or the IBM Public License
! # either version 2 or later of the GPL or version 1.0 or later of the IPL.
  
  use Term::ReadLine;
  use strict;
  use Debian::OpenAFS::ConfigUtils;
  use Getopt::Long;
! use vars qw($admin $server
! 	   $requirements_met  $shutdown_needed);
  my $rl = new Term::ReadLine('afs-newcell');
  
  =head1  NAME
  
!    afs-newcell - Set up initial database server for AFS cell.
  
  =head1 SYNOPSIS
  
--- 1,20 ----
  #!/usr/bin/perl -w
  # Copyright (C) 2000 by Sam Hartman
! # This file may be copied either under the terms of the GNU GPL or the IBM
! # Public License either version 2 or later of the GPL or version 1.0 or later
! # of the IPL.
  
  use Term::ReadLine;
  use strict;
  use Debian::OpenAFS::ConfigUtils;
  use Getopt::Long;
! use Socket qw(inet_ntoa);
! use vars qw($admin $server $requirements_met $shutdown_needed);
  my $rl = new Term::ReadLine('afs-newcell');
  
  =head1  NAME
  
! afs-newcell - Set up initial database server for AFS cell
  
  =head1 SYNOPSIS
  
***************
*** 21,37 ****
  
  =head1 DESCRIPTION
  
- 
  This script sets up the initial AFS database and configures the first
  database/file server.
  
! The B&lt;requirements-met&gt; option specifies that the initial requirements
! have been met and that the script can proceed without displaying the
! initial banner or asking for confirmation.
! 
! The B&lt;admin&gt; option specifies the name of the administrative user.
! This user will be given system:administrators and susers permission in
! the cell.
  
  =head1 AUTHOR
  
--- 22,36 ----
  
  =head1 DESCRIPTION
  
  This script sets up the initial AFS database and configures the first
  database/file server.
  
! The B&lt;--requirements-met&gt; option specifies that the initial requirements have
! been met and that the script can proceed without displaying the initial
! banner or asking for confirmation.
! 
! The B&lt;--admin&gt; option specifies the name of the administrative user.  This
! user will be given system:administrators and susers permission in the cell.
  
  =head1 AUTHOR
  
***************
*** 39,59 ****
  
  =cut
  
! # main script
  
! GetOptions (
! 	    "requirements-met" =&gt; \$requirements_met, 
! 	    "admin=s" =&gt; \$admin);
  
  unless ($requirements_met) {
!   print &lt;&lt;eoreqs;
! 			    Prerequisites
  
  In order to set up a new AFS cell, you must meet the following:
  
  1) You need a working Kerberos realm with Kerberos4 support.  You
!    should install Heimdal with Kth-kerberos compatibility or MIT
!    Kerberos5.
  
  2) You need to create the single-DES AFS key and load it into
     /etc/openafs/server/KeyFile.  If your cell's name is the same as
--- 38,57 ----
  
  =cut
  
! # Flush all output immediately.
! $| = 1;
  
! GetOptions ("requirements-met" =&gt; \$requirements_met, "admin=s" =&gt; \$admin);
  
  unless ($requirements_met) {
!     print &lt;&lt;eoreqs;
!                             Prerequisites
  
  In order to set up a new AFS cell, you must meet the following:
  
  1) You need a working Kerberos realm with Kerberos4 support.  You
!    should install Heimdal with KTH Kerberos compatibility or MIT
!    Kerberos 5.
  
  2) You need to create the single-DES AFS key and load it into
     /etc/openafs/server/KeyFile.  If your cell's name is the same as
***************
*** 66,191 ****
  3) This machine should have a filesystem mounted on /vicepa.  If you
     do not have a free partition, then create a large file by using dd
     to extract bytes from /dev/zero.  Create a filesystem on this file
!    and mount it using -oloop.  
  
  4) You will need an administrative principal created in a Kerberos
! realm.  This principal will be added to susers and
! system:administrators and thus will be able to run administrative
! commands.  Generally the user is a root instance of some administravie
! user.  For example if jruser is an administrator then it would be
! reasonable to create jruser/root and specify jruser/root as the user
! to be added in this script.
  
  5) The AFS client must not be running on this workstation.  It will be
! at the end of this script.
  
  eoreqs
  
!   $_ = $rl-&gt;readline("Do you meet these requirements? [y/n] ");
!   unless (/^y/i ) {
!     print "Run this script again when you meet the requirements\n";
!     exit(1);
!   }
! 	
! 		if ($&gt; != 0) {
! die "This script should almost always be run as root.  Use the --requirements-met option to run as non-root.\n";
! }
  }
  open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
  while(&lt;MOUNT&gt;) {
! if(m:^AFS:) {
! print "The AFS client is currently running on this workstation.\n";
! print "Please restart this script after running /etc/init.d/openafs-client stop\n";
! exit(1);
! }
  }
  close MOUNT;
  
  unless ( -f "/etc/openafs/server/KeyFile") {
!   print "You do not have an AFS keyfile.  Please create this using asetkey from openafs-krb5 or 
! the bos addkey command";
!   exit(1);
  }
  
  print "If the fileserver is not running, this may hang for 30 seconds.\n";
  run("/etc/init.d/openafs-fileserver stop");
! $server = `hostname`;
  chomp $server;
! $admin = $rl-&gt;readline("What administrative principal should be used? ") unless $admin;
!  die "Please specify an administrative user\n" unless $admin;
! $admin =~ s:/:.:g;
! if($admin =~ /@/) {
! die "The administrative user must be in the same realm as the cell and no realm may be specified.\n";
  }
! open(CELL, "/etc/openafs/server/ThisCell") 
!   or die "Cannot open /etc/openafs/server/ThisCell: $!\n";
  my $cell = &lt;CELL&gt;;
  chomp $cell;
  
! run( "echo \\&gt;$cell &gt;/etc/openafs/server/CellServDB");
  run("/etc/init.d/openafs-fileserver start");
  $shutdown_needed = 1;
! run ("bos addhost $server $server -localauth ||true");
! run("bos adduser $server $admin -localauth");
! unwind("bos removeuser $server $admin -localauth");
! if ( -f "/var/lib/openafs/db/prdb.DB0" ) {
!   die "Protection database already exists; cell already partially created\n";
!  }
! open(PRDB, "|pt_util -p /var/lib/openafs/db/prdb.DB0 -w ")
! or die "Unable to start pt_util: $!\n";
! print PRDB "$admin 128/20 1 -204 -204\n";
  print PRDB "system:administrators 130/20 -204 -204 -204\n";
! print PRDB" $admin 1\n";
  close PRDB;
! unwind( "rm /var/lib/openafs/db/prdb* ");
! # Start up ptserver and vlserver
  run("bos create $server ptserver simple /usr/lib/openafs/ptserver -localauth");
  unwind("bos delete $server ptserver -localauth");
- 
  run("bos create $server vlserver simple /usr/lib/openafs/vlserver -localauth");
  unwind("bos delete $server vlserver -localauth");
  
! run( "bos create $server fs fs ".
!      "-cmd /usr/lib/openafs/fileserver ".
!      "-cmd /usr/lib/openafs/volserver ".
!      "-cmd /usr/lib/openafs/salvager -localauth");
! unwind( "bos delete $server fs -localauth ");
  
  print "Waiting for database elections: ";
  sleep(30);
  print "done.\n";
! # Past this point we want to control when bos shutdown happens
  $shutdown_needed = 0;
! unwind( "bos shutdown $server -localauth ");
  run("vos create $server a root.afs -localauth");
! # bring up client
! run("echo $cell &gt;/etc/openafs/ThisCell");
  run("/etc/init.d/openafs-client force-start");
  my $afs_running = 0;
! open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
  while(&lt;MOUNT&gt;) {
! if(m:^AFS:) {
! 	$afs_running = 1;
  }
- 	}
  unless ($afs_running) {
! print "*** The AFS client failed to start.\n";
! print  "Please fix whatever problem kept it from running.\n";
! 	exit(1);
  }
  
! print &lt;&lt;eomsg; 
! Now, get tokens as $admin in the $cell cell.  Then, run
! afs-rootvol.
! eomsg
! 
! 
! 
! 
  @unwinds = ();
  END {
! # If we fail before all the instances are created, we need to perform 
! # our own bos shutdown
!     system("bos shutdown $server -localauth") if $shutdown_needed;
!   run(pop @unwinds) while @unwinds;
!   }
--- 64,279 ----
  3) This machine should have a filesystem mounted on /vicepa.  If you
     do not have a free partition, then create a large file by using dd
     to extract bytes from /dev/zero.  Create a filesystem on this file
!    and mount it using -oloop.
  
  4) You will need an administrative principal created in a Kerberos
!    realm.  This principal will be added to susers and
!    system:administrators and thus will be able to run administrative
!    commands.  Generally the user is a root or admin instance of some
!    administrative user.  For example if jruser is an administrator then
!    it would be reasonable to create jruser/admin (or jruser/root) and
!    specify that as the user to be added in this script.
  
  5) The AFS client must not be running on this workstation.  It will be
!    at the end of this script.
  
  eoreqs
+ #'# cperl-mode
  
!     $_ = $rl-&gt;readline("Do you meet these requirements? [y/n] ");
!     unless (/^y/i ) {
!         print "Run this script again when you meet the requirements\n";
!         exit(1);
!     }
! 
!     if ($&gt; != 0) {
!         die "This script should almost always be run as root.  Use the\n"
!             . "--requirements-met option to run as non-root.\n";
!     }
  }
+ 
+ # Make sure the AFS client is not already running.
  open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
  while(&lt;MOUNT&gt;) {
!     if (m:^AFS:) {
!         print "The AFS client is currently running on this workstation.\n";
!         print "Please restart this script after running"
!             . " /etc/init.d/openafs-client stop\n";
!         exit(1);
!     }
  }
  close MOUNT;
  
+ # Make sure there is a keyfile.
  unless ( -f "/etc/openafs/server/KeyFile") {
!     print "You do not have an AFS keyfile.  Please create this using\n";
!     print "asetkey from openafs-krb5 or the bos addkey command\n";
!     exit(1);
  }
  
+ # Stop the file server.
  print "If the fileserver is not running, this may hang for 30 seconds.\n";
  run("/etc/init.d/openafs-fileserver stop");
! 
! # Get the local hostname.  Use the fully-qualified hostname to be safer.
! $server = `hostname -f`;
  chomp $server;
! my $ip = gethostbyname $server;
! if (inet_ntoa($ip) eq '127.0.0.1') {
!     print "\n";
!     print "Your hostname $server resolves to 127.0.0.1, which AFS cannot\n";
!     print "cope with.  Make sure your hostname resolves to a non-loopback\n";
!     print "IP address.  (Check /etc/hosts and make sure that your hostname\n";
!     print "isn't listed on the 127.0.0.1 line.  If it is, removing it from\n";
!     print "that line will probably solve this problem.)\n";
!     exit(1);
  }
! 
! # Determine the admin principal.
! $admin = $rl-&gt;readline("What administrative principal should be used? ")
!     unless $admin;
! print "\n";
! die "Please specify an administrative user\n" unless $admin;
! my $afs_admin = $admin;
! $afs_admin =~ s:/:.:g;
! if ($afs_admin =~ /@/) {
!     die "The administrative user must be in the same realm as the cell and\n"
!         . "no realm may be specified.\n";
! }
! 
! # Determine the local cell.  This should be configured via debconf, from the
! # openafs-client configuration, when openafs-fileserver is installed.
! open(CELL, "/etc/openafs/server/ThisCell")
!     or die "Cannot open /etc/openafs/server/ThisCell: $!\n";
  my $cell = &lt;CELL&gt;;
  chomp $cell;
  
! # Make sure the new cell is configured in the client CellServDB.
! open(CELLSERVDB, "/etc/openafs/CellServDB")
!     or die "Cannot open /etc/openafs/CellServDB: $!\n";
! my $found = 0;
! while (&lt;CELLSERVDB&gt;) {
!     next unless /^&gt;\Q$cell\E\s/;
!     while (&lt;CELLSERVDB&gt;) {
!         last if /^&gt;/;
!         my ($dbserver) = split ' ';
!         if ($dbserver eq inet_ntoa($ip)) {
!             $found = 1;
!             last;
!         }
!     }
!     last;
! }
! unless ($found) {
!     print "\n";
!     print "The new cell $cell is not configured in /etc/openafs/CellServDB\n";
!     print "Add configuration like:\n\n";
!     print "&gt;$cell\n";
!     print inet_ntoa($ip), "\n\n";
!     print "to that file before continuing.\n";
!     exit(1);
! }
! 
! # Write out a new CellServDB for the local cell containing only this server.
! if (-f "/etc/openafs/server/CellServDB") {
!     print "/etc/openafs/server/CellServDB already exists, renaming to .old\n";
!     rename("/etc/openafs/server/CellServDB",
!            "/etc/openafs/server/CellServDB.old")
!         or die "Cannot rename /etc/openafs/server/CellServDB: $!\n";
! }
! open(CELLSERVDB, "&gt; /etc/openafs/server/CellServDB")
!     or die "Cannot create /etc/openafs/server/CellServDB: $!\n";
! print CELLSERVDB "&gt;$cell\n";
! print CELLSERVDB inet_ntoa($ip), "\t\t\t#$server\n";
! close CELLSERVDB or die "Cannot write to /etc/openafs/server/CellServDB: $!\n";
! 
! # Now, we should be able to start bos and add the admin user.
  run("/etc/init.d/openafs-fileserver start");
  $shutdown_needed = 1;
! run("bos adduser $server $afs_admin -localauth");
! unwind("bos removeuser $server $afs_admin -localauth");
! 
! # Create the initial protection database using pt_util.  This is safer than
! # the standard mechanism of starting the cell in noauth mode until the first
! # user has been created.
! if (-f "/var/lib/openafs/db/prdb.DB0") {
!     warn "ERROR: Protection database already exists; cell already partially\n";
!     warn "ERROR: created.   If you do not want the current database, remove\n";
!     warn "ERROR: all files in /var/lib/openafs/db and then run this program\n";
!     warn "ERROR: again.\n";
!     exit(1);
! }
! print "\nCreating initial protection database.  This will print some errors\n";
! print "about an id already existing and a bad ubik magic.  These errors can\n";
! print "be safely ignored.\n\n";
! open(PRDB, "| pt_util -p /var/lib/openafs/db/prdb.DB0 -w")
!     or die "Unable to start pt_util: $!\n";
! print PRDB "$afs_admin 128/20 1 -204 -204\n";
  print PRDB "system:administrators 130/20 -204 -204 -204\n";
! print PRDB " $afs_admin 1\n";
  close PRDB;
! unwind("rm /var/lib/openafs/db/prdb*");
! print "\n";
! 
! # We should now be able to start ptserver and vlserver.
  run("bos create $server ptserver simple /usr/lib/openafs/ptserver -localauth");
  unwind("bos delete $server ptserver -localauth");
  run("bos create $server vlserver simple /usr/lib/openafs/vlserver -localauth");
  unwind("bos delete $server vlserver -localauth");
  
! # Create a file server as well.
! run("bos create $server fs fs"
!     . " -cmd /usr/lib/openafs/fileserver"
!     . " -cmd /usr/lib/openafs/volserver"
!     . " -cmd /usr/lib/openafs/salvager -localauth");
! unwind("bos delete $server fs -localauth");
  
+ # Pause for a while for ubik to catch up.
  print "Waiting for database elections: ";
  sleep(30);
  print "done.\n";
! 
! # Past this point we want to control when bos shutdown happens.
  $shutdown_needed = 0;
! unwind("bos shutdown $server -localauth -wait");
  run("vos create $server a root.afs -localauth");
! unwind("vos remove $server a root.afs -localauth");
! 
! # We should now be able to bring up the client (it may need root.afs to exist
! # if not using dynroot).  We override whatever default cell was configured for
! # the client, just in case it was pointing to some other cell.
! open(THIS, "&gt; /etc/openafs/ThisCell")
!     or die "ERROR: Cannot create /etc/openafs/ThisCell: $!\n";
! print THIS "$cell\n";
! close THIS or die "ERROR: Cannot write to /etc/openafs/ThisCell: $!\n";
  run("/etc/init.d/openafs-client force-start");
+ 
+ # Verify that AFS has managed to start.
  my $afs_running = 0;
! open(MOUNT, "mount |") or die "ERROR: Failed to run mount: $!\n";
  while(&lt;MOUNT&gt;) {
!     if (m:^AFS:) {
!         $afs_running = 1;
!     }
  }
  unless ($afs_running) {
!     print "ERROR: The AFS client failed to start.\n";
!     print "ERROR: Please fix whatever problem kept it from running.\n";
!     exit(1);
  }
+ print "\n";
+ print "Now, get tokens as $admin in the $cell cell.\n";
+ print "Then, run afs-rootvol.\n";
  
! # Success, so clear the unwind commands.
  @unwinds = ();
+ 
+ # If we fail before all the instances are created, we need to back out of
+ # everything we did as much as possible.
  END {
!     if ($shutdown_needed || @unwinds) {
!         print "\nCell setup failed, ABORTING\n";
!     }
!     system("bos shutdown $server -localauth -wait") if $shutdown_needed;
!     run(pop @unwinds) while @unwinds;
! }
Index: openafs/src/packaging/Debian/afs-rootvol
diff -c openafs/src/packaging/Debian/afs-rootvol:1.1 openafs/src/packaging/Debian/afs-rootvol:1.2
*** openafs/src/packaging/Debian/afs-rootvol:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/afs-rootvol	Thu Mar 23 15:19:07 2006
***************
*** 1,157 ****
  #!/usr/bin/perl -w
  # Copyright (C) 2000 by Sam Hartman
! # This file may be copied either under the terms of the GNU GPL or the IBM Public License
! # either version 2 or later of the GPL or version 1.0 or later of the IPL.
  
  use strict;
  use Term::ReadLine;
  use Getopt::Long;
  
! =head1  NAME
  
!    afs-rootvol - Generate and populate root volumes for new AFS cells.
  
  =head1 SYNOPSIS
  
! B&lt;afs-rootvol&gt; [B&lt;--requirements-met&gt;] [B&lt;--server&gt; server-name] [B&lt;--partition&gt; partition-letter]
  
  =head1 DESCRIPTION
  
! This script sets up an AFS cell's root volumes.  It assumes that you
! already have a fileserver and database servers.  The fileserver should
! have an empty root.afs.
!   This script creates root.cell, user, service and populates root.afs.  
  
  =head1 AUTHOR
  
  Sam Hartman &lt;hartmans@debian.org&gt;
  
  =cut
! 
! use vars qw($rl $server  $part $requirements_met);
! use vars qw( @unwinds);
! use Debian::OpenAFS::ConfigUtils;
! 
  
  # This subroutine creates a volume, mounts it and then sets the access
  # to allow read by anyuser.  The volume is scheduled for deletion in
  # case of error.
! # mkvol(volume, mount)
! 		    sub mkvol($$) {
! 		      my ($vol, $mnt) = @_;
! 		      run("vos create $server $part $vol -localauth");
! 		      unwind("vos remove $server $part $vol -localauth");
! 		      run("fs mkm $mnt $vol ");
! 		      run("fs sa $mnt system:anyuser rl");
! 		    }
  
! # main script
  $rl = new Term::ReadLine('AFS');
! 
! 
! GetOptions (
! 	    "requirements-met" =&gt; \$requirements_met, 
! 	    "server=s" =&gt; \$server,
! 	    "partition=s" =&gt; \$part
! 	    );
  unless ($requirements_met) {
!       print &lt;&lt;eotext;
! 			    Prerequisites
  
! In order to set up the root.afs volume, you must meet the following pre-conditions:
  
  1) The cell must be configured, running a database server with a
     volume location and protection server.  The afs-newcell script will
     set up these services.
  
! 2)  You must be logged into the cell with  tokens in
!    system:administrators and with a principal that is in the susers
     file of the servers in the cell.
  
  3) You need a fileserver in the cell with partitions mounted and a
!    root.afs volume created.   Presumably, it has no volumes on it,
     although the script will work so long as nothing besides root.afs
     exists.  The afs-newcell script will set up the file server.
  
  4) The AFS client must be running pointed at the new cell.
  eotext
      $_ = $rl-&gt;readline("Do you meet these conditions? (y/n) ");
      unless (/^y/i ) {
! 	print "Please restart the script when you meet these conditions.\n";
! 	exit(1);
      }
- 	
- 		if ($&gt; != 0) {
- die "This script should almost always be run as root.  Use the --requirements-met option to run as non-root.\n";
  }
  
! }
! # Get configuration information we need
  open(CELL, "/etc/openafs/server/ThisCell")
! or die "Unable to find out what cell this machine serves: $!\n";
  my $cell = &lt;CELL&gt;;
  close CELL;
  chomp $cell;
  
  unless ($server) {
!   print &lt;&lt;eotext; 
! You will need to select a server (hostname) and AFS
! partition on which to create the root volumes.
  eotext
  
!   $server = $rl-&gt;readline("What AFS Server should volumes be placed on? ");
!   die "Please select a server.\n" unless $server;
  }
  unless ($part) {
!   $part = $rl    -&gt;readline("What partition? [a] ");
! $part = "a" unless $part;
  }
  
  
! run("fs sa /afs system:anyuser rl");
! 
  run("vos create $server $part root.cell -localauth");
  unwind("vos remove $server $part root.cell -localauth");
! # We make root.cell s:anyuser readable after we mount in the next
! # loop.
! 
  
  open(CELLSERVDB, "/etc/openafs/CellServDB")
      or die "Unable to open /etc/openafs/CellServDB: $!\n";
! while(&lt;CELLSERVDB&gt;) {
      chomp;
!     if (/^&gt;\s*([a-z0-9_\-.]+)/ ) {
! 	run("fs mkm /afs/$1 root.cell -cell $1  -fast");
! 	unwind ("fs rmm /afs/$1");
      }
  }
  
  run("fs sa /afs/$cell system:anyuser rl");
! run ("fs mkm /afs/.$cell root.cell -cell $cell -rw");
! unwind ("fs rmm /afs/.$cell");
! run("fs mkm /afs/.root.afs root.afs -rw");
! unwind ("fs rmm /afs/.root.afs");
! 
! mkvol( "user", "/afs/$cell/user" );
! mkvol( "service", "/afs/$cell/service" );
  
! $cell =~ /^([^.]*)/;
  my $cellpart = $1;
! run("ln -s /afs/$cell /afs/$cellpart");
! unwind ("rm /afs/$cellpart");
! run( "ln -s /afs/.$cell /afs/.$cellpart" );
! unwind ("rm /afs/.$cellpart");
! 
! run( "vos addsite $server $part root.afs -localauth" );
! run( "vos addsite $server $part root.cell -localauth" );
! run( "vos release root.afs -localauth" );
! run( "vos release root.cell -localauth" );
! unwind( "vos remove $server $part root.cell.readonly -localauth ");
! unwind( "vos remove $server $part root.afs.readonly -localauth ");
  
  @unwinds = ();
  
  END {
!   run(pop @unwinds) while @unwinds;
!   }
! 
--- 1,194 ----
  #!/usr/bin/perl -w
  # Copyright (C) 2000 by Sam Hartman
! # This file may be copied either under the terms of the GNU GPL or the IBM
! # Public License either version 2 or later of the GPL or version 1.0 or later
! # of the IPL.
  
  use strict;
+ use Debian::OpenAFS::ConfigUtils;
  use Term::ReadLine;
  use Getopt::Long;
+ use vars qw($rl $server $part $requirements_met);
  
! =head1 NAME
  
! afs-rootvol - Generate and populate root volumes for new AFS cells.
  
  =head1 SYNOPSIS
  
! B&lt;afs-rootvol&gt; [B&lt;--requirements-met&gt;] [B&lt;--server&gt; I&lt;server-name&gt;]
! [B&lt;--partition&gt; I&lt;partition-letter&gt;]
  
  =head1 DESCRIPTION
  
! This script sets up an AFS cell's root volumes.  It assumes that you already
! have a fileserver and database servers.  The fileserver should have an empty
! root.afs.  This script creates root.cell, user, and service and populates
! root.afs.
  
  =head1 AUTHOR
  
  Sam Hartman &lt;hartmans@debian.org&gt;
  
  =cut
! #'# cperl-mode
  
  # This subroutine creates a volume, mounts it and then sets the access
  # to allow read by anyuser.  The volume is scheduled for deletion in
  # case of error.
! sub mkvol($$) {
!     my ($vol, $mnt) = @_;
!     run("vos create $server $part $vol -localauth");
!     unwind("vos remove $server $part $vol -localauth");
!     run("fs mkm $mnt $vol ");
!     run("fs sa $mnt system:anyuser rl");
! }
  
! # Main script.  Flush all output immediately.
! $| = 1;
  $rl = new Term::ReadLine('AFS');
! GetOptions ("requirements-met" =&gt; \$requirements_met,
!             "server=s" =&gt; \$server,
!             "partition=s" =&gt; \$part);
  unless ($requirements_met) {
!     print &lt;&lt;eotext;
!                             Prerequisites
  
! In order to set up the root.afs volume, you must meet the following
! pre-conditions:
  
  1) The cell must be configured, running a database server with a
     volume location and protection server.  The afs-newcell script will
     set up these services.
  
! 2) You must be logged into the cell with tokens in for a user in
!    system:administrators and with a principal that is in the UserList
     file of the servers in the cell.
  
  3) You need a fileserver in the cell with partitions mounted and a
!    root.afs volume created.  Presumably, it has no volumes on it,
     although the script will work so long as nothing besides root.afs
     exists.  The afs-newcell script will set up the file server.
  
  4) The AFS client must be running pointed at the new cell.
  eotext
+ 
      $_ = $rl-&gt;readline("Do you meet these conditions? (y/n) ");
      unless (/^y/i ) {
!         print "Please restart the script when you meet these conditions.\n";
!         exit(1);
!     }
!     if ($&gt; != 0) {
!         die "This script should almost always be run as root.  Use the\n"
!             . "--requirements-met option to run as non-root.\n";
      }
  }
  
! # Get configuration information we need.
  open(CELL, "/etc/openafs/server/ThisCell")
!     or die "Unable to find out what cell this machine serves: $!\n";
  my $cell = &lt;CELL&gt;;
  close CELL;
  chomp $cell;
  
  unless ($server) {
!     print &lt;&lt;eotext;
! 
! You will need to select a server (hostname) and AFS partition on which to
! create the root volumes.
! 
  eotext
  
!     $server = $rl-&gt;readline("What AFS Server should volumes be placed on? ");
!     die "Please select a server.\n" unless $server;
  }
  unless ($part) {
!     $part = $rl-&gt;readline("What partition? [a] ");
!     $part = "a" unless $part;
  }
+ print "\n";
  
+ # Make sure the user has tokens.  Forgetting to do this is a common error.
+ my $status = system("tokens | grep Expires &gt; /dev/null");
+ if ($status != 0) {
+     die "You appear to not have AFS tokens.  Obtain tokens (with aklog,\n"
+         . "for example) and then run this script again.\n";
+ }
  
! # Figure out where root.afs is.  There are two possibilities: either we aren't
! # running with dynroot, and root.afs is therefore accessible as /afs, or we
! # are running with dynroot, in which case we have to create root.cell first
! # and then mount root.afs under it.
! #
! # Always create root.cell first; we may need it if running with dynroot, and
! # it doesn't hurt to do it now regardless.
! my $rootmnt = "/afs";
  run("vos create $server $part root.cell -localauth");
  unwind("vos remove $server $part root.cell -localauth");
! my $dynroot = (-d "$rootmnt/$cell/.");
! if ($dynroot) {
!     run("fs mkm /afs/$cell/.root.afs root.afs -rw");
!     unwind("fs rmm /afs/$cell/.root.afs");
!     $rootmnt = "/afs/$cell/.root.afs";
! }
! run("fs sa $rootmnt system:anyuser rl");
  
+ # Scan CellServDB and create the cell mount points for every cell found there.
+ # Force these commands to succeed, since it's possible to end up with
+ # duplicate entries in CellServDB (and the second fs mkm will fail).
  open(CELLSERVDB, "/etc/openafs/CellServDB")
      or die "Unable to open /etc/openafs/CellServDB: $!\n";
! while (&lt;CELLSERVDB&gt;) {
      chomp;
!     if (/^&gt;\s*([a-z0-9_\-.]+)/) {
!         run("fs mkm $rootmnt/$1 root.cell -cell $1 -fast || true");
!         unwind("fs rmm $rootmnt/$1 || true");
      }
  }
  
+ # Now, create the read/write mount points for root.cell and root.afs and set
+ # root.cell system:anyuser read.
  run("fs sa /afs/$cell system:anyuser rl");
! run("fs mkm $rootmnt/.$cell root.cell -cell $cell -rw");
! unwind("fs rmm $rootmnt/.$cell");
! run("fs mkm $rootmnt/.root.afs root.afs -rw");
! unwind("fs rmm $rootmnt/.root.afs");
! 
! # Create the user and service mount point volumes to fit the semi-standard AFS
! # cell layout.
! mkvol("user", "/afs/$cell/user");
! mkvol("service", "/afs/$cell/service");
  
! # Strip the domain off of the cell name and create the short symlinks.
! $cell =~ /^([^.]+)/;
  my $cellpart = $1;
! if ($cellpart &amp;&amp; $cellpart ne $cell) {
!     run("ln -s $cell $rootmnt/$cellpart");
!     unwind("rm $rootmnt/$cellpart");
!     run("ln -s .$cell $rootmnt/.$cellpart");
!     unwind("rm $rootmnt/.$cellpart");
! }
! if ($dynroot) {
!     run("fs rmm /afs/$cell/.root.afs");
!     unwind("fs mkm /afs/$cell/.root.afs root.afs -rw");
! }
! 
! # Now, replicate the infrastructure volumes.
! run("vos addsite $server $part root.afs -localauth");
! run("vos addsite $server $part root.cell -localauth");
! run("vos release root.afs -localauth");
! run("vos release root.cell -localauth");
! unwind("vos remove $server $part root.cell.readonly -localauth");
! unwind("vos remove $server $part root.afs.readonly -localauth");
  
+ # Success, so clear the unwind commands.
  @unwinds = ();
  
+ # If we fail before all the instances are created, we need to back out of
+ # everything we did as much as possible.
  END {
!     if (@unwinds) {
!         print "\nRoot volume setup failed, ABORTING\n";
!     }
!     run(pop @unwinds) while @unwinds;
! }
Index: openafs/src/packaging/Debian/afs.conf
diff -c /dev/null openafs/src/packaging/Debian/afs.conf:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/afs.conf	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1,129 ----
+ # -*- sh -*-
+ # Copyright 2000, International Business Machines Corporation and others.
+ # All Rights Reserved.
+ # 
+ # This software has been released under the terms of the IBM Public
+ # License.  For details, see the LICENSE file in the top-level source
+ # directory or online at http://www.openafs.org/dl/license10.html
+ 
+ # Configuration information for AFS client.
+ 
+ # The following options are maintained by debconf.  To change them, run
+ # dpkg-reconfigure openafs-client.
+ #
+ #   AFS_CLIENT          Whether to start the AFS client at boot
+ #   AFS_AFSDB           Whether to use AFSDB DNS records to find VLDB servers
+ #   AFS_CRYPT           Whether to enable fcrypt encryption
+ #   AFS_DYNROOT         Whether to use a dynamic /afs directory
+ #   AFS_FAKESTAT        Whether to fake stat data for mount points
+ 
+ test -f /etc/openafs/afs.conf.client &amp;&amp; . /etc/openafs/afs.conf.client
+ 
+ # Set to "-verbose" for a lot of debugging information from afsd.  Only useful
+ # for debugging as it prints a LOT of information.
+ VERBOSE=
+ 
+ # AFS client configuration options.
+ #
+ # Here is a (mostly) complete list of flags that afsd accepts and that are
+ # useful here:
+ #
+ #   -blocks     The number of blocks available in the workstation cache.
+ #   -files      The target number of files in the workstation cache (Default:
+ #               1000).
+ #   -rootvol    The name of the root volume to use.
+ #   -stat       The number of stat cache entries.
+ #   -hosts      List of servers to check for volume location info FOR THE
+ #               HOME CELL.
+ #   -memcache   Use an in-memory cache rather than disk.
+ #   -cachedir   The base directory for the workstation cache.
+ #   -mountdir   The directory on which the AFS is to be mounted.
+ #   -confdir    The configuration directory.
+ #   -nosettime  Don't keep checking the time to avoid drift (default).
+ #   -settime    Keep checking the time to avoid drift.
+ #   -verbose    Be chatty.
+ #   -debug      Print out additional debugging info.
+ #   -daemons    The number of background daemons to start (Default: 2).
+ #   -rmtsys     Also fires up an afs remote sys call (e.g. pioctl, setpag)
+ #               support daemon 
+ #   -chunksize  2^n is the chunksize to be used (Default: use a kernel
+ #               module default).
+ #   -dcache     The number of data cache entries.
+ #   -prealloc   Number of preallocated "small" memory blocks
+ #   -waitclose  Make close calls always synchronous (slows them down, though)
+ #   -files_per_subdir   Number of files per cache subdir (Default: 2048).
+ #
+ # Using the memory cache is not recommended.  It's less stable than the disk
+ # cache and doesn't improve performance as much as it might sound.
+ #
+ # The default behavior is to pick one of the following option sets based on
+ # the size of the AFS cache, as follows:
+ #
+ #           cache &lt; 128MB       $SMALL
+ #   128MB &lt; cache &lt; 512MB       $MEDIUM
+ #   512MB &lt; cache &lt; 1GB         $LARGE
+ #     1GB &lt; cache &lt; 2GB         $XLARGE
+ #     2GB &lt; cache               $XXLARGE
+ #
+ # You can override that default behavior by setting OPTIONS below.
+ XXLARGE="-chunksize 20 -files 80000 -dcache 10000 -stat 15000 -daemons 6 -volumes 500"
+ XLARGE="-chunksize 20 -files 50000 -dcache 10000 -stat 15000 -daemons 5 -volumes 250"
+ LARGE="-chunksize 18 -files 25000 -dcache 10000 -stat 15000 -daemons 5 -volumes 200"
+ MEDIUM="-chunksize 18 -files 10000 -dcache 5000 -stat 7500 -daemons 3 -volumes 200"
+ SMALL="-chunksize 18 -files 2500 -dcache 2000 -stat 3000 -daemons 2 -volumes 200"
+ 
+ # The default behavior is to pick one of the above settings as described
+ # above.  You can override this by setting OPTIONS explicitly to either one of
+ # the above variables or to any set of flags that you prefer.
+ OPTIONS=AUTOMATIC
+ 
+ # The default value for the client sysname (as returned by fs sysname) is
+ # determined during the kernel module build and is taken from the architecture
+ # and the major Linux kernel version.  Accesses to directories named "@sys" in
+ # AFS will be internally redirected to a directory by this name by the AFS
+ # client, allowing a single path to resolve to different directories depending
+ # on the client architecture.
+ #
+ # If you would like to override the client sysname, uncomment this line and
+ # set the variable to a space-separated list of sysnames.  The AFS client will
+ # attempt to resolve @sys to each directory name in the order given.
+ #AFS_SYSNAME=""
+ 
+ # If you want to prefer particular servers for replicated volumes, you can
+ # configure that by defining an afs_server_prefs function here and then
+ # uncommenting the setting of AFS_POST_INIT below.  For more information, see
+ # fs help setserverprefs and fs getserverprefs (for the current values).
+ 
+ #afs_server_prefs() {
+ #    fs setserverprefs &lt;host&gt; &lt;rank&gt;
+ #}
+ 
+ # If you want to always run some command after starting OpenAFS, you can put
+ # it here.  Note that you cannot run multiple commands, even combined with &amp;&amp;
+ # or ; or similar shell meta-characters.  If you want to run multiple
+ # commands, define a shell function instead and put the name of the shell
+ # function here.
+ AFS_POST_INIT=
+ 
+ # Uncomment this line if you defined an afs_server_prefs function.  (If you
+ # have other commands that you also want to run, you'll have to put them in
+ # that function, as you can only run one function.)
+ #AFS_POST_INIT=afs_server_prefs
+ 
+ # If you want to always run some command before shutting down OpenAFS, you can
+ # put it here.  The same caveat applies about multiple commands.
+ AFS_PRE_SHUTDOWN=
+ 
+ # If you are having problems with AFS shutting down cleanly or the system not
+ # rebooting because the partition the AFS cache was on could not be unmounted,
+ # try installing lsof and uncommenting this.  This will cause all processes
+ # with open AFS files to be killed before unmounting AFS if the runlevel being
+ # switched to is 0 or 6.
+ #
+ # Warning: This means /etc/init.d/openafs-client stop will kill all processes
+ # with files open in AFS rather than returning an error saying the file system
+ # is busy.  This is probably what you want when the whole system is shutting
+ # down, but often *not* what you want when just stopping and restarting the
+ # client.  The code doesn't run unless the runlevel is 0 or 6, but still, be
+ # sure that this is what you want before enabling it.
+ #AFS_PRE_SHUTDOWN=kill_all_afs
Index: openafs/src/packaging/Debian/changelog
diff -c openafs/src/packaging/Debian/changelog:1.1 openafs/src/packaging/Debian/changelog:1.2
*** openafs/src/packaging/Debian/changelog:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/changelog	Thu Mar 23 15:19:07 2006
***************
*** 1,3 ****
--- 1,577 ----
+ openafs (1.4.0-4) unstable; urgency=low
+ 
+   * Hopefully fix sparc64 kernel support.  Thanks, Troy Benjegerdes.
+     (Closes: #219429)
+   * Document the need to restart ptserver and vlserver on the existing
+     database servers when adding a new one.  Thanks, Niklas Edmundsson.
+     (Closes: #349659)
+   * Include xstat_cm_test and xstat_fs_test in openafs-client, as they're
+     quite useful for debugging.
+ 
+  -- Russ Allbery &lt;rra@debian.org&gt;  Tue, 14 Mar 2006 21:07:07 -0800
+ 
+ openafs (1.4.0-3) unstable; urgency=low
+ 
+   * Apply upstream patch from Chas Williams to be more careful about what
+     dentry is used in renames, avoiding a kernel fault when renaming
+     dentries accessed through multiple paths (such as RO and RW).
+   * Apply patch to allow the module to build with the Ubuntu kernel.
+     Thanks, BjÃ¶rn Torkelsson.  (Closes: #342607)
+   * Stop unconditionally forcing the compiler to cc or gcc in configure,
+     allowing, among other things, building the kernel module with a
+     compiler other than the default system compiler.  (Closes: #338306)
+   * Call kernel-version correctly from prep-modules, which fixes build
+     issues with manually-built kernels.  (Closes: #344851)
+   * Backport man pages from upstream CVS.  (Closes: #79763)
+   * Include afsmonitor and livesys in openafs-client.
+   * Include volinfo in openafs-fileserver.
+   * Document FAM's lack of support for AFS's security model and recommend
+     gamin instead.  (Closes: #343246)
+   * Add a hint to README.Debian on what to do about the cache partition if
+     running ReiserFS or XFS without a spare partition.
+   * Use make install into debian/tmp rather than make dest.  make dest is
+     mostly for Transarc compatibility and make install looks more like a
+     typical package and makes it easier to evaluate differences in FHS
+     location between upstream and Debian.  As a side effect, there's no
+     need to mess with the @sys link.  (Closes: #165909)
+   * Install more files with dh_install rather than install commands in
+     debian/rules so that *.install shows a more complete picture of what
+     goes into each package.
+   * Don't ignore make distclean errors.
+ 
+  -- Russ Allbery &lt;rra@debian.org&gt;  Tue, 27 Dec 2005 15:34:16 -0800
+ 
+ openafs (1.4.0-2) unstable; urgency=low
+ 
+   * Install more of the standard OpenAFS utilities.  (Closes: #138851)
+     - openafs-dbserver: Install prdb_check and vldb_check.
+     - openafs-fileserver: Install voldump.
+     - openafs-client: Install fstrace, scout, and up (as afs-up).
+     - Modify fstrace to load its catalog from /usr/share/openafs.
+   * Do not install kpwvalid.  The default version does little useful and
+     the kpwvalid binary must be in AFS for it to take effect.
+   * Overhaul the way kernel modules are built.
+     - Recommend linux-image rather than kernel-image for newer kernels.
+     - Always recommend the kernel package; since it's only a recommends,
+       there's no need to special-case the hand-built kernel case.
+     - Be less fragile about how the kernel version is used in prep-modules
+       to support other ways kernel modules are built.  (Closes: #341836)
+     - Add Build-Depends and Uploaders to the openafs-modules-source
+       control file.
+     - Remove unused parts of prep-modules and heavily comment it.
+   * openafs-client should only recommend the AFS kernel module.  Many of
+     the client programs will work in unauthenticated mode without it, and
+     openafs-fileserver depends on it (but doesn't require the kernel
+     module).  (Closes: #342095)
+   * openafs-modules-source no longer has to depend on as many libraries.
+   * Suggest the same PAM settings for pam_krb5 that libpam-krb5 does.
+   * Update uploader address.
+ 
+  -- Russ Allbery &lt;rra@debian.org&gt;  Tue,  6 Dec 2005 23:34:18 -0800
+ 
+ openafs (1.4.0-1) unstable; urgency=low
+ 
+   * New upstream version.
+     - Builds correctly with 2.6.13 kernels and software suspend.
+     - Builds correctly with 2.6.12-10.  (Closes: #337883)
+   * Install afsd in /sbin rather than /usr/sbin.  While putting /usr in
+     AFS isn't as common as it once was, no reason to make it harder than
+     it needs to be.
+   * Update CellServDB to the 2005-10-15 grand.central.org version.
+   * Install NEWS as an upstream changelog.
+   * Add a watch file.
+   * Remove the unused and uninstalled make-links script.
+ 
+  -- Russ Allbery &lt;rra@stanford.edu&gt;  Sun,  6 Nov 2005 21:37:40 -0800
+ 
+ openafs (1.4rc4-1) unstable; urgency=low
+ 
+   * New upstream version.
+     - Correctly handle root.afs becoming replicated after the client
+       starts.  This should resolve the problems with AFS eventually
+       failing on the first system using a new cell.  (Closes: #88906)
+   * When kill_all_afs is enabled in /etc/openafs/afs.conf, only kill AFS
+     processes if the runlevel is 0 or 6.  You really only want this when
+     the system is shutting down.  (Closes: #325347)
+   * Remove the init script check of the cache file system and instead
+     improve the check in afsd.  The init script check used stat, which is
+     in /usr/bin and therefore not fair game for init scripts.
+   * Set PATH in the init script, just in case.
+   * libpam-openafs-kaserver must depend on openafs-client, not just
+     recommend it, since acquiring tokens requires that the client be
+     running.
+   * Expand README.Debian and include information about PAM configuration.
+   * Link libpam-openafs-kaserver's doc directory to openafs-client.
+   * Make the short descriptions shorter.
+   * Translation updates.
+     - Portuguese (Brazil), thanks AndrÃ© LuÃ­s Lopes.
+ 
+  -- Russ Allbery &lt;rra@stanford.edu&gt;  Wed, 21 Sep 2005 13:36:34 -0700
+ 
+ openafs (1.4rc1-1) unstable; urgency=low
+ 
+   * New upstream version.
+   * Install pam_afs.krb.so on hppa.  I believe the new PAM module build
+     process fixes the issue that was being worked around before.
+   * Improve the documentation and scripts for setting up new servers or a
+     new cell.  afs-rootvol can now be run from a client configured to use
+     dynroot.  afs-newcell generates the server CellServDB directly to work
+     around oddities with bos addhost.  There are many other, more minor
+     improvements as well.  Thanks to Faheem Mitha and Sergio Gelato for
+     analysis and patches.  (Closes: #322638)
+   * Update the configuration transcript to reflect the current packages,
+     messages, and instructions.  Thanks, Faheem Mitha.
+   * Fill in the server CellServDB with information about the local cell,
+     if available in the client CellServDB, rather than always initializing
+     it to contain just the name of the cell.
+   * Detect AFS caches on non-ext2/ext3 file systems and abort AFS client
+     initialization.  (Closes: #249315)
+   * Provide a way of setting sysname in afs.conf.  (Closes: #324694)
+   * Don't create the unused /etc/openafs/AFSLog file.  (Closes: #120097)
+   * Redo how library object files are found for the PAM module build to
+     avoid assuming C locale character set behavior.  (Closes: #323582)
+   * Remove the openafs-client warning against dynroot for the first system
+     in a cell now that afs-rootvol can cope.  Provide some basic
+     documentation of the CellAlias syntax in that message until we have a
+     real man page.
+   * Suggest openafs-doc.
+   * Update standards version to 3.6.2 for the kernel module packages (no
+     changes required).
+   * Translation updates.
+     - Czech, thanks Martin Sin.
+     - Vietnamese, thanks Clytie Siddall.
+     - French, thanks Christian Perrier.
+ 
+  -- Russ Allbery &lt;rra@stanford.edu&gt;  Fri, 26 Aug 2005 01:30:21 -0700
+ 
+ openafs (1.3.87-1) unstable; urgency=low
+ 
+   * New upstream version.
+     - Fixes build problems with 2.6.12.3 and later.  (Closes: #320099)
+   * Add support for ppc64, thanks Andreas Jochens.  (Closes: #322020)
+   * Improve the openafs-client init script.
+     - Update the default client options based on the cache tuning synopsis
+       by Jeffrey Hutzelman, including setting a larger chunksize for all
+       default option sets.  (Closes: #303944)
+     - Choose the client options based on the cache size by default.
+     - Move the code to build the options string to the init script from
+       afs.conf so that afs.conf is pure configuration.
+     - Add an AFS_PRE_SHUTDOWN hook called before shutting down the client.
+     - Provide a shutdown hook, disabled by default, that kills all
+       processes with files open in /afs.  Enabling this ensures a more
+       reliable clean shutdown and umounting of the cache partition, but
+       may not always be what the admin wants.
+     - Improve the readability of the output on start.
+     - Significantly improve the comments in afs.conf.
+     - Remove the code to set -nosettime as it's now the default.
+   * Move the openafs-client init script and afs.conf file we use into the
+     debian directory rather than patching the upstream version.  We've
+     diverged so much that there's no point in continuing to merge changes.
+   * Diagnose unsupported architectures earlier and with a clearer error.
+   * Suppress error messages from a missing kernel version header since
+     they occur normally when doing the regular package build and are just
+     confusing.  Instead, print an error in kern-sysname and abort if the
+     kernel version could not be determined.
+   * Rework how PAM modules are handled.
+     - Build against the pthread-aware libraries.  (Closes: #297804)
+     - Use the shared library objects instead of building separate PIC
+       objects, eliminating the need for many Makefile modifications.
+     - Include pam_afs.krb.so as well.  (Closes: #165972)
+   * Don't include the empty /usr/src/modules directory in
+     openafs-modules-source, only the tarball, to match how other kernel
+     module source packages behave.  (Closes: #244685)
+   * Update config.guess and config.sub.
+   * Translation updates.
+     - French, thanks Christian Perrier.  (Closes: #318807)
+     - Vietnamese, thanks Clytie Siddall.  (Closes: #319705)
+     - Czech, thanks Martin Sin.  (Closes: #319940)
+ 
+  -- Russ Allbery &lt;rra@stanford.edu&gt;  Sun, 14 Aug 2005 14:41:48 -0700
+ 
+ openafs (1.3.82-2) unstable; urgency=low
+ 
+   * Output error messages from heredocs in the init script with cat rather
+     than echo.  Thanks, Reid Barton.  (Closes: #311729)
+   * Make bosserver less picky about permissions and remove the attempt to
+     set /etc/openafs/server-local not-world-readable since dh_fixperms was
+     overridding it anyway.  (Closes: #312921)
+   * Fix some spacing and capitalization errors in the debconf templates.
+     Thanks, Clytie Siddall.  (Closes: #316597)
+   * Initial Czech translation, thanks Martin Sin.  (Closes: #310699)
+   * New Vietnamese translation, thanks Clytie Siddall.  (Closes: #316598)
+   * Update standards version to 3.6.2 (no changes required).
+ 
+  -- Russ Allbery &lt;rra@stanford.edu&gt;  Mon, 11 Jul 2005 17:34:13 -0700
+ 
+ openafs (1.3.82-1) unstable; urgency=medium
+ 
+   * New upstream version.  (Closes: #307699)
+     - Proper locking for preempt kernels.  This bug manifested as an
+       inability to shut down AFS cleanly.  (Closes: #308399, #304040)
+     - Correctly handle the inotify semaphore.  (Closes: #303495)
+   * Repackage upstream to remove MacOS-specific files covered by the APSL.
+     Remove the WINNT directory to save space since we have to repackage
+     anyway.  Provide a get-orig-source target to do the repackaging.
+   * libpam-openafs-kaserver: Fix compilation so that the PAM module isn't
+     missing symbols and therefore unusable.  (Closes: #308844)
+   * Apply patch from Chas Williams to fix stale cache data from deleted
+     files, a bug introduced in 1.3.82.
+   * In all cases, only build the module appropriate to the kernel we're
+     building against.  Building an SMP module against a non-SMP kernel
+     fails due to missing defines.  (Closes: #225907)
+   * README.modules: Add documentation for module-assistant and recommend
+     it when using Debian kernels.  Mention divergences from upstream in
+     module naming.  (Closes: #253168)  Emphasize that the kernel source
+     tree used for make-kpkg must be identically configured to the kernel
+     the module will be used with.
+   * Update copyright with more complete information from upstream
+     src/LICENSE.
+   * Simplify clean target.  Upstream make distclean is now better.
+ 
+  -- Russ Allbery &lt;rra@stanford.edu&gt;  Tue, 10 May 2005 21:09:55 -0700
+ 
+ openafs (1.3.81-5) unstable; urgency=low
+ 
+   * Handle modules named either with or without the .mp extension on SMP
+     hosts.  (Closes: #305389, #307280, #307797)
+   * README.Debian: Document that the client cache partition must be ext2
+     or ext3 and that XFS and ReiserFS will not work.  upserver and
+     upclient are now provided.  Provide some information about why
+     kaserver is not provided.  (Closes: #249315)
+   * Overhaul the module build rules.
+     - Use debhelper to build the module binary package.
+     - Let debhelper handle the module postinst and prerm control scripts.
+     - Properly support modules_config and modules_clean.
+     - Break the build process into configure, build, install, and binary
+       rules, paralleling the regular build rules and making it easier to
+       maintain the make-kpkg build targets.
+     - Include the kernel version in the long description.
+     - Update standards version of module packages to 3.6.1.
+     - Include the copyright and basic documentation in the module binary
+       package.  Otherwise, policy requires an exact versioned dependency
+       on the package containing the copyright file.
+   * Update standards version to 3.6.1.
+     - Install Debian::OpenAFS::ConfigUtils in /usr/share, not /usr/lib.
+     - Always enable debugging symbols and disable optimization if noopt is
+       set in DEB_BUILD_OPTIONS.  (Alas, this doesn't entirely work; the
+       upstream makefiles don't always honor the configure options.)
+     - /etc/init.d/openafs-fileserver restart starts bosserver if it's not
+       already running.
+   * Update debhelper compatibility level to V4.
+     - Remove all *.conffiles control files.  They're no longer needed.
+     - Use misc:Depends to get debconf dependencies.
+     - Use dh_install rather than the movefiles script.
+   * openafs-dbserver doesn't need to depend on debconf.
+   * Use dh_perl to get the correct Perl dependency for openafs-dbserver.
+   * Remove unnecessary build dependencies.
+   * Depend on comerr-dev rather than e2fslibs-dev.
+   * Remove unnecessary preinst for openafs-fileserver.
+   * Clean up and reformat package build rules.
+   * Update lintian overrides.
+ 
+  -- Russ Allbery &lt;rra@stanford.edu&gt;  Sat,  7 May 2005 20:57:12 -0700
+ 
+ openafs (1.3.81-4) unstable; urgency=low
+ 
+   * make-kpkg doesn't run fakeroot for us but instead expects the module
+     rules file to use $(ROOT_CMD) appropriately.  (Closes: #237861)
+   * Put the compiled modules into KPKG_DEST_DIR if set.  This appears to
+     be preferred over DEB_DEST by the make-kpkg documentation.  Thanks,
+     Jonas Smedegaard.  (Closes: #206403)
+   * Add a check to afs-newcell to ensure the local hostname doesn't
+     resolve to 127.0.0.1.  (Closes: #163751)
+   * Exclude .svn directories from the modules source tarball.
+   * Fix genchanges for module builds to not fail when trying to remove a
+     nonexistent file.
+     * New French translations from Christian Perrier, Closes: #305780
+ 
+  -- Russ Allbery &lt;rra@stanford.edu&gt;  Sun, 17 Apr 2005 00:00:27 -0700
+ 
+ openafs (1.3.81-3) unstable; urgency=low
+ 
+   * Patch from kcr to fix osconf.m4 so that sparc defines afs_pthread_env
+     and thus builds.
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Wed,  6 Apr 2005 19:54:24 -0400
+ 
+ openafs (1.3.81-2) unstable; urgency=low
+ 
+   * Oops, update debian/sysname because hppa is hppa not parisc-*-linux-*
+     since we now use dpkg --print-installation-architecture
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Wed,  6 Apr 2005 11:10:14 -0400
+ 
+ openafs (1.3.81-1) unstable; urgency=low
+ 
+   * New Upstream version
+   * Use Linux 2.4 as the claimed userspace OS for alpha; hopefully this
+     resolves the  largefile issue and allows us to build again, Closes: #271923
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Wed,  6 Apr 2005 08:08:29 -0400
+ 
+ openafs (1.3.80-1) UNRELEASED; urgency=low
+ 
+   *  New upstream version, Closes: #297781
+   * I think this works on sparc better and definitely works on 2.6.10, Closes: #283488
+   * Make thiscell a high debconf value, Closes: #302939
+   * New upstream version (1.3.79)
+         - Works with 2.6.10, Closes: #296835
+   * Use amd64 not x86_64 for sysname script, Closes: #296855
+   * Patches from kcr
+       - Loosen dependencies for client and modules
+       - Enable debugging
+       - Some callbacks later stuff and fix short bitfield
+       - Fix permissions on /etc/openafs/server-local, Closes: #271460
+   
+   * Versions 1.3.79 an newer work on amd64, Closes: #262382
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Mon,  4 Apr 2005 00:32:42 -0400
+ 
+ openafs (1.3.77-1) unstable; urgency=low
+ 
+   * New upstream version
+   * Target for unstable not experimental
+   * New CellServDB
+   * OpenAFS seems not to have a changelog available, so stop shipping it.
+   * Build openafs.ko not libafs.ko so the right name appears in lsmod
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sat,  8 Jan 2005 20:02:23 -0500
+ 
+ openafs (1.3.74-1) experimental; urgency=low
+ 
+   * New upstream version
+ 
+  -- Sam Hartman &lt;hartmans@mit.edu&gt;  Mon, 15 Nov 2004 16:58:02 -0500
+ 
+ openafs (1.3.73-1) experimental; urgency=low
+ 
+   * New upstream version
+     -  Works with 2.6.8 and 2.6.9, Closes: #277521
+   * Remove call to dh_suidregister
+   * Update sysname to prefer 2.4 on more arches for largefile issues
+   * Patch from pnelson@ANDREW.CMU.EDU to add x86_64 support to sysname scripts
+   * debian/sysname: Use installation architecture 
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Wed, 27 Oct 2004 20:42:12 -0400
+ 
+ openafs (1.3.71-1) experimental; urgency=low
+ 
+   * New upstream version
+ 
+  -- Sam Hartman &lt;hartmans@mit.edu&gt;  Tue, 31 Aug 2004 09:45:59 -0400
+ 
+ openafs (1.3.70-1) experimental; urgency=low
+ 
+   * New upstream version
+   * debian/kern-sysname: 2.6* not 2.6
+   * Enable supergroups and largefile-fileserver
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sun, 15 Aug 2004 18:56:48 -0400
+ 
+ openafs (1.3.65-1) experimental; urgency=low
+ 
+   * New upstream Version, Closes: #256580
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Mon, 28 Jun 2004 19:40:30 -0400
+ 
+ openafs (1.3.64-2) experimental; urgency=low
+ 
+   * Allow loading of a .ko file not just .o
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Mon, 31 May 2004 13:46:05 -0400
+ 
+ openafs (1.3.64-1) experimental; urgency=low
+ 
+   * New upstream version
+   * Add 2.6 to kern-sysname for i386
+   * Apply patch from
+     /afs/cs.cmu.edu/user/jhutz/junk/openafs-patches/openafs-build-on-linux26  which correctly generates 2.6 modules, Closes: #234284
+   * use make only_libafs not dest_only_libafs
+     - AS a result, build times are much faster, Closes: #144781
+   * Correct module build scripts to install module package from new location
+   * Fix afslocaldir to be /etc/openafs/server-local, Closes: #237154
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sun, 30 May 2004 18:12:54 -0400
+ 
+ openafs (1.2.12-1) unstable; urgency=medium
+ 
+   * New upstream version
+   * Medium urgency because this version fixes a significant server crash
+     bug.  Windows clients, particularly greater than version 1.3.70 tend
+     to crash openafs servers.
+   * Cause openafs-kpasswd to conflict  with kerberos4kth-clients, Closes:
+     #277844 
+   * Conflict between libopenafs-dev and arla-dev, Closes: #274788
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Fri, 22 Oct 2004 16:21:29 -0400
+ 
+ openafs (1.2.11-3) unstable; urgency=high
+ 
+   * Now that libopenafs-dev contains binaries, it should have shared
+     library dependencies, Closes: #267509
+   * New fr.po from Christian Perrier, Closes: #237098
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Tue, 24 Aug 2004 12:10:02 -0400
+ 
+ openafs (1.2.11-2) unstable; urgency=low
+ 
+   * Install rxgen
+   * Install upserver and upclient
+   * Mark as version 1.2.11, Closes: #255883
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Thu, 12 Aug 2004 14:27:39 -0400
+ 
+ openafs (1.2.11-1) unstable; urgency=high
+ 
+   * Versions prior to 1.2.10 stopped working with multiple servers in a
+     cell because of a ubik bug prompting the 1.2.11 release.
+   * Fix afs startup script not to start afsd if already running; really
+     fixed in 1.2.10-3, but not documented, Closes: #219702
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sat, 10 Jan 2004 16:37:33 -0500
+ 
+ openafs (1.2.10-3) unstable; urgency=low
+ 
+   * Fix Openafs not to include kernel headers from /usr/include,
+   Closes: #220600 
+   * Fix typo in openafs templates, Closes: #215714
+   * New French translations, Closes: #216158
+   * Build-depend on e2fslibs-dev to get appropriate headers
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Thu, 20 Nov 2003 16:02:45 -0500
+ 
+ openafs (1.2.10-2) unstable; urgency=low
+ 
+   * New Brazilian Portuguese (pt_BR) translations, Closes: #208035
+   * Don't conflict with ircd, Closes: #204865
+   * Fix wording of question about using dynroot, Closes: #209332
+   * New French debconf translations, sorry about the delay in including these, Closes: #203608
+   * Avoid yes/no construction in openafs-client templates, Closes: #198476
+   * Fix libpam-openafs-kaserver to include the symbols it needs, patch
+     from Daniel Joseph Barnhart Clark , Closes: #194818
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Mon, 13 Oct 2003 00:38:42 -0400
+ 
+ openafs (1.2.10-1) unstable; urgency=low
+ 
+   * New upstream version
+   * net/*.h included properly by kernel module, Closes: #204642
+   * Don't build libafsrpc or libafsauthent, as we can't exactly use them
+     because they contain non-pic code, Closes: #203456
+   * I think I finally build the PAM module on hppa, Closes: #179679
+   * Decnet includes should work now because of the change of the net
+     symlink, Closes: #204486
+   * Escape $ in debian/rules, Closes: #204185
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sun, 24 Aug 2003 18:03:21 -0400
+ 
+ openafs (1.2.9-3) unstable; urgency=low
+ 
+   * Add support for kernel headers, thanks to Patrick Sodre, 
+     Closes: #173137 
+   * Add patch to support the Debian 2.4.21 Kernel sources, thanks to amu,
+     Closes: #198774
+   * Add chronyd to list of programs we assume set the clock, thanks RISKO
+     Gergely, Closes: #201725
+   * Fix template formatting (extra leading spaces), Closes: #198477
+   * New French translations, thanks Christian Perrier, Closes: #198719
+   * Fix PAM problem on hppa, Closes: #179679
+   * Don't translate defaults: Closes: #198384
+   * Fix movefiles error handling and errors exposed by this change.  The
+     contents of libopenafs-dev  were somewhat wrong because of this.
+   * Make /usr/src/modules root.src 775, Closes: #201733
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sat, 26 Jul 2003 18:03:31 -0400
+ 
+ openafs (1.2.9-2) unstable; urgency=low
+ 
+   * Fix   to not build PAM krb since we don't install it and it breaks alpha, Closes: #189548
+   * Don't install pagsh man page symlink since we no longer link to
+     undocumented, Closes: #189860
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Mon, 21 Apr 2003 21:05:51 -0400
+ 
+ openafs (1.2.9-1) unstable; urgency=low
+ 
+   * Literal newline fixes, Closes: #175627
+   * Require new kernel modules per upstream change.
+   * New upstream version
+   * Fix section of libopenafs-dev to libdevel
+   * openafs-client stop should shut down afsd if it is running even if afs
+     not mounted, Closes: #188000
+       * Fix to build on alpha again; PAM patch was broken
+   * Report i386_linux24 not linux22 on i386, Closes: #187789
+   * Convert to po-debconf, patch from Andre Luis Lopes, CLoses: #187901
+   * Fix from Lamont to build on hppa, Closes: #179679
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sun, 13 Apr 2003 17:21:54 -0400
+ 
+ openafs (1.2.8-4) unstable; urgency=low
+ 
+   * Fix from Eduard Bloch to compile on kernels with variable numbers of
+     CPUs; he is not sure it actually works yet though, Closes: #178505
+   * Patch that might possibly fix the fails to build on recent unstable;
+     definitely fixes a bug in include path handling, but I am not sure it
+     is a correct patch since I cannot reproduce the problem, Closes: #178154
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sun,  2 Feb 2003 14:08:14 -0500
+ 
+ openafs (1.2.8-3) unstable; urgency=medium
+ 
+   * Patch from Eduard Bloch &lt;blade@debian.org&gt; to build the PAM module for
+     kaserver users; the main thing this patch does in create a bunch of
+     PIC object files so it is a policy-conformant shared library, Closes:
+     #174668 
+   * Do not include -I/usr/include and especially -I/usr/include/sys in the
+     PAM Makefile so gcc 3.2 works; already fixed upstream, Closes: #176538
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sun, 19 Jan 2003 17:44:53 -0500
+ 
+ openafs (1.2.8-2) unstable; urgency=low
+ 
+   * Convert v5 principal names to v4 style names in rxkad 2b.  Especially
+     important for rcmd vs host
+   * Fix debian/rules clean to remove  generated files, Closes: #174625
+   * Fix AFS not to declare errno, Closes: #174059
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Fri,  3 Jan 2003 15:28:30 -0500
+ 
+ openafs (1.2.8-1) unstable; urgency=low
+ 
+   * New upstream version
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Tue, 10 Dec 2002 23:43:46 -0500
+ 
+ openafs (1.2.7-3) unstable; urgency=low
+ 
+   * Apparently OpenAFS and  ircd conflict on a UDP port, so you can't use
+     both at once, Closes: #150242
+   * Patch from seph to add -nosettime when ntp is installed, Closes: #155123
+   * Fix bosserver  shutdown on restart after upgrade, Closes :#155586
+   * Install translate_et, Closes: #138672
+   * Allow byacc instead of bison
+   
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Tue,  3 Dec 2002 22:30:44 -0500
+ 
+ openafs (1.2.7-2) unstable; urgency=low
+ 
+   * Fix uss to build with bison 1.50 and 1.75 so we can throw away the
+     resulting binaries, Closes: #164366
+   * Evaluate all limited range of comparison warnings; a warning in
+     rxkad_client.c remains but is harmless, other warnings pointed to
+     potential problems that were fixed, Closes: #162754
+   * Fix s390 modules to actually build, Closes: #162772
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Sun, 20 Oct 2002 15:20:19 -0400
+ 
+ openafs (1.2.7-1) unstable; urgency=low
+ 
+   * Fix typo in templates, Closes: #150356
+   
+   * New upstream version
+ 
+  -- Sam Hartman &lt;hartmans@debian.org&gt;  Thu, 26 Sep 2002 16:11:25 -0400
+ 
  openafs (1.2.6-1) unstable; urgency=low
  
  
***************
*** 308,318 ****
    * Only run init script once; confusion with DH_OPTIONS
    * Fix bosserver to look in /usr/openafs/lib so it restarts correctly every Sunday.
    * Upload to Debian (Gloses: BUG#69336)
!  -- Sam Hartman &lt;hartmans@debian.org&gt;  Wed,  6 Dec 2000 11:21:53 -0500
! 
! Do not generate .map file for module; depmod complains.  * 
  
!  --
  
  openafs (1.0.1-1) unstable; urgency=low
  
--- 882,890 ----
    * Only run init script once; confusion with DH_OPTIONS
    * Fix bosserver to look in /usr/openafs/lib so it restarts correctly every Sunday.
    * Upload to Debian (Gloses: BUG#69336)
!   * Do not generate .map file for module; depmod complains.
  
!  -- Sam Hartman &lt;hartmans@debian.org&gt;  Wed,  6 Dec 2000 11:21:53 -0500
  
  openafs (1.0.1-1) unstable; urgency=low
  
***************
*** 434,440 ****
  
   -- unknown &lt;hartmans@snorklewacker.mit.edu&gt;  Fri,  3 Nov 2000 23:41:41 -0500
  
- Local variables:
- mode: debian-changelog
- add-log-mailing-address "hartmans@snorklewacker.mit.edu"
- End:
--- 1006,1008 ----
Index: openafs/src/packaging/Debian/compat
diff -c /dev/null openafs/src/packaging/Debian/compat:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/compat	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1 ----
+ 4
Index: openafs/src/packaging/Debian/control
diff -c openafs/src/packaging/Debian/control:1.1 openafs/src/packaging/Debian/control:1.2
*** openafs/src/packaging/Debian/control:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/control	Thu Mar 23 15:19:07 2006
***************
*** 2,15 ****
  Section: net
  Priority: optional
  Maintainer: Sam Hartman &lt;hartmans@debian.org&gt;
! Build-Depends: debhelper (&gt;= 2.2.20), libncurses5-dev, libpam0g-dev, bison, docbook-to-man, flex, autoconf, automake, perl
! Standards-Version: 3.5.0
  
  Package: openafs-client
! Architecture: i386 powerpc sparc alpha s390 ia64
! Depends: ${shlibs:Depends}, debconf,  openafs-modules-source|openafs-modules1
! Conflicts: arla, openafs-modules
! Description: The AFS distributed filesystem- client support
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
--- 2,18 ----
  Section: net
  Priority: optional
  Maintainer: Sam Hartman &lt;hartmans@debian.org&gt;
! Uploaders: Russ Allbery &lt;rra@debian.org&gt;
! Build-Depends: debhelper (&gt;= 4.1.16), libncurses5-dev, libpam0g-dev, bison, docbook-to-man, flex, perl, comerr-dev
! Standards-Version: 3.6.2
  
  Package: openafs-client
! Architecture: i386 powerpc sparc alpha s390 ia64 hppa amd64 ppc64
! Depends: ${shlibs:Depends}, ${misc:Depends}
! Recommends: openafs-modules-source (&gt;= 1.2.9) | openafs-modules2
! Suggests: openafs-doc
! Conflicts: arla, openafs-modules1
! Description: AFS distributed filesystem client support
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
***************
*** 19,42 ****
  
  Package: openafs-kpasswd
  Priority: extra
! Architecture: i386 powerpc sparc alpha  s390 ia64
! Depends: ${shlibs:Depends}, openafs-client (= ${Source-Version})
! Conflicts: krb5-user, heimdal-clients
! Description: The AFS distributed filesystem- old password changing
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
   .
!  This package provides kpasswd and kas, utilities needed by the 
!  Transarc kaserver to create users and change passwords.  Only install
!  this package if you are already using kaserver; generally you should
!  not install this package for new cells or for cells using Kerberos5.
  
  Package: openafs-fileserver
! Architecture: i386 powerpc sparc alpha s390 ia64
! Depends: ${shlibs:Depends}, debconf, openafs-client (= ${Source-Version})
  Recommends: ntp
! Description: The AFS distributed filesystem- file server
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
--- 22,46 ----
  
  Package: openafs-kpasswd
  Priority: extra
! Architecture: i386 powerpc sparc alpha s390 ia64 hppa amd64 ppc64
! Depends: ${shlibs:Depends}, openafs-client
! Conflicts: krb5-user, heimdal-clients, kerberos4kth-clients
! Description: AFS distributed filesystem old password changing
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
   .
!  This package provides kpasswd and kas, utilities needed by the OpenAFS
!  kaserver to create users and change passwords.  Only install this package
!  if you are already using kaserver; generally you should not install this
!  package for new cells or for cells using Kerberos v5.
  
  Package: openafs-fileserver
! Architecture: i386 powerpc sparc alpha s390 ia64 hppa amd64 ppc64
! Depends: ${shlibs:Depends}, ${misc:Depends}, openafs-client
  Recommends: ntp
! Suggests: openafs-doc
! Description: AFS distributed filesystem file server
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
***************
*** 45,56 ****
   installed on any machine that will export files into AFS.
  
  Package: openafs-dbserver
! Architecture: i386 powerpc sparc alpha s390 ia64
! Depends: ${shlibs:Depends}, debconf, openafs-fileserver (= ${Source-Version}), openafs-client (= ${Source-Version}), perl5
  Conflicts: openafs-ptutil
  Replaces: openafs-ptutil
  Provides: openafs-ptutil
! Description: The AFS distributed filesystem- database server
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
--- 49,61 ----
   installed on any machine that will export files into AFS.
  
  Package: openafs-dbserver
! Architecture: i386 powerpc sparc alpha s390 ia64 hppa amd64 ppc64
! Depends: ${shlibs:Depends}, ${perl:Depends}, openafs-fileserver, openafs-client
! Suggests: openafs-doc
  Conflicts: openafs-ptutil
  Replaces: openafs-ptutil
  Provides: openafs-ptutil
! Description: AFS distributed filesystem database server
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
***************
*** 60,69 ****
   protection servers.
  
  Package: libopenafs-dev
! Section: devel
! Architecture: i386 powerpc sparc alpha s390 ia64
  Priority: extra
! Description: The AFS distributed filesystem- development libraries
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
--- 65,77 ----
   protection servers.
  
  Package: libopenafs-dev
! Section: libdevel
! Architecture: i386 powerpc sparc alpha s390 ia64 hppa amd64 ppc64
  Priority: extra
! Depends: ${shlibs:Depends}
! Suggests: openafs-doc
! Conflicts: arla-dev
! Description: AFS distributed filesystem development libraries
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
***************
*** 73,84 ****
  
  Package: openafs-modules-source
  Priority: extra
! Depends: bison, flex, debhelper, libpam0g-dev, libncurses5-dev, kernel-package
  Architecture: all
! Description: The AFS distributed filesystem- Module Sources
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
   .
   This package provides source to the AFS kernel modules.
  
--- 81,103 ----
  
  Package: openafs-modules-source
  Priority: extra
! Depends: bison, flex, debhelper (&gt;= 4.0.0), kernel-package | module-assistant
  Architecture: all
! Description: AFS distributed filesystem kernel module source
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
   .
   This package provides source to the AFS kernel modules.
  
+ Package: libpam-openafs-kaserver
+ Priority: extra
+ Depends: ${shlibs:Depends}, openafs-client
+ Architecture: i386 powerpc sparc alpha s390 ia64 hppa amd64 ppc64
+ Description: AFS distributed filesystem kaserver PAM module
+  AFS is a distributed filesystem allowing cross-platform sharing of
+  files among multiple computers.  Facilities are provided for access
+  control, authentication, backup and administrative management.
+  .
+  This package provides a PAM module for existing  sites using the AFS
+  kaserver for authentication.  New sites should use a Kerberos v5
Index: openafs/src/packaging/Debian/control.module
diff -c openafs/src/packaging/Debian/control.module:1.1 openafs/src/packaging/Debian/control.module:1.2
*** openafs/src/packaging/Debian/control.module:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/control.module	Thu Mar 23 15:19:07 2006
***************
*** 2,16 ****
  Section: net
  Priority: optional
  Maintainer: Sam Hartman &lt;hartmans@debian.org&gt;
! Standards-Version: 3.1.1
  
  Package: openafs-modules-=KVERS
! Conflicts: openafs-client (&lt;&lt; 1.2.2-0)
! Provides: openafs-modules1
  Architecture: any
! Description: The AFS distributed filesystem- Kernel Module
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
   .
!  This package provides the kernel module for the filesystem
--- 2,20 ----
  Section: net
  Priority: optional
  Maintainer: Sam Hartman &lt;hartmans@debian.org&gt;
! Uploaders: Russ Allbery &lt;rra@debian.org&gt;
! Build-Depends: debhelper (&gt;= 4.1.16), flex, bison
! Standards-Version: 3.6.2
  
  Package: openafs-modules-=KVERS
! Conflicts: openafs-client (&lt;&lt; 1.2.9)
! Provides: openafs-modules2
  Architecture: any
! Recommends: =IMG-=KVERS
! Description: AFS distributed filesystem kernel module
   AFS is a distributed filesystem allowing cross-platform sharing of
   files among multiple computers.  Facilities are provided for access
   control, authentication, backup and administrative management.
   .
!  This package provides the compiled AFS kernel module for kernel
!  version =KVERS.
Index: openafs/src/packaging/Debian/copyright
diff -c openafs/src/packaging/Debian/copyright:1.1 openafs/src/packaging/Debian/copyright:1.2
*** openafs/src/packaging/Debian/copyright:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/copyright	Thu Mar 23 15:19:07 2006
***************
*** 1,9 ****
  This package was debianized by Sam Hartman &lt;hartmans@debian.org&gt; on
  Fri,  3 Nov 2000 23:41:41 -0500.
  
! It was downloaded from the Openafs CVS repository.
  
! Upstream Maintainers(s):openafs-gatekeepers@openafs.org
  
  Copyright:
  
--- 1,20 ----
  This package was debianized by Sam Hartman &lt;hartmans@debian.org&gt; on
  Fri,  3 Nov 2000 23:41:41 -0500.
  
! It was downloaded from either:
  
!     http://www.openafs.org/release/
!     /afs/grand.central.org/software/openafs/
! 
! Upstream Maintainers:
! 
!     openafs-gatekeepers@openafs.org
! 
! The upstream source has been repackaged to remove the src/packaging/MacOS
! directory, which contained a file (afssettings.m) that was covered under
! the Apple Public Source License 2.0.  This license is not considered
! DFSG-free.  Since the repackaging was needed anyway, the WINNT directory
! was also dropped, reducing the size of the upstream tarball by 8MB.
  
  Copyright:
  
***************
*** 240,242 ****
--- 251,343 ----
     party to this Agreement will bring a legal action under this Agreement
     more than one year after the cause of action arose. Each party waives
     its rights to a jury trial in any resulting litigation.
+ 
+ Kerberos 5 ticket support in rxkad is subject to the following copyright:
+ /*
+  * Copyright (c) 1995, 1996, 1997, 2002 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ Some code in rxkad/ticket5.c is subject to the following copyright:
+ /*
+  * Copyright 1992, 2002 by the Massachusetts Institute of Technology.
+  * All Rights Reserved.
+  *
+  * Export of this software from the United States of America may
+  *   require a specific license from the United States Government.
+  *   It is the responsibility of any person or organization contemplating
+  *   export to obtain such a license before exporting.
+  * 
+  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+  * distribute this software and its documentation for any purpose and
+  * without fee is hereby granted, provided that the above copyright
+  * notice appear in all copies and that both that copyright notice and
+  * this permission notice appear in supporting documentation, and that
+  * the name of M.I.T. not be used in advertising or publicity pertaining
+  * to distribution of the software without specific, written prior
+  * permission.  Furthermore if you modify this software you must label
+  * your software as modified software and not distribute it in such a
+  * fashion that it might be confused with the original M.I.T. software.
+  * M.I.T. makes no representations about the suitability of
+  * this software for any purpose.  It is provided "as is" without express
+  * or implied warranty.
+  */
+ 
+ Some portions of Rx are subject to the following license:
+ /*
+  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+  * unrestricted use provided that this legend is included on all tape
+  * media and as a part of the software program in whole or part.  Users
+  * may copy or modify Sun RPC without charge, but are not authorized
+  * to license or distribute it to anyone else except as part of a product or
+  * program developed by the user or with the express written consent of
+  * Sun Microsystems, Inc.
+  *
+  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+  *
+  * Sun RPC is provided with no support and without any obligation on the
+  * part of Sun Microsystems, Inc. to assist in its use, correction,
+  * modification or enhancement.
+  *
+  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+  * OR ANY PART THEREOF.
+  *
+  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+  * or profits or other special, indirect and consequential damages, even if
+  * Sun has been advised of the possibility of such damages.
+  *
+  * Sun Microsystems, Inc.
+  * 2550 Garcia Avenue
+  * Mountain View, California  94043
+  */
Index: openafs/src/packaging/Debian/genchanges.sh
diff -c openafs/src/packaging/Debian/genchanges.sh:1.1 openafs/src/packaging/Debian/genchanges.sh:1.2
*** openafs/src/packaging/Debian/genchanges.sh:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/genchanges.sh	Thu Mar 23 15:19:07 2006
***************
*** 2,22 ****
  # genchanges.sh - generate a changes file for a deb file generated via
  #	the make-kpkg utility
  
! # KSRC KMAINT and KEMAIL are expected to be passed through the environment
  
  set -e
  umask 022
  
- #KVERS=`cat debian/KVERS`
  MODVERS=`cat debian/VERSION | sed s/:/\+/`
  ARCH=`dpkg --print-architecture`
  
  mprefix=`grep Package: debian/control.module | cut -d' ' -f 2 | cut -d= -f 1`
- 
- # the changes file's name
  chfile="$KSRC/../$mprefix${KVERS}${INT_SUBARCH}_${MODVERS}_${ARCH}.changes"
  
  dpkg-genchanges -b ${KMAINT:+-m"$KMAINT &lt;$KEMAIL&gt;"} -u"$KSRC/.." \
! 	-cdebian/control &gt; "$chfile"
! #pgp -fast ${KMAINT:+-u"$KMAINT"} &lt; "$chfile.pt" &gt; "$chfile"
! rm "$chfile.pt"
--- 2,19 ----
  # genchanges.sh - generate a changes file for a deb file generated via
  #	the make-kpkg utility
  
! # KSRC, KVERS, KMAINT, and KEMAIL are expected to be passed through the
! # environment.
  
  set -e
  umask 022
  
  MODVERS=`cat debian/VERSION | sed s/:/\+/`
  ARCH=`dpkg --print-architecture`
  
  mprefix=`grep Package: debian/control.module | cut -d' ' -f 2 | cut -d= -f 1`
  chfile="$KSRC/../$mprefix${KVERS}${INT_SUBARCH}_${MODVERS}_${ARCH}.changes"
  
  dpkg-genchanges -b ${KMAINT:+-m"$KMAINT &lt;$KEMAIL&gt;"} -u"$KSRC/.." \
!     -cdebian/control &gt; "$chfile"
! #debsign "$chfile"
Index: openafs/src/packaging/Debian/kern-sysname
diff -c openafs/src/packaging/Debian/kern-sysname:1.2 openafs/src/packaging/Debian/kern-sysname:1.3
*** openafs/src/packaging/Debian/kern-sysname:1.2	Thu Jan 13 20:35:43 2005
--- openafs/src/packaging/Debian/kern-sysname	Thu Mar 23 15:19:07 2006
***************
*** 1,68 ****
  #!/bin/sh
  case `arch` in
  i[3456]86)
! 	case $KVERS in
! 	    2.2*)
! 		echo i386_linux22
! 		;;
! 	    2.4*)
! 		echo i386_linux24
! 		;;
! 	    esac
! ;;
!     ia64)
! 	case $KVERS in
! 	    2.4*)
! 		echo ia64_linux24
! 		;;
! 	    2.6*)
! 		echo ia64_linux26
! 		;;
! 	    esac
! 	;;
!     alpha)
! 	case $KVERS in
! 	    2.2*)
! 		echo alpha_linux_22
! 		;;
! 	    2.4*)
! 		echo alpha_linux_24
! 		;;
! 	    esac
! ;;
!     sparc)
! 	case $KVERS in
! 	    2.2*)
! 		echo sparc_linux22
! 		;;
! 	    2.4*)
! 		echo sparc_linux24
! 		;;
! 	    esac
! 	;;
!     sparc64)
!         case $KVERS in
! 	    2.2*)
! 		echo sparc64_linux22
! 		;;
! 	    2.4*)
! 		echo sparc64_linux24
! 		;;
! 	    esac
! 	;;
! 	    
!     ppc)
! 	case $KVERS in
! 	    2.2*)
! 		echo ppc_linux22
! 		;;
! 	    2.4*)
! 		echo ppc_linux24
! 		;;
! 	    esac
! 	    ;;
! 	*)
! 	echo ERROr:  sysname not yet known
! 	exit 1
! 
  esac
--- 1,97 ----
  #!/bin/sh
+ 
+ if [ x"$KVERS" = x ] ; then
+     echo "ERROR: no kernel version" &gt;&amp;2
+     echo "  ($KSRC/include/linux/version.h not found?)" &gt;&amp;2
+     echo UNKNOWN
+     exit 1
+ fi
+ 
  case `arch` in
  i[3456]86)
!     case $KVERS in
!     2.2*)
!         echo i386_linux22
!         ;;
!     2.4*)
!         echo i386_linux24
!         ;;
!     2.6*)
!         echo i386_linux26
!         ;;
!     esac
!     ;;
! x86_64)
!     case $KVERS in
!     2.4*)
!         echo amd64_linux24
!         ;;
!     2.6*)
!         echo amd64_linux26
!         ;;
!     esac
!     ;;
! ia64)
!     echo ia64_linux24
!     ;;
! alpha)
!     case $KVERS in
!     2.2*)
!         echo alpha_linux_22
!         ;;
!     2.4*)
!         echo alpha_linux_24
!         ;;
!     esac
!     ;;
! sparc)
!     case $KVERS in
!     2.2*)
!         echo sparc_linux22
!         ;;
!     2.4*)
!         echo sparc_linux24
!         ;;
!     esac
!     ;;
! sparc64)
!     case $KVERS in
!     2.2*)
!         echo sparc64_linux22
!         ;;
!     2.4*)
!         echo sparc64_linux24
!         ;;
!     esac
!     ;;
! ppc)
!     case $KVERS in
!     2.2*)
!         echo ppc_linux22
!         ;;
!     2.4*)
!         echo ppc_linux24
!         ;;
!     2.6)
!         echo ppc_linux26
!         ;;
!     esac
!     ;;
! ppc64)
!     case $KVERS in
!     2.4*)
!         echo ppc64_linux24
!         ;;
!     2.6*)
!         echo ppc64_linux26
!         ;;
!     esac
!     ;;
! s390)
!     echo s390_linux24
!     ;;
! *)
!     echo "ERROR: unsupported architecture" &gt;&amp;2
!     echo UNKNOWN
!     exit 1
  esac
Index: openafs/src/packaging/Debian/kernel-version
diff -c /dev/null openafs/src/packaging/Debian/kernel-version:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/kernel-version	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1,15 ----
+ #!/usr/bin/perl
+ #
+ # Extract the kernel version from the kernel version header file.  Takes the
+ # kernel source path as its only argument.  If the version header couldn't be
+ # found, print nothing and exit quietly.
+ 
+ my $ksrc = shift;
+ unless ($ksrc &amp;&amp; open (VERSION, "$ksrc/include/linux/version.h")) {
+     exit 0;
+ }
+ my $line = &lt;VERSION&gt;;
+ if ($line =~ /"(.+)"/) {
+     print "$1\n";
+ }
+ exit 0;
Index: openafs/src/packaging/Debian/libopenafs-dev.dirs
diff -c /dev/null openafs/src/packaging/Debian/libopenafs-dev.dirs:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/libopenafs-dev.dirs	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1 ----
+ usr/lib
Index: openafs/src/packaging/Debian/libopenafs-dev.install
diff -c /dev/null openafs/src/packaging/Debian/libopenafs-dev.install:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/libopenafs-dev.install	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1,8 ----
+ debian/tmp/usr/bin/rxgen                usr/bin
+ 
+ debian/tmp/usr/include                  usr
+ 
+ debian/tmp/usr/lib/*.a                  usr/lib
+ debian/tmp/usr/lib/afs                  usr/lib
+ 
+ debian/doc/man1/rxgen.1                 usr/share/man/man1
Index: openafs/src/packaging/Debian/libpam-openafs-kaserver.dirs
diff -c /dev/null openafs/src/packaging/Debian/libpam-openafs-kaserver.dirs:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/libpam-openafs-kaserver.dirs	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1,2 ----
+ lib/security
+ usr/share/doc
Index: openafs/src/packaging/Debian/openafs-client.config
diff -c openafs/src/packaging/Debian/openafs-client.config:1.1 openafs/src/packaging/Debian/openafs-client.config:1.2
*** openafs/src/packaging/Debian/openafs-client.config:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/openafs-client.config	Thu Mar 23 15:19:07 2006
***************
*** 1,6 ****
  #!/bin/sh -e
  
! . /usr/share/debconf/confmodule ||exit
  
  db_version 2.0
  if [ -r /etc/openafs/ThisCell ] ; then
--- 1,6 ----
  #!/bin/sh -e
  
! . /usr/share/debconf/confmodule || exit
  
  db_version 2.0
  if [ -r /etc/openafs/ThisCell ] ; then
***************
*** 15,21 ****
      IFS=: read mountpoint cachedir cachesize  &lt;/etc/openafs/cacheinfo
      db_set openafs-client/cachesize $cachesize
      fi
! db_input medium openafs-client/thiscell ||true
  db_input critical openafs-client/cachesize ||true
  db_go
  test -f /etc/openafs/afs.conf &amp;&amp;. /etc/openafs/afs.conf
--- 15,21 ----
      IFS=: read mountpoint cachedir cachesize  &lt;/etc/openafs/cacheinfo
      db_set openafs-client/cachesize $cachesize
      fi
! db_input high openafs-client/thiscell ||true
  db_input critical openafs-client/cachesize ||true
  db_go
  test -f /etc/openafs/afs.conf &amp;&amp;. /etc/openafs/afs.conf
Index: openafs/src/packaging/Debian/openafs-client.docs
diff -c openafs/src/packaging/Debian/openafs-client.docs:1.1 openafs/src/packaging/Debian/openafs-client.docs:1.2
*** openafs/src/packaging/Debian/openafs-client.docs:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/openafs-client.docs	Thu Mar 23 15:19:07 2006
***************
*** 2,6 ****
  debian/README.servers
  debian/configuration-transcript.txt
  debian/README.modules
- NEWS
- RELNOTES-1.2.6
--- 2,4 ----
Index: openafs/src/packaging/Debian/openafs-client.install
diff -c /dev/null openafs/src/packaging/Debian/openafs-client.install:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/openafs-client.install	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1,224 ----
+ debian/afs.conf                         etc/openafs
+ 
+ debian/tmp/usr/bin/afsmonitor           usr/bin
+ debian/tmp/usr/bin/bos                  usr/bin
+ debian/tmp/usr/bin/cmdebug              usr/bin
+ debian/tmp/usr/bin/fs                   usr/bin
+ debian/tmp/usr/bin/klog                 usr/bin
+ debian/tmp/usr/bin/livesys              usr/bin
+ debian/tmp/usr/bin/pagsh                usr/bin
+ debian/tmp/usr/bin/pts                  usr/bin
+ debian/tmp/usr/bin/scout                usr/bin
+ debian/tmp/usr/bin/sys                  usr/bin
+ debian/tmp/usr/bin/tokens               usr/bin
+ debian/tmp/usr/bin/translate_et         usr/bin
+ debian/tmp/usr/bin/udebug               usr/bin
+ debian/tmp/usr/bin/unlog                usr/bin
+ debian/tmp/usr/bin/up                   usr/bin
+ debian/tmp/usr/bin/xstat_cm_test        usr/bin
+ debian/tmp/usr/bin/xstat_fs_test        usr/bin
+ 
+ debian/tmp/usr/sbin/rxdebug             usr/bin
+ debian/tmp/usr/sbin/vos                 usr/bin
+ 
+ debian/tmp/usr/sbin/backup              usr/sbin
+ debian/tmp/usr/sbin/butc                usr/sbin
+ debian/tmp/usr/sbin/fms                 usr/sbin
+ debian/tmp/usr/sbin/fstrace             usr/sbin
+ 
+ debian/tmp/usr/sbin/afsd                sbin
+ 
+ src/afs/afszcm.cat                      usr/share/openafs
+ 
+ debian/CellServDB                       usr/share/openafs
+ 
+ debian/doc/man1/afs.1                   usr/share/man/man1
+ debian/doc/man1/afsmonitor.1            usr/share/man/man1
+ debian/doc/man1/bos.1                   usr/share/man/man1
+ debian/doc/man1/bos_addhost.1           usr/share/man/man1
+ debian/doc/man1/bos_addkey.1            usr/share/man/man1
+ debian/doc/man1/bos_adduser.1           usr/share/man/man1
+ debian/doc/man1/bos_apropos.1           usr/share/man/man1
+ debian/doc/man1/bos_create.1            usr/share/man/man1
+ debian/doc/man1/bos_delete.1            usr/share/man/man1
+ debian/doc/man1/bos_exec.1              usr/share/man/man1
+ debian/doc/man1/bos_getdate.1           usr/share/man/man1
+ debian/doc/man1/bos_getlog.1            usr/share/man/man1
+ debian/doc/man1/bos_getrestart.1        usr/share/man/man1
+ debian/doc/man1/bos_help.1              usr/share/man/man1
+ debian/doc/man1/bos_install.1           usr/share/man/man1
+ debian/doc/man1/bos_listhosts.1         usr/share/man/man1
+ debian/doc/man1/bos_listkeys.1          usr/share/man/man1
+ debian/doc/man1/bos_listusers.1         usr/share/man/man1
+ debian/doc/man1/bos_prune.1             usr/share/man/man1
+ debian/doc/man1/bos_removehost.1        usr/share/man/man1
+ debian/doc/man1/bos_removekey.1         usr/share/man/man1
+ debian/doc/man1/bos_removeuser.1        usr/share/man/man1
+ debian/doc/man1/bos_restart.1           usr/share/man/man1
+ debian/doc/man1/bos_salvage.1           usr/share/man/man1
+ debian/doc/man1/bos_setauth.1           usr/share/man/man1
+ debian/doc/man1/bos_setcellname.1       usr/share/man/man1
+ debian/doc/man1/bos_setrestart.1        usr/share/man/man1
+ debian/doc/man1/bos_shutdown.1          usr/share/man/man1
+ debian/doc/man1/bos_start.1             usr/share/man/man1
+ debian/doc/man1/bos_startup.1           usr/share/man/man1
+ debian/doc/man1/bos_status.1            usr/share/man/man1
+ debian/doc/man1/bos_stop.1              usr/share/man/man1
+ debian/doc/man1/bos_uninstall.1         usr/share/man/man1
+ debian/doc/man1/cmdebug.1               usr/share/man/man1
+ debian/doc/man1/fs.1                    usr/share/man/man1
+ debian/doc/man1/fs_apropos.1            usr/share/man/man1
+ debian/doc/man1/fs_checkservers.1       usr/share/man/man1
+ debian/doc/man1/fs_checkvolumes.1       usr/share/man/man1
+ debian/doc/man1/fs_cleanacl.1           usr/share/man/man1
+ debian/doc/man1/fs_copyacl.1            usr/share/man/man1
+ debian/doc/man1/fs_diskfree.1           usr/share/man/man1
+ debian/doc/man1/fs_examine.1            usr/share/man/man1
+ debian/doc/man1/fs_exportafs.1          usr/share/man/man1
+ debian/doc/man1/fs_flush.1              usr/share/man/man1
+ debian/doc/man1/fs_flushmount.1         usr/share/man/man1
+ debian/doc/man1/fs_flushvolume.1        usr/share/man/man1
+ debian/doc/man1/fs_getcacheparms.1      usr/share/man/man1
+ debian/doc/man1/fs_getcellstatus.1      usr/share/man/man1
+ debian/doc/man1/fs_getclientaddrs.1     usr/share/man/man1
+ debian/doc/man1/fs_getserverprefs.1     usr/share/man/man1
+ debian/doc/man1/fs_help.1               usr/share/man/man1
+ debian/doc/man1/fs_listacl.1            usr/share/man/man1
+ debian/doc/man1/fs_listcells.1          usr/share/man/man1
+ debian/doc/man1/fs_listquota.1          usr/share/man/man1
+ debian/doc/man1/fs_lsmount.1            usr/share/man/man1
+ debian/doc/man1/fs_messages.1           usr/share/man/man1
+ debian/doc/man1/fs_mkmount.1            usr/share/man/man1
+ debian/doc/man1/fs_newcell.1            usr/share/man/man1
+ debian/doc/man1/fs_quota.1              usr/share/man/man1
+ debian/doc/man1/fs_rmmount.1            usr/share/man/man1
+ debian/doc/man1/fs_setacl.1             usr/share/man/man1
+ debian/doc/man1/fs_setcachesize.1       usr/share/man/man1
+ debian/doc/man1/fs_setcell.1            usr/share/man/man1
+ debian/doc/man1/fs_setclientaddrs.1     usr/share/man/man1
+ debian/doc/man1/fs_setquota.1           usr/share/man/man1
+ debian/doc/man1/fs_setserverprefs.1     usr/share/man/man1
+ debian/doc/man1/fs_setvol.1             usr/share/man/man1
+ debian/doc/man1/fs_storebehind.1        usr/share/man/man1
+ debian/doc/man1/fs_sysname.1            usr/share/man/man1
+ debian/doc/man1/fs_whereis.1            usr/share/man/man1
+ debian/doc/man1/fs_whichcell.1          usr/share/man/man1
+ debian/doc/man1/fs_wscell.1             usr/share/man/man1
+ debian/doc/man1/klog.1                  usr/share/man/man1
+ debian/doc/man1/livesys.1               usr/share/man/man1
+ debian/doc/man1/pagsh.1                 usr/share/man/man1
+ debian/doc/man1/pts.1                   usr/share/man/man1
+ debian/doc/man1/pts_adduser.1           usr/share/man/man1
+ debian/doc/man1/pts_apropos.1           usr/share/man/man1
+ debian/doc/man1/pts_chown.1             usr/share/man/man1
+ debian/doc/man1/pts_creategroup.1       usr/share/man/man1
+ debian/doc/man1/pts_createuser.1        usr/share/man/man1
+ debian/doc/man1/pts_delete.1            usr/share/man/man1
+ debian/doc/man1/pts_examine.1           usr/share/man/man1
+ debian/doc/man1/pts_help.1              usr/share/man/man1
+ debian/doc/man1/pts_listentries.1       usr/share/man/man1
+ debian/doc/man1/pts_listmax.1           usr/share/man/man1
+ debian/doc/man1/pts_listowned.1         usr/share/man/man1
+ debian/doc/man1/pts_membership.1        usr/share/man/man1
+ debian/doc/man1/pts_removeuser.1        usr/share/man/man1
+ debian/doc/man1/pts_rename.1            usr/share/man/man1
+ debian/doc/man1/pts_setfields.1         usr/share/man/man1
+ debian/doc/man1/pts_setmax.1            usr/share/man/man1
+ debian/doc/man1/rxdebug.1               usr/share/man/man1
+ debian/doc/man1/scout.1                 usr/share/man/man1
+ debian/doc/man1/sys.1                   usr/share/man/man1
+ debian/doc/man1/tokens.1                usr/share/man/man1
+ debian/doc/man1/translate_et.1          usr/share/man/man1
+ debian/doc/man1/udebug.1                usr/share/man/man1
+ debian/doc/man1/unlog.1                 usr/share/man/man1
+ debian/doc/man1/up.1                    usr/share/man/man1
+ debian/doc/man1/vos.1                   usr/share/man/man1
+ debian/doc/man1/vos_addsite.1           usr/share/man/man1
+ debian/doc/man1/vos_apropos.1           usr/share/man/man1
+ debian/doc/man1/vos_backup.1            usr/share/man/man1
+ debian/doc/man1/vos_backupsys.1         usr/share/man/man1
+ debian/doc/man1/vos_changeaddr.1        usr/share/man/man1
+ debian/doc/man1/vos_create.1            usr/share/man/man1
+ debian/doc/man1/vos_delentry.1          usr/share/man/man1
+ debian/doc/man1/vos_dump.1              usr/share/man/man1
+ debian/doc/man1/vos_examine.1           usr/share/man/man1
+ debian/doc/man1/vos_help.1              usr/share/man/man1
+ debian/doc/man1/vos_listaddrs.1         usr/share/man/man1
+ debian/doc/man1/vos_listpart.1          usr/share/man/man1
+ debian/doc/man1/vos_listvldb.1          usr/share/man/man1
+ debian/doc/man1/vos_listvol.1           usr/share/man/man1
+ debian/doc/man1/vos_lock.1              usr/share/man/man1
+ debian/doc/man1/vos_move.1              usr/share/man/man1
+ debian/doc/man1/vos_partinfo.1          usr/share/man/man1
+ debian/doc/man1/vos_release.1           usr/share/man/man1
+ debian/doc/man1/vos_remove.1            usr/share/man/man1
+ debian/doc/man1/vos_remsite.1           usr/share/man/man1
+ debian/doc/man1/vos_rename.1            usr/share/man/man1
+ debian/doc/man1/vos_restore.1           usr/share/man/man1
+ debian/doc/man1/vos_status.1            usr/share/man/man1
+ debian/doc/man1/vos_syncserv.1          usr/share/man/man1
+ debian/doc/man1/vos_syncvldb.1          usr/share/man/man1
+ debian/doc/man1/vos_unlock.1            usr/share/man/man1
+ debian/doc/man1/vos_unlockvldb.1        usr/share/man/man1
+ debian/doc/man1/vos_zap.1               usr/share/man/man1
+ debian/doc/man1/xstat_cm_test.1         usr/share/man/man1
+ debian/doc/man1/xstat_fs_test.1         usr/share/man/man1
+ 
+ debian/doc/man5/CellServDB.5            usr/share/man/man5
+ debian/doc/man5/NetInfo.5               usr/share/man/man5
+ debian/doc/man5/NetRestrict.5           usr/share/man/man5
+ debian/doc/man5/ThisCell.5              usr/share/man/man5
+ debian/doc/man5/afs.5                   usr/share/man/man5
+ debian/doc/man5/afs_cache.5             usr/share/man/man5
+ debian/doc/man5/afsmonitor.5            usr/share/man/man5
+ debian/doc/man5/afszcm.cat.5            usr/share/man/man5
+ debian/doc/man5/butc.5                  usr/share/man/man5
+ debian/doc/man5/butc_logs.5             usr/share/man/man5
+ debian/doc/man5/cacheinfo.5             usr/share/man/man5
+ debian/doc/man5/tapeconfig.5            usr/share/man/man5
+ 
+ debian/doc/man8/afsd.8                  usr/share/man/man8
+ debian/doc/man8/backup.8                usr/share/man/man8
+ debian/doc/man8/backup_adddump.8        usr/share/man/man8
+ debian/doc/man8/backup_addhost.8        usr/share/man/man8
+ debian/doc/man8/backup_addvolentry.8    usr/share/man/man8
+ debian/doc/man8/backup_addvolset.8      usr/share/man/man8
+ debian/doc/man8/backup_apropos.8        usr/share/man/man8
+ debian/doc/man8/backup_dbverify.8       usr/share/man/man8
+ debian/doc/man8/backup_deldump.8        usr/share/man/man8
+ debian/doc/man8/backup_deletedump.8     usr/share/man/man8
+ debian/doc/man8/backup_delhost.8        usr/share/man/man8
+ debian/doc/man8/backup_delvolentry.8    usr/share/man/man8
+ debian/doc/man8/backup_delvolset.8      usr/share/man/man8
+ debian/doc/man8/backup_diskrestore.8    usr/share/man/man8
+ debian/doc/man8/backup_dump.8           usr/share/man/man8
+ debian/doc/man8/backup_dumpinfo.8       usr/share/man/man8
+ debian/doc/man8/backup_help.8           usr/share/man/man8
+ debian/doc/man8/backup_interactive.8    usr/share/man/man8
+ debian/doc/man8/backup_jobs.8           usr/share/man/man8
+ debian/doc/man8/backup_kill.8           usr/share/man/man8
+ debian/doc/man8/backup_labeltape.8      usr/share/man/man8
+ debian/doc/man8/backup_listdumps.8      usr/share/man/man8
+ debian/doc/man8/backup_listhosts.8      usr/share/man/man8
+ debian/doc/man8/backup_listvolsets.8    usr/share/man/man8
+ debian/doc/man8/backup_quit.8           usr/share/man/man8
+ debian/doc/man8/backup_readlabel.8      usr/share/man/man8
+ debian/doc/man8/backup_restoredb.8      usr/share/man/man8
+ debian/doc/man8/backup_savedb.8         usr/share/man/man8
+ debian/doc/man8/backup_scantape.8       usr/share/man/man8
+ debian/doc/man8/backup_setexp.8         usr/share/man/man8
+ debian/doc/man8/backup_status.8         usr/share/man/man8
+ debian/doc/man8/backup_volinfo.8        usr/share/man/man8
+ debian/doc/man8/backup_volrestore.8     usr/share/man/man8
+ debian/doc/man8/backup_volsetrestore.8  usr/share/man/man8
+ debian/doc/man8/butc.8                  usr/share/man/man8
+ debian/doc/man8/fms.8                   usr/share/man/man8
+ debian/doc/man8/fstrace.8               usr/share/man/man8
+ debian/doc/man8/fstrace_apropos.8       usr/share/man/man8
+ debian/doc/man8/fstrace_clear.8         usr/share/man/man8
+ debian/doc/man8/fstrace_dump.8          usr/share/man/man8
+ debian/doc/man8/fstrace_help.8          usr/share/man/man8
+ debian/doc/man8/fstrace_lslog.8         usr/share/man/man8
+ debian/doc/man8/fstrace_lsset.8         usr/share/man/man8
+ debian/doc/man8/fstrace_setlog.8        usr/share/man/man8
+ debian/doc/man8/fstrace_setset.8        usr/share/man/man8
Index: openafs/src/packaging/Debian/openafs-client.lintian
diff -c openafs/src/packaging/Debian/openafs-client.lintian:1.1 openafs/src/packaging/Debian/openafs-client.lintian:1.2
*** openafs/src/packaging/Debian/openafs-client.lintian:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/openafs-client.lintian	Thu Mar 23 15:19:07 2006
***************
*** 1,3 ****
- openafs-client: link-to-undocumented-manpage
  openafs-client: non-standard-dir-perm
  openafs-client: postinst-uses-db-input
--- 1,2 ----
Index: openafs/src/packaging/Debian/openafs-client.postinst
diff -c openafs/src/packaging/Debian/openafs-client.postinst:1.1 openafs/src/packaging/Debian/openafs-client.postinst:1.2
*** openafs/src/packaging/Debian/openafs-client.postinst:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/openafs-client.postinst	Thu Mar 23 15:19:07 2006
***************
*** 1,82 ****
  #! /bin/sh
! # postinst script for openafs
  
  set -e
  
- # summary of how this script can be called:
- #        * &lt;postinst&gt; `configure' &lt;most-recently-configured-version&gt;
- #        * &lt;old-postinst&gt; `abort-upgrade' &lt;new version&gt;
- #        * &lt;conflictor's-postinst&gt; `abort-remove' `in-favour' &lt;package&gt;
- #          &lt;new-version&gt;
- #        * &lt;deconfigured's-postinst&gt; `abort-deconfigure' `in-favour'
- #          &lt;failed-install-package&gt; &lt;version&gt; `removing'
- #          &lt;conflicting-package&gt; &lt;version&gt;
- 
  case "$1" in
!     configure)
  
!     update-alternatives --install /usr/bin/pagsh pagsh /usr/bin/pagsh.openafs 100 \
!     --slave /usr/share/man/man1/pagsh.1.gz pagsh.1.gz /usr/share/man/man1/pagsh.openafs.1.gz
  
- 	test -d /afs || mkdir /afs
      . /usr/share/debconf/confmodule
  
! 	db_version 2.0
! 
! 	db_get openafs-client/thiscell
! 	echo $RET &gt;/etc/openafs/ThisCell
! 	THISCELL=$RET
! 
! 	if test -f /etc/openafs/CellServDB; then :
! 	    else cp /usr/share/openafs/CellServDB \
! 	      /etc/openafs
! 	    fi
! 	if grep  -q -F "$RET" /etc/openafs/CellServDB&amp;&amp; [ "x$RET" != "x" ]  ; then :
! 		else db_input critical  openafs-client/cell-info || true
! 	    db_input high openafs-client/run-client ||true
! 	    db_go
! 	    db_get openafs-client/cell-info
! 	    if [ "x$RET" != "x" ] ; then
! 		echo \&gt;$THISCELL &gt;/etc/openafs/CellServDB.new
! 		perl -MSocket -e 'foreach (@ARGV) {' \
! 		        -e '@a=gethostbyname($_) and ' \
! 		        -e 'printf("%s\t\t# %s\n",inet_ntoa($a[4]),$a[0]) }' $RET \
! 		    &gt;&gt;/etc/openafs/CellServDB.new
! 			if [ `wc -l &lt;/etc/openafs/CellServDB.new` -eq 1 ] ; then
! 			    echo None of the hostnames resolved to an address 2&gt;&amp;1
! 			    db_reset openafs-client/cell-info ||true
! 			    exit 1
! 			 fi
! 		    cat /etc/openafs/CellServDB.new \
! 		      /etc/openafs/CellServDB  &gt;/etc/openafs/CellServDB.tmp
! 		    mv /etc/openafs/CellServDB.tmp \
! 		      /etc/openafs/CellServDB
! 		    rm /etc/openafs/CellServDB.new
! 		fi
! 	    fi
! 		    
! 	db_get openafs-client/cachesize
! 	echo /afs:/var/cache/openafs:$RET &gt;/etc/openafs/cacheinfo
! 
! 	db_get openafs-client/run-client
! 	echo AFS_CLIENT=$RET &gt;/etc/openafs/afs.conf.client
! 	db_get openafs-client/afsdb
! 	echo AFS_AFSDB=$RET &gt;&gt;/etc/openafs/afs.conf.client
! 	db_get openafs-client/crypt
! 	echo AFS_CRYPT=$RET &gt;&gt;/etc/openafs/afs.conf.client
! db_get openafs-client/dynroot
! echo AFS_DYNROOT=$RET &gt;&gt;/etc/openafs/afs.conf.client
! db_get openafs-client/fakestat
! echo AFS_FAKESTAT=$RET &gt;&gt;/etc/openafs/afs.conf.client
      ;;
  
!     abort-upgrade|abort-remove|abort-deconfigure)
! 
      ;;
  
!     *)
!         echo "postinst called with unknown argument \`$1'" &gt;&amp;2
!         exit 0
      ;;
  esac
  
--- 1,90 ----
  #! /bin/sh
! #
! # Summary of how this script can be called:
! #
! #  * &lt;postinst&gt; `configure' &lt;most-recently-configured-version&gt;
! #  * &lt;old-postinst&gt; `abort-upgrade' &lt;new version&gt;
! #  * &lt;conflictor's-postinst&gt; `abort-remove' `in-favour' &lt;package&gt;
! #    &lt;new-version&gt;
! #  * &lt;deconfigured's-postinst&gt; `abort-deconfigure' `in-favour'
! #    &lt;failed-install-package&gt; &lt;version&gt; `removing'
! #    &lt;conflicting-package&gt; &lt;version&gt;
  
  set -e
  
  case "$1" in
! configure)
!     update-alternatives --install /usr/bin/pagsh pagsh \
!         /usr/bin/pagsh.openafs 100  \
!         --slave /usr/share/man/man1/pagsh.1.gz pagsh.1.gz \
!         /usr/share/man/man1/pagsh.openafs.1.gz
  
!     test -d /afs || mkdir /afs
  
      . /usr/share/debconf/confmodule
+     db_version 2.0
  
!     db_get openafs-client/thiscell
!     echo $RET &gt;/etc/openafs/ThisCell
!     THISCELL=$RET
! 
!     if test -f /etc/openafs/CellServDB ; then
!         :
!     else
!         cp /usr/share/openafs/CellServDB /etc/openafs
!     fi
! 
!     # If ThisCell is not in CellServDB, we have to prompt the user for the
!     # VLDB servers.  Unfortunately, we can't do this in config because we
!     # need the CellServDB file, which is part of the package.  We have to
!     # override a lintian warning for this since prompts at installation time
!     # are frowned upon.
!     if grep -q -F "$RET" /etc/openafs/CellServDB &amp;&amp; [ "x$RET" != "x" ] ; then
!         :
!     else
!         db_input critical openafs-client/cell-info || true
!         db_input high openafs-client/run-client || true
!         db_go
!         db_get openafs-client/cell-info
!         if [ "x$RET" != "x" ] ; then
!             echo \&gt;$THISCELL &gt; /etc/openafs/CellServDB.new
!             perl -MSocket -e 'foreach (@ARGV) {' \
!                 -e '@a=gethostbyname($_) and ' \
!                 -e 'printf("%s\t\t# %s\n",inet_ntoa($a[4]),$a[0]) }' $RET \
!                     &gt;&gt;/etc/openafs/CellServDB.new
!             if [ `wc -l &lt;/etc/openafs/CellServDB.new` -eq 1 ] ; then
!                 echo None of the hostnames resolved to an address 2&gt;&amp;1
!                 db_reset openafs-client/cell-info || true
!                 exit 1
!             fi
!             cat /etc/openafs/CellServDB.new /etc/openafs/CellServDB \
!                 &gt;/etc/openafs/CellServDB.tmp
!             mv /etc/openafs/CellServDB.tmp /etc/openafs/CellServDB
!             rm /etc/openafs/CellServDB.new
!         fi
!     fi
!                     
!     db_get openafs-client/cachesize
!     echo /afs:/var/cache/openafs:$RET &gt;/etc/openafs/cacheinfo
! 
!     db_get openafs-client/run-client
!     echo AFS_CLIENT=$RET &gt;/etc/openafs/afs.conf.client
!     db_get openafs-client/afsdb
!     echo AFS_AFSDB=$RET &gt;&gt;/etc/openafs/afs.conf.client
!     db_get openafs-client/crypt
!     echo AFS_CRYPT=$RET &gt;&gt;/etc/openafs/afs.conf.client
!     db_get openafs-client/dynroot
!     echo AFS_DYNROOT=$RET &gt;&gt;/etc/openafs/afs.conf.client
!     db_get openafs-client/fakestat
!     echo AFS_FAKESTAT=$RET &gt;&gt;/etc/openafs/afs.conf.client
      ;;
  
! abort-upgrade|abort-remove|abort-deconfigure)
      ;;
  
! *)
!     echo "postinst called with unknown argument '$1'" &gt;&amp;2
!     exit 0
      ;;
  esac
  
***************
*** 86,90 ****
  #DEBHELPER#
  
  exit 0
- 
- 
--- 94,96 ----
Index: openafs/src/packaging/Debian/openafs-client.templates
diff -c openafs/src/packaging/Debian/openafs-client.templates:1.1 openafs/src/packaging/Debian/openafs-client.templates:1.2
*** openafs/src/packaging/Debian/openafs-client.templates:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/openafs-client.templates	Thu Mar 23 15:19:07 2006
***************
*** 1,85 ****
  Template: openafs-client/cell-info
  Type: string
! Description: What hosts are DB servers for your home cell?
!  AFS uses the file /etc/openafs/CellServDB to hold the list of servers
!  that should be contacted to find parts of a cell.  The cell you claim
!  this workstation belongs to is not in that file.  Enter the host
!  names of the database servers separated by spaces.
!  IMPORTANT: If you are creating a new cell and this machine is to be
!  a database server in that cell, only enter this machine's name; add
!  the other servers later after they are functioning. Also, do not
!  enable the AFS client to start at boot on this server until the cell
!  is configured.  When you are ready you can edit
   /etc/openafs/afs.conf.client to enable the client.
  
  Template: openafs-client/thiscell
  Type: string
! Description:  What AFS cell does this workstation belong to?
!    AFS filespace is organized into cells or administrative domains.
!    Each workstation belongs to one cell.  Usually the cell is the DNS
!    domain name of the site.
  
  Template: openafs-client/cachesize
  Type: string
  Default: 50000
! Description:  How large is your AFS cache (kb)? 
!    AFS uses a  area of the disk to cache remote files for faster
!    access.  This cache will be mounted on /var/cache/openafs.  It is
!    important that the cache not overfill the partition it is located
!    on.  Often, people find it useful to dedicate a partition to their
!    AFS cache.
  
  Template: openafs-client/run-client
  Type: boolean
  Default: true
! Description: Run Openafs client now and at boot?
!  Should the Openafs filesystem be started and mounted at boot?
!  Normally, most users who install the openafs-client package expect to
!  run it at boot.  However, if you are planning on setting up a new
!  cell or are on a laptop, you may not want it started at boot time.
!  If you answer no to this question, run /etc/init.d/openafs-client
!  force-start to run.
  
  Template: openafs-client/afsdb
  Type: boolean
  Default: true
! Description: Look up AFS cells in DNS?
!  In order to contact an AFS cell, you need the IP addresses of the
!  cell's database servers.  Normally, this information is read from
!  /etc/openafs/CellServDB.  However, if Openafs cannot find a cell in
!  that file it can use DNS to look for AFSDB records that contain the
   information.
  
  Template: openafs-client/crypt
  Type: boolean
  Default: true
! Description: ENcrypt authenticated traffic with AFS fileserver? 
!  AFS provides a weak form of encryption that can optionally be used
!  between a client and the fileservers.  While this encryption is weaker
!  than DES and thus is not sufficient for highly confidential data, it
!  does provide some confidentiality and is likely to make the job of a
!  casual attacker significantly more difficult.
  
  Template: openafs-client/dynroot
  Type: boolean
  Default: false
! Description: Dynamically generate the contents of /afs?
!  /afs generally contains an entry for each cell that a client can talk to.  
   Traditionally, these entries were generated by servers in the client's
   home cell.  However, OpenAFS clients can generate the contents of /afs
   dynamically based on the contents of /etc/openafs/CellServDB and DNS.
   .
!  If you generate /afs dynamically, you may need to create 
!  /etc/openafs/CellAliases to include aliases for common cells.
!  DO NOT SELECT THIS OPTION IF YOU ARE CREATING A NEW CELL.
  
  Template: openafs-client/fakestat
! type: boolean
! default: true
! Description: Use fakestat to avoid hangs when listing /afs?
!  Because AFS is a global file space, operations on the /afs directory
!  can generate significant network traffic.  If some AFS cells are
!  unavailable then looking at /afs using ls or a graphical file browser
!  may hang your machine for minutes.  AFS has an option to simulate
!  answers to these operations locally to avoid these hangs.  You want
!  this option under most circumstances.
--- 1,93 ----
  Template: openafs-client/cell-info
  Type: string
! _Description: What hosts are DB servers for your home cell?
!  AFS uses the file /etc/openafs/CellServDB to hold the list of servers that
!  should be contacted to find parts of a cell.  The cell you claim this
!  workstation belongs to is not in that file.  Enter the host names of the
!  database servers separated by spaces. IMPORTANT: If you are creating a new
!  cell and this machine is to be a database server in that cell, only enter
!  this machine's name; add the other servers later after they are
!  functioning. Also, do not enable the AFS client to start at boot on this
!  server until the cell is configured.  When you are ready you can edit
   /etc/openafs/afs.conf.client to enable the client.
  
  Template: openafs-client/thiscell
  Type: string
! _Description:  What AFS cell does this workstation belong to?
!  AFS filespace is organized into cells or administrative domains.
!  Each workstation belongs to one cell.  Usually the cell is the DNS
!  domain name of the site.
  
  Template: openafs-client/cachesize
  Type: string
  Default: 50000
! _Description:  How large is your AFS cache (kB)?
!  AFS uses an area of the disk to cache remote files for faster
!  access.  This cache will be mounted on /var/cache/openafs.  It is
!  important that the cache not overfill the partition it is located
!  on.  Often, people find it useful to dedicate a partition to their
!  AFS cache.
  
  Template: openafs-client/run-client
  Type: boolean
  Default: true
! _Description: Run Openafs client now and at boot?
!  Should the Openafs filesystem be started and mounted at boot? Normally,
!  most users who install the openafs-client package expect to run it at
!  boot.  However, if you are planning on setting up a new cell or are on a
!  laptop, you may not want it started at boot time.  If you choose not
!  to start AFS at boot, run /etc/init.d/openafs-client force-start to
!  start the client when you wish to run it.
  
  Template: openafs-client/afsdb
  Type: boolean
  Default: true
! _Description: Look up AFS cells in DNS?
!  In order to contact an AFS cell, you need the IP addresses of the cell's
!  database servers.  Normally, this information is read from
!  /etc/openafs/CellServDB.  However, if Openafs cannot find a cell in that
!  file, it can use DNS to look for AFSDB records that contain the
   information.
  
  Template: openafs-client/crypt
  Type: boolean
  Default: true
! _Description: Encrypt authenticated traffic with AFS fileserver?
!  AFS provides a weak form of encryption that can optionally be used between
!  a client and the fileservers.  While this encryption is weaker than DES
!  and thus is not sufficient for highly confidential data, it does provide
!  some confidentiality and is likely to make the job of a casual attacker
!  significantly more difficult.
  
  Template: openafs-client/dynroot
  Type: boolean
  Default: false
! _Description: Dynamically generate the contents of /afs?
!  /afs generally contains an entry for each cell that a client can talk to.
   Traditionally, these entries were generated by servers in the client's
   home cell.  However, OpenAFS clients can generate the contents of /afs
   dynamically based on the contents of /etc/openafs/CellServDB and DNS.
   .
!  If you generate /afs dynamically, you may need to create
!  /etc/openafs/CellAlias to include aliases for common cells.  (The syntax
!  of this file is one line per alias, with the cell name, a space, and then
!  the alias for that cell.)
  
  Template: openafs-client/fakestat
! Type: boolean
! Default: true
! _Description: Use fakestat to avoid hangs when listing /afs?
!  Because AFS is a global file space, operations on the /afs directory can
!  generate significant network traffic.  If some AFS cells are unavailable
!  then looking at /afs using ls or a graphical file browser may hang your
!  machine for minutes.  AFS has an option to simulate answers to these
!  operations locally to avoid these hangs.  You want this option under most
!  circumstances.
! 4
! 4
! 4
! 4
! 4
! 4
! 4
! 4
Index: openafs/src/packaging/Debian/openafs-dbserver.dirs
diff -c openafs/src/packaging/Debian/openafs-dbserver.dirs:1.1 openafs/src/packaging/Debian/openafs-dbserver.dirs:1.2
*** openafs/src/packaging/Debian/openafs-dbserver.dirs:1.1	Mon Aug 26 16:52:02 2002
--- openafs/src/packaging/Debian/openafs-dbserver.dirs	Thu Mar 23 15:19:07 2006
***************
*** 2,4 ****
--- 2,12 ----
  var/lib/openafs/db
  usr/share/man/man8
  usr/sbin
+ usr/share/doc
+ usr/share/doc
+ usr/share/doc
+ usr/share/doc
+ usr/share/doc
+ usr/share/doc
+ usr/share/doc
+ usr/share/doc
Index: openafs/src/packaging/Debian/openafs-dbserver.install
diff -c /dev/null openafs/src/packaging/Debian/openafs-dbserver.install:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/openafs-dbserver.install	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1,24 ----
+ debian/tmp/usr/sbin/prdb_check          usr/sbin
+ debian/tmp/usr/sbin/pt_util             usr/sbin
+ debian/tmp/usr/sbin/vldb_check          usr/sbin
+ 
+ debian/afs-rootvol                      usr/sbin
+ debian/afs-newcell                      usr/sbin
+ 
+ debian/tmp/usr/lib/openafs/buserver     usr/lib/openafs
+ debian/tmp/usr/lib/openafs/ptserver     usr/lib/openafs
+ debian/tmp/usr/lib/openafs/vlserver     usr/lib/openafs
+ 
+ debian/ConfigUtils.pm                   usr/share/perl5/Debian/OpenAFS
+ 
+ debian/doc/man5/BackupLog.5             usr/share/man/man5
+ debian/doc/man5/VLLog.5                 usr/share/man/man5
+ debian/doc/man5/bdb.DB0.5               usr/share/man/man5
+ debian/doc/man5/prdb.DB0.5              usr/share/man/man5
+ debian/doc/man5/vldb.DB0.5              usr/share/man/man5
+ 
+ debian/doc/man8/buserver.8              usr/share/man/man8
+ debian/doc/man8/prdb_check.8            usr/share/man/man8
+ debian/doc/man8/ptserver.8              usr/share/man/man8
+ debian/doc/man8/vldb_check.8            usr/share/man/man8
+ debian/doc/man8/vlserver.8              usr/share/man/man8
Index: openafs/src/packaging/Debian/openafs-dbserver.lintian
diff -c /dev/null openafs/src/packaging/Debian/openafs-dbserver.lintian:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/openafs-dbserver.lintian	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1 ----
+ openafs-dbserver: non-standard-dir-perm
Index: openafs/src/packaging/Debian/openafs-fileserver.init
diff -c openafs/src/packaging/Debian/openafs-fileserver.init:1.1 openafs/src/packaging/Debian/openafs-fileserver.init:1.2
*** openafs/src/packaging/Debian/openafs-fileserver.init:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/openafs-fileserver.init	Thu Mar 23 15:19:07 2006
***************
*** 34,40 ****
  	echo -n "Stopping $DESC: "
      bos shutdown localhost -wait -localauth
  	start-stop-daemon --stop --quiet  \
! 		--exec $DAEMON
  	echo "$NAME."
  	;;
    #reload)
--- 34,40 ----
  	echo -n "Stopping $DESC: "
      bos shutdown localhost -wait -localauth
  	start-stop-daemon --stop --quiet  \
! 		--user root --name bosserver
  	echo "$NAME."
  	;;
    #reload)
***************
*** 56,62 ****
  	#	just the same as "restart".
  	#
  	echo -n "Restarting $DESC: "
!     bos restart localhost -localauth -bos
  	sleep 1
  	echo "$NAME."
  	;;
--- 56,67 ----
  	#	just the same as "restart".
  	#
  	echo -n "Restarting $DESC: "
!         if pidof $DAEMON &gt; /dev/null ; then
!             bos restart localhost -localauth -bos
!         else
!             start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
!                 --exec $DAEMON
!         fi
  	sleep 1
  	echo "$NAME."
  	;;
Index: openafs/src/packaging/Debian/openafs-fileserver.install
diff -c /dev/null openafs/src/packaging/Debian/openafs-fileserver.install:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/openafs-fileserver.install	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1,31 ----
+ debian/tmp/usr/sbin/bosserver           usr/sbin
+ debian/tmp/usr/sbin/voldump             usr/sbin
+ debian/tmp/usr/sbin/volinfo             usr/sbin
+ 
+ debian/tmp/usr/lib/openafs/up*          usr/sbin
+ 
+ debian/tmp/usr/lib/openafs/fileserver   usr/lib/openafs
+ debian/tmp/usr/lib/openafs/salvager     usr/lib/openafs
+ debian/tmp/usr/lib/openafs/volserver    usr/lib/openafs
+ 
+ debian/doc/man5/BosConfig.5             usr/share/man/man5
+ debian/doc/man5/BosLog.5                usr/share/man/man5
+ debian/doc/man5/FORCESALVAGE.5          usr/share/man/man5
+ debian/doc/man5/FileLog.5               usr/share/man/man5
+ debian/doc/man5/KeyFile.5               usr/share/man/man5
+ debian/doc/man5/NoAuth.5                usr/share/man/man5
+ debian/doc/man5/SALVAGE.fs.5            usr/share/man/man5
+ debian/doc/man5/SalvageLog.5            usr/share/man/man5
+ debian/doc/man5/VolserLog.5             usr/share/man/man5
+ debian/doc/man5/afs_volume_header.5     usr/share/man/man5
+ debian/doc/man5/salvage.lock.5          usr/share/man/man5
+ debian/doc/man5/sysid.5                 usr/share/man/man5
+ 
+ debian/doc/man8/bosserver.8             usr/share/man/man8
+ debian/doc/man8/fileserver.8            usr/share/man/man8
+ debian/doc/man8/salvager.8              usr/share/man/man8
+ debian/doc/man8/upclient.8              usr/share/man/man8
+ debian/doc/man8/upserver.8              usr/share/man/man8
+ debian/doc/man8/voldump.8               usr/share/man/man8
+ debian/doc/man8/volinfo.8               usr/share/man/man8
+ debian/doc/man8/volserver.8             usr/share/man/man8
Index: openafs/src/packaging/Debian/openafs-fileserver.lintian
diff -c openafs/src/packaging/Debian/openafs-fileserver.lintian:1.1 openafs/src/packaging/Debian/openafs-fileserver.lintian:1.2
*** openafs/src/packaging/Debian/openafs-fileserver.lintian:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/openafs-fileserver.lintian	Thu Mar 23 15:19:07 2006
***************
*** 1,2 ****
- openafs-fileserver: link-to-undocumented-manpage
  openafs-fileserver: non-standard-dir-perm
--- 1 ----
Index: openafs/src/packaging/Debian/openafs-fileserver.postinst
diff -c openafs/src/packaging/Debian/openafs-fileserver.postinst:1.1 openafs/src/packaging/Debian/openafs-fileserver.postinst:1.2
*** openafs/src/packaging/Debian/openafs-fileserver.postinst:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/openafs-fileserver.postinst	Thu Mar 23 15:19:07 2006
***************
*** 1,46 ****
  #!/bin/sh -e
  
! # summary of how this script can be called:
! #        * &lt;postinst&gt; `configure' &lt;most-recently-configured-version&gt;
! #        * &lt;old-postinst&gt; `abort-upgrade' &lt;new version&gt;
! #        * &lt;conflictor's-postinst&gt; `abort-remove' `in-favour' &lt;package&gt;
! #          &lt;new-version&gt;
! #        * &lt;deconfigured's-postinst&gt; `abort-deconfigure' `in-favour'
! #          &lt;failed-install-package&gt; &lt;version&gt; `removing'
! #          &lt;conflicting-package&gt; &lt;version&gt;
  
  case "$1" in
!     configure)
! 
! 	. /usr/share/debconf/confmodule
! 
! 	db_version 2.0
! 
! 	db_get openafs-fileserver/thiscell
! 	echo $RET &gt;/etc/openafs/server/ThisCell
! 	if [ -f /etc/openafs/server/CellServDB ] ; then :
! 	    else echo \&gt;$RET &gt;/etc/openafs/server/CellServDB
! 	    fi
! 	    if [ "x$2" != "x" ] ; then
! 		if dpkg --compare-versions $2 lt 1.2.0-1 ; then
! 		    mv /etc/openafs/server-local/BosConfig /etc/openafs/BosConfig ||true
! 		    mv /etc/openafs/server-local/sysid /var/lib/openafs ||true
! 		    fi
! 		fi
      ;;
  
!     abort-upgrade|abort-remove|abort-deconfigure)
! 
      ;;
  
!     *)
!         echo "postinst called with unknown argument \`$1'" &gt;&amp;2
!         exit 0
      ;;
  esac
  
! # dh_installdeb will replace this with shell code automatically
! # generated by other debhelper scripts.
  #DEBHELPER#
  
  exit 0
--- 1,55 ----
  #!/bin/sh -e
+ #
+ # Summary of how this script can be called:
+ #
+ #  * &lt;postinst&gt; `configure' &lt;most-recently-configured-version&gt;
+ #  * &lt;old-postinst&gt; `abort-upgrade' &lt;new version&gt;
+ #  * &lt;conflictor's-postinst&gt; `abort-remove' `in-favour' &lt;package&gt;
+ #    &lt;new-version&gt;
+ #  * &lt;deconfigured's-postinst&gt; `abort-deconfigure' `in-favour'
+ #    &lt;failed-install-package&gt; &lt;version&gt; `removing'
+ #    &lt;conflicting-package&gt; &lt;version&gt;
  
! set -e
  
  case "$1" in
! configure)
!     . /usr/share/debconf/confmodule
!     db_version 2.0
! 
!     db_get openafs-fileserver/thiscell
!     echo $RET &gt;/etc/openafs/server/ThisCell
! 
!     if [ -f /etc/openafs/server/CellServDB ] ; then
!         :
!     else
!         sed -n "/^&gt;$RET/,/^&gt;/p" /etc/openafs/CellServDB | sed '$d' \
!             &gt;/etc/openafs/server/CellServDB
!         if [ ! -s /etc/openafs/server/CellServDB ] ; then
!             echo "&gt;$RET" &gt;/etc/openafs/server/CellServDB
!         fi
!     fi
!     if [ "x$2" != "x" ] ; then
!         if dpkg --compare-versions $2 lt 1.2.0-1 ; then
!             mv /etc/openafs/server-local/BosConfig \
!                 /etc/openafs/BosConfig || true
!             mv /etc/openafs/server-local/sysid /var/lib/openafs || true
!         fi
!     fi
!     db_stop
      ;;
  
! abort-upgrade|abort-remove|abort-deconfigure)
      ;;
  
! *)
!     echo "postinst called with unknown argument \`$1'" &gt;&amp;2
!     exit 0
      ;;
  esac
  
! # dh_installdeb will replace this with shell code automatically generated by
! # other debhelper scripts.
  #DEBHELPER#
  
  exit 0
Index: openafs/src/packaging/Debian/openafs-fileserver.postrm
diff -c openafs/src/packaging/Debian/openafs-fileserver.postrm:1.1 openafs/src/packaging/Debian/openafs-fileserver.postrm:1.2
*** openafs/src/packaging/Debian/openafs-fileserver.postrm:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/openafs-fileserver.postrm	Thu Mar 23 15:19:07 2006
***************
*** 38,41 ****
  
  #DEBHELPER#
  
- 
--- 38,40 ----
Index: openafs/src/packaging/Debian/openafs-fileserver.templates
diff -c openafs/src/packaging/Debian/openafs-fileserver.templates:1.1 openafs/src/packaging/Debian/openafs-fileserver.templates:1.2
*** openafs/src/packaging/Debian/openafs-fileserver.templates:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/openafs-fileserver.templates	Thu Mar 23 15:19:07 2006
***************
*** 1,31 ****
  Template: openafs-fileserver/thiscell
  Type: string
! Description: What cell does this server serve files for?
   AFS fileservers belong to a cell.  They have the key for that cell's
!  Kerberos service and serve volumes into that cell.  Normally, this
!  cell is the same cell as the workstation's client belongs to.
! Description-de: Für welche Zelle liefert der Server Dateien?
!  AFS-Dateiserver gehören zu einer Zelle. Die Server haben den Schlüssel
!  für den Kerberos-Service der Zelle und stellen Volumes für die Zelle
!  bereit. Normalerweise ist die Zelle identisch mit der des Clients
  
! template: openafs-fileserver/bosconfig_moved
  Type: boolean
! default: true
! Description: Upgrading will move files to new locations; continue? 
!  Between Openafs 1.1 and Openafs 1.2, several files moved.  In
!  particular,  files in /etc/openafs/server-local have been distributed
!  to other locations.  The BosConfig file is now located in
!  /etc/openafs and the other files are located in /var/lib/openafs.  If
!  you continue with this upgrade, these files will be moved. You should
!  use the bos restart command to  reload your servers.  Any
!  configuration changes made before you do so will be lost.
  
! template: openafs-fileserver/alpha-broken
  Type: note
! Description: OpenAFS Fileserv Probably does not work!
   You are running the OpenAFS file server package on an alpha.  This
!  probably doesn't work; the DES code is flaky on the alpha, along with
!  the threaded file server.  Likely, the fileserver will simply fail to
!  start, but if it does load, data corruption may result.  You have been
!  warned.
--- 1,26 ----
  Template: openafs-fileserver/thiscell
  Type: string
! _Description: What cell does this server serve files for?
   AFS fileservers belong to a cell.  They have the key for that cell's
!  Kerberos service and serve volumes into that cell.  Normally, this cell is
!  the same cell as the workstation's client belongs to.
  
! Template: openafs-fileserver/bosconfig_moved
  Type: boolean
! Default: true
! _Description: Upgrading will move files to new locations; continue?
!  Between Openafs 1.1 and Openafs 1.2, several files moved.  In particular,
!  files in /etc/openafs/server-local have been distributed to other
!  locations.  The BosConfig file is now located in /etc/openafs and the
!  other files are located in /var/lib/openafs.  If you continue with this
!  upgrade, these files will be moved.  You should use the bos restart
!  command to reload your servers.  Any configuration changes made before
!  you do so will be lost.
  
! Template: openafs-fileserver/alpha-broken
  Type: note
! _Description: OpenAFS file server probably does not work!
   You are running the OpenAFS file server package on an alpha.  This
!  probably doesn't work; the DES code is flaky on the alpha, along with the
!  threaded file server.  Likely, the fileserver will simply fail to start,
!  but if it does load, data corruption may result.  You have been warned.
Index: openafs/src/packaging/Debian/openafs-kpasswd.install
diff -c /dev/null openafs/src/packaging/Debian/openafs-kpasswd.install:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/openafs-kpasswd.install	Thu Mar 23 15:19:07 2006
***************
*** 0 ****
--- 1,23 ----
+ debian/tmp/usr/bin/kpasswd              usr/bin
+ 
+ debian/tmp/usr/sbin/kas                 usr/bin
+ 
+ debian/doc/man1/kpasswd.1               usr/share/man/man1
+ 
+ debian/doc/man8/kas.8                   usr/share/man/man8
+ debian/doc/man8/kas_apropos.8           usr/share/man/man8
+ debian/doc/man8/kas_create.8            usr/share/man/man8
+ debian/doc/man8/kas_delete.8            usr/share/man/man8
+ debian/doc/man8/kas_examine.8           usr/share/man/man8
+ debian/doc/man8/kas_forgetticket.8      usr/share/man/man8
+ debian/doc/man8/kas_help.8              usr/share/man/man8
+ debian/doc/man8/kas_interactive.8       usr/share/man/man8
+ debian/doc/man8/kas_list.8              usr/share/man/man8
+ debian/doc/man8/kas_listtickets.8       usr/share/man/man8
+ debian/doc/man8/kas_noauthentication.8  usr/share/man/man8
+ debian/doc/man8/kas_quit.8              usr/share/man/man8
+ debian/doc/man8/kas_setfields.8         usr/share/man/man8
+ debian/doc/man8/kas_setpassword.8       usr/share/man/man8
+ debian/doc/man8/kas_statistics.8        usr/share/man/man8
+ debian/doc/man8/kas_stringtokey.8       usr/share/man/man8
+ debian/doc/man8/kas_unlock.8            usr/share/man/man8
Index: openafs/src/packaging/Debian/openafs-modules-source.docs
diff -c openafs/src/packaging/Debian/openafs-modules-source.docs:1.1 openafs/src/packaging/Debian/openafs-modules-source.docs:1.2
*** openafs/src/packaging/Debian/openafs-modules-source.docs:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/openafs-modules-source.docs	Thu Mar 23 15:19:07 2006
***************
*** 2,5 ****
  debian/README.servers
  debian/configuration-transcript.txt
  debian/README.modules
- NEWS
--- 2,4 ----
Index: openafs/src/packaging/Debian/prep-modules
diff -c openafs/src/packaging/Debian/prep-modules:1.1 openafs/src/packaging/Debian/prep-modules:1.2
*** openafs/src/packaging/Debian/prep-modules:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/prep-modules	Thu Mar 23 15:19:07 2006
***************
*** 1,55 ****
  #! /bin/sh
  
  set -e
  
! if [ $# -ne 2 ]; then
! 	echo Usage: $0 kernelsource-location control-template
! 	exit 1
  fi
  
  
  changelog="$1/debian/changelog"
  if [ -n "$KVERS" ] &amp;&amp; [ -n "$KDREV" ]; then
!   linuxversion=$KVERS${INT_SUBARCH}
!   kernversion=$KDREV
! 
! elif [ ! -f $changelog ]; then
!         linuxversion=`awk '{ if (NR==1) v=$3; else if (NR==2) p=$3; else if (NR==3) s=$3; \
!                 else if (NR==4) { e=$3; exit; } } \
!                 END { printf("%s.%s.%s%s\n",v,p,s,e); }' $1/Makefile`
! 
!         if [ -z "$KDREV" ]; then
!           kernversion=$linuxversion-0
!         else
! 	    linuxversion=${linuxversion}${INT_SUBARCH}
!           kernversion=$KDREV
!         fi
! 
  else
!         linuxversion=`head -1 $changelog | \
!                 sed -e 's/.*source-\([^ ]*\) (\([^)]*\)).*/\1/'`
!         kernversion=`head -1 $changelog | \
!                 sed -e 's/.*source-\([^ ]*\) (\([^)]*\)).*/\2/'`
  fi
  
! pkgversion=`head -1 debian/changelog | \
! 	sed -e 's/.*(\([^)]*\)).*/\1/'`
! 
! pkgupversion=`echo $pkgversion | cut -d- -f 1`
! pkgupversion2=`perl -e "\"$pkgupversion\" =~ /(.*?)(\d+)\D*$/;"'printf $1 . ($2+1);'`
! 
! sed -e s/=KVERS/$linuxversion/g -e s/=KREVS/$kernversion/g -e s/=AVERS/$pkgupversion/g -e s/=2AVERS/$pkgupversion2/g $2
  
! mprefix=`grep Package: $2 | cut -d' ' -f 2 | cut -d= -f 1`
! 
! rm -f debian/tmp/usr/share/doc/$mprefix$linuxversion
  
  
! epochversion=`echo $kernversion | sed -n -e 's/^\([0-9]*\):.*/\1/p' -e 's/.*//'`
! kernversion="$pkgversion+`echo $kernversion | sed -e 's/^[0-9]*://'`"
  
! if [ -n "$epochversion" ]; then
!   kernversion=$epochversion:$kernversion
  fi
! echo "$kernversion" &gt; debian/VERSION
! echo "$linuxversion" &gt; debian/KVERS
--- 1,103 ----
  #! /bin/sh
+ #
+ # Prepares to build kernel modules.  This script figures out and munges
+ # version strings.  The goal is:
+ #
+ #  * Set the package name to openafs-modules-$(KVERS) where $(KVERS) is the
+ #    major kernel revision plus the debian subrevision and whatever
+ #    architecture string is appropriate if building against the stock Debian
+ #    kernels.  $(KVERS) should be identical to the version component contained
+ #    in the Debian kernel package names.
+ #
+ #  * Make the package recommend either kernel-image-$(KVERS) or
+ #    linux-image-$(KVERS) as appropriate for the kernel version that we're
+ #    building against.  Use recommend rather than depends since the user may
+ #    have built their own kernel outside of the Debian package infrastructure.
+ #
+ #  * Save the version number of the binary package in debian/VERSION for later
+ #    use by dh_gencontrol.  This will be the version number of the source
+ #    package followed by a + and the version number of the kernel package that
+ #    we're building against.  If the kernel package version contains an epoch,
+ #    try to hack our way into doing the right thing by using that epoch number
+ #    as our own.  This isn't quite the right thing, but seems reasonably good.
+ #
+ # This script generates debian/control from debian/control.module using sed.
+ # Unfortunately, substvars cannot be used since the name of the package is
+ # modified and substvars happens too late.  It also outputs debian/VERSION,
+ # containing the version of the binary package.
  
  set -e
  
! if [ "$#" -ne 1 ]; then
!     echo Usage: $0 kernelsource-location
!     exit 1
  fi
  
+ # We can get the kernel version from one of three places.  If KVERS and KDREV
+ # are both already set in the environment (which will be the case when invoked
+ # by make-kpkg or module-assistant), use them.  Otherwise, if we have a kernel
+ # source directory that contains debian/changelog (generated by make-kpkg),
+ # parse that file to find the version information.  Finally, if neither works,
+ # extract the kernel version from the kernel headers, append INT_SUBARCH to
+ # that version if it's available, and assume a kernel package revision of -0
+ # if none is provided.
+ #
+ # Set the variables $afs_kvers, which will hold the revision of the kernel,
+ # and $afs_kdrev, which will hold the version of the kernel package that we're
+ # building against.
  
  changelog="$1/debian/changelog"
  if [ -n "$KVERS" ] &amp;&amp; [ -n "$KDREV" ]; then
!     afs_kvers="${KVERS}${INT_SUBARCH}"
!     afs_kdrev="${KDREV}"
! elif [ ! -f "$changelog" ] ; then
!     if [ -n "$KVERS" ] ; then
!         afs_kvers="$KVERS"
!     else
!         afs_kvers=`perl debian/kernel-version "$1"`
!     fi
!     if [ -z "$KDREV" ] ; then
!         afs_kdrev="${afs_kvers}-0"
!     else
!         afs_kvers="${afs_kvers}${INT_SUBARCH}"
!         afs_kdrev="${KDREV}"
!     fi
  else
!     if [ -n "$KVERS" ] ; then
!         afs_kvers="$KVERS"
!     else
!         afs_kvers=`head -1 "$changelog" \
!             | sed -e 's/.*source-\([^ ]*\) (\([^)]*\)).*/\1/'`
!     fi
!     afs_kdrev=`head -1 "$changelog" \
!         | sed -e 's/.*source-\([^ ]*\) (\([^)]*\)).*/\2/'`
  fi
  
! # Determine the kernel package name.  For right now, assume linux-image for
! # 2.6.12 and later, and kernel-image for anything earlier.  If this doesn't
! # work for someone, please submit a bug with the details.
  
! if dpkg --compare-versions "$afs_kvers" ge "2.6.12" ; then
!     afs_image=linux-image
! else
!     afs_image=kernel-image
! fi
  
+ # Generate the control file from the template.
  
! sed -e "s/=KVERS/${afs_kvers}/g" -e "s/=IMG/${afs_image}/g" \
!     debian/control.module &gt; debian/control
  
! # Now, calcuate the binary package version.  Extract the epoch from the kernel
! # package revision and add it to the beginning of the binary package version
! # if present.  Then, concatenate the source version, '+', and the kernel
! # package revision without the epoch.
! 
! afs_version=`head -1 debian/changelog | sed -e 's/.*(\([^)]*\)).*/\1/'`
! afs_epoch=`echo ${afs_kdrev} | sed -n -e 's/^\([0-9]*\):.*/\1/p'`
! afs_version="${afs_version}+`echo ${afs_kdrev} | sed -e 's/^[0-9]*://'`"
! if [ -n "$afs_epoch" ] ; then
!     afs_version="${afs_epoch}:${afs_version}"
  fi
! 
! echo "$afs_version" &gt; debian/VERSION
Index: openafs/src/packaging/Debian/pt_util.sgml
diff -c openafs/src/packaging/Debian/pt_util.sgml:1.1 openafs/src/packaging/Debian/pt_util.sgml:1.2
*** openafs/src/packaging/Debian/pt_util.sgml:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/pt_util.sgml	Thu Mar 23 15:19:07 2006
***************
*** 182,185 ****
  sgml-local-catalogs:nil
  sgml-local-ecat-files:nil
  End:
- --&gt;
--- 182,184 ----
Index: openafs/src/packaging/Debian/rules
diff -c openafs/src/packaging/Debian/rules:1.1 openafs/src/packaging/Debian/rules:1.2
*** openafs/src/packaging/Debian/rules:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/rules	Thu Mar 23 15:19:07 2006
***************
*** 9,276 ****
  # Uncomment this to turn on verbose mode. 
  #export DH_VERBOSE=1
  
- # This is the debhelper compatability version to use.
- export DH_COMPAT=2
- 
  # This has to be exported to make some magic below work.
  export DH_OPTIONS
  
! # The AFS sysname is determined by a script
! KVERS=`awk '{ if (NR==1) v=$$3; else if (NR==2) p=$$3; else if (NR==3) s=$$3; \
!        else if (NR==4) { e=$$3; exit; } } \
!        END { printf("%s.%s.%s%s\n",v,p,s,e); }' $(KSRC)/Makefile`
! SYS_NAME=$(shell KVERS=$(KVERS) sh debian/sysname)
! package=openafs
! srcpkg = openafs-modules-source
! modulepkg=$(shell echo openafs-modules-$(KVERS)${INT_SUBARCH})
  ifndef KSRC
! KSRC=/usr/src/linux
  endif
! MODDIR=..
! LINTIAN_PACKAGES= openafs-client openafs-fileserver
  export KSRC 
  export KVERS
  
  
  configure: configure-stamp
  configure-stamp:
  	dh_testdir
! 	-ln -s @sys/dest dest
! 	-ln -s $(SYS_NAME) @sys
! #	sh regen.sh
! 	 afslogsdir=/var/log/openafs sh configure --with-afs-sysname=$(SYS_NAME) --disable-kernel-module \
! 	--prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \
! 	--localstatedir=/var/lib 
! 	install -d $(SYS_NAME)/dest/root.client/usr/vice/etc
! 	install -d dest/root.server/usr/afs/bin
! 
  	touch configure-stamp
  
  build: configure-stamp build-stamp
  build-stamp:
  	dh_testdir
! 
! 	$(MAKE) dest 
! 	-rm $(SYS_NAME)/dest/include/crypt.h
  	touch build-stamp
  
  clean:
  	dh_testdir
  	dh_testroot
! 	rm -f build-stamp configure-stamp build-modules-stamp
! 	# Add here commands to clean up after the build process.
! 	-$(MAKE) -ki distclean
! 	-rm -rf obj dest $(SYS_NAME) @sys Makefile debian/openafs-client.init
! 	-rm -rf config.status config.cache lib include
  	dh_clean
  
  install: DH_OPTIONS=
  install: build
  	dh_testdir
  	dh_testroot
- 	dh_clean -k
  	dh_installdirs
! 	mkdir -p debian/openafs-dbserver/usr/share/man/man8
! 		/usr/bin/docbook-to-man debian/pt_util.sgml &gt;debian/openafs-dbserver/usr/share/man/man8/pt_util.8
! 	for foo in $(LINTIAN_PACKAGES) ; do \
! 		install -d debian/$$foo/usr/share/lintian/overrides; \
! 		cp debian/$$foo.lintian debian/$$foo/usr/share/lintian/overrides/$$foo; \
! 		done
! 	for pkg in openafs-dbserver openafs-fileserver openafs-kpasswd; do \
! 		ln -s openafs-client debian/$$pkg/usr/share/doc/$$pkg; \
! 		done
! 	# Add here commands to install the package into debian/tmp.
! 	cat debian/filelist |sh debian/movefiles
! 	mv debian/openafs-client/usr/bin/pagsh  \
! 	debian/openafs-client/usr/bin/pagsh.openafs
! 
! 	cp debian/CellServDB debian/openafs-client/usr/share/openafs
! 	cp dest/root.client/usr/vice/etc/afs.rc debian/openafs-client.init
! 	cp dest/root.client/usr/vice/etc/afs.conf debian/openafs-client/etc/openafs/afs.conf
! 	install -m 755 -o root -g root debian/afs-rootvol debian/openafs-dbserver/usr/sbin
! 	install -g root -o root -m 755 debian/afs-newcell \
! 		debian/openafs-dbserver/usr/sbin
! 	install -D -m 644 debian/ConfigUtils.pm \
! 		debian/openafs-dbserver/usr/lib/perl5/Debian/OpenAFS/ConfigUtils.pm
! 	(cd debian&amp;&amp;pod2man --section 8 --center "Debian GNU/Linux"  \
! 		afs-rootvol ) &gt;debian/openafs-dbserver/usr/share/man/man8/afs-rootvol.8
! 	(cd debian&amp;&amp;pod2man --section 8 --center "Debian GNU/Linux"  \
! 		afs-newcell ) &gt;debian/openafs-dbserver/usr/share/man/man8/afs-newcell.8
! 	# No, includes should not have the x bit set
! 	find debian/libopenafs-dev/usr/include -type f -print | \
! 		xargs chmod a-x
! 	# And drop the pam modules
! 	rm debian/libopenafs-dev/usr/lib/*pam*
  
! # Build architecture-independent files here.
! # Pass -i to all debhelper commands in this target to reduce clutter.
  binary-indep: DH_OPTIONS=-i
  binary-indep: build install binary-source
- 	# Need this version of debhelper for DH_OPTIONS to work.
- 	dh_testversion 1.1.17
  	dh_testdir
  	dh_testroot
! #	dh_installdebconf
  	dh_installdocs
- 	dh_installexamples
- 	dh_installmenu
- #	dh_installemacsen
- #	dh_installpam
- #	dh_installinit
- 	dh_installcron
- #	dh_installmanpages
- 	dh_installinfo
- 	dh_undocumented
- 	dh_installchangelogs   ChangeLog
  	dh_link
  	dh_compress
  	dh_fixperms
- 	# You may want to make some executables suid here.
- 	dh_suidregister
  	dh_installdeb
- #	dh_perl
  	dh_gencontrol
  	dh_md5sums
  	dh_builddeb
  
! # Build architecture-dependent files here.
! # Pass -a to all debhelper commands in this target to reduce clutter.
  binary-arch: DH_OPTIONS=-a
  binary-arch: build install
- 	# Need this version of debhelper for DH_OPTIONS to work.
- 	dh_testversion 1.1.17
  	dh_testdir
  	dh_testroot
! 	dh_installdebconf
  	dh_installdocs
! 	dh_installexamples
! 	dh_installmenu
! #	dh_installemacsen
! #	dh_installpam
  	DH_OPTIONS= dh_installinit -popenafs-client -r -- defaults 25 18
  	DH_OPTIONS= dh_installinit -popenafs-fileserver -r
- 	dh_installcron
- #	dh_installmanpages
- 	dh_installinfo
- 	dh_undocumented
- 	dh_installchangelogs   ChangeLog
- 	dh_strip
  	dh_link
  	dh_compress
  	dh_fixperms
- 	# You may want to make some executables suid here.
  	chmod 700 debian/openafs-client/var/cache/openafs
- 	chmod 700 debian/openafs-fileserver/etc/openafs/server
  	chmod 700 debian/openafs-dbserver/var/lib/openafs/db
  	chmod 700 debian/openafs-fileserver/var/lib/openafs/cores
! 	dh_suidregister
  	dh_installdeb
- #	dh_makeshlibs
- #	dh_perl
  	dh_shlibdeps
  	dh_gencontrol
  	dh_md5sums
  	dh_builddeb
  
! binary:   binary-indep binary-arch
! .PHONY: build clean binary-indep binary-arch binary install configure
! 
! ############################Module package support
! kdist_image:  build-modules
! 	$(MAKE) $(MFLAGS) -f debian/rules MODDIR=$(KSRC)/.. binary-modules
! 	$(MAKE) $(MFLAGS) -f debian/rules MODDIR=$(KSRC)/.. clean
! 
! kdist:  build-modules
! 	$(MAKE) $(MFLAGS) -f debian/rules MODDIR=$(KSRC)/.. KERNEL_DEPENDS=y binary-modules
! 	KSRC="$(KSRC)" KMAINT="$(KMAINT)" KEMAIL="$(KEMAIL)" \
! 		sh -v debian/genchanges.sh
! 	$(MAKE) $(MFLAGS) -f debian/rules MODDIR=$(KSRC)/.. clean
  
  
- 
- kdist_config: configure
- 
- kdist_clean: clean
- 
- ############################ source stuff #################################
  binary-source:
! # Perform some tests
! 	test -f debian/rules
! 	test `id -u` = "0"
! 
! 
! # Setup everything first
  	-rm -rf debian/$(srcpkg) debian/substvars
- 	install -d debian/$(srcpkg)
- # Clean up the sources	
  	install -d debian/$(srcpkg)/usr/src/modules/$(package)
! 	find . \( -name \*.o -o -path ./debian/$(srcpkg) -o -path \*/CVS -o -path ./src/WINNT  \
! 		-o -path ./obj -o -path ./$(SYS_NAME)  \
! 	-o \( -path ./debian/\* -type d \) \
! 	-o -path ./debian/\*debhelper \) -prune -o -print | \
! 		cpio -admp debian/$(srcpkg)/usr/src/modules/$(package)
! 	( cd debian/$(srcpkg)/usr/src/modules/$(package)&amp;&amp; \
! 		$(MAKE) -f debian/rules clean &amp;&amp; \
! 	rm -rf src/libafs/rx src/libafs/afs src/libafs/afsint; \
! 		mv debian/kern-sysname debian/sysname)
! 	chown -R root.root debian/$(srcpkg)
  	find debian/$(srcpkg) -type d | xargs chmod 755
  	find debian/$(srcpkg) -type f -perm -100 | xargs chmod 755
  	find debian/$(srcpkg) -type f -not -perm -100 | xargs chmod 644
  	cd debian/$(srcpkg)/usr/src &amp;&amp; \
! 	  tar cf $(package).tar modules &amp;&amp; \
! 	  $(RM) -r modules/$(package)
  	gzip -9 debian/$(srcpkg)/usr/src/$(package).tar
  	chmod 644 debian/$(srcpkg)/usr/src/$(package).tar.gz
- ############################ modules stuff #################################
  
! build-modules: build-modules-stamp
  
! build-modules-stamp: 
! 	-ln -s @sys/dest dest
! 	-ln -s $(SYS_NAME) @sys
! 	sh configure --with-afs-sysname=$(SYS_NAME) --with-linux-kernel-headers=$(KSRC)
! 	make dest_only_libafs
  	touch build-modules-stamp
  
! binary-modules: build-modules
! # Perform some tests
! 	test -f debian/rules
! 	test `id -u` = "0"
! 
! # Setup everything first
! 	-rm -rf debian/$(modulepkg) debian/substvars
! 	install -d debian/$(modulepkg)
! 
! # Install the software
! 	install -d -g root -o root -m 755 debian/$(modulepkg)/lib/modules/$(KVERS)/fs
! 	install -g root -o root -m 755  dest/root.client/usr/vice/etc/modload/*.o \
! 		debian/$(modulepkg)/lib/modules/$(KVERS)/fs
! # Fix some stuff up
! 	install -d -o root -g root -m 755 debian/$(modulepkg)/usr/share/doc
! 	ln -s openafs-client debian/$(modulepkg)/usr/share/doc/$(modulepkg)
! 	rm -rf debian/$(modulepkg)/usr/include
! ifeq ($(KERNEL_DEPENDS),y)
! 	sh debian/prep-modules $(KSRC) debian/control.module &gt; debian/control
! else
! 	sh debian/prep-modules $(KSRC) debian/control.module-image &gt; debian/control
! endif
  
! # Install control files
! 	install -d -o root -g root -m 755 debian/$(modulepkg)/DEBIAN
! 	install -p -o root -g root -m 755 debian/prerm.mod \
! 		debian/$(modulepkg)/DEBIAN/prerm
! 	install -p -o root -g root -m 755 debian/postinst.mod \
! 		debian/$(modulepkg)/DEBIAN/postinst
! 
! # And now.. for the final packaging!
! 	find debian/$(modulepkg) -type f | grep -v "./DEBIAN" | xargs md5sum | \
! 		sed -e 's#debian/$(modulepkg)/##' &gt; debian/$(modulepkg)/DEBIAN/md5sums
! 
! 	dpkg-gencontrol -isp \
! 		-p$(modulepkg) \
! 		-v`cat debian/VERSION` \
! 		-Pdebian/$(modulepkg)
! 	chown -R root.root debian/$(modulepkg)
! 	chmod -R go=rX debian/$(modulepkg)
! 	dpkg --build debian/$(modulepkg) $(MODDIR)
--- 9,281 ----
  # Uncomment this to turn on verbose mode. 
  #export DH_VERBOSE=1
  
  # This has to be exported to make some magic below work.
  export DH_OPTIONS
  
! ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
!     DEBIAN_OPT_FLAGS = --disable-optimize --disable-lwp-optimize
!     DEBIAN_KERN_FLAGS = --disable-kernel-optimize
! else
!     DEBIAN_OPT_FLAGS =
!     DEBIAN_KERN_FLAGS =
! endif
! 
  ifndef KSRC
!     KSRC = /usr/src/linux
  endif
! ifndef KPKG_DEST_DIR
!     KPKG_DEST_DIR = ..
! endif
! KVERS := $(shell perl debian/kernel-version $(KSRC))
  export KSRC 
  export KVERS
+ export KPKG_DEST_DIR
+ 
+ SYS_NAME  := $(shell KSRC="$(KSRC)" KVERS="$(KVERS)" sh debian/sysname)
  
+ package    = openafs
+ srcpkg     = openafs-modules-source
+ modulepkg := openafs-modules-$(KVERS)${INT_SUBARCH}
+ moduledir := debian/$(modulepkg)/lib/modules/$(KVERS)/fs
+ 
+ # These packages have lintian overrides.
+ LINTIAN_PACKAGES = openafs-dbserver openafs-client openafs-fileserver
+ 
+ # The /usr/share/doc directory for these packages should be a symlink to
+ # /usr/share/doc/openafs-client.  Any package on this list must depend on
+ # openafs-client.
+ DOC_PACKAGES = libpam-openafs-kaserver openafs-dbserver openafs-fileserver \
+ 	openafs-kpasswd
+ 
+ # These variable is used only by get-orig-source, which will normally only be
+ # run by maintainers.
+ VERSION   = 1.4.0
+ UPSTREAM  = /afs/grand.central.org/software/openafs/$(VERSION)
+ 
+ # Download the upstream source and do the repackaging that we have to do for
+ # DFSG reasons.  This assumes AFS is mounted, as it's generally only used by
+ # the package maintainers.
+ get-orig-source:
+ 	cp $(UPSTREAM)/openafs-$(VERSION)-src.tar.bz2 .
+ 	tar xjf openafs-$(VERSION)-src.tar.bz2
+ 	rm openafs-$(VERSION)-src.tar.bz2
+ 	rm -r openafs-$(VERSION)/src/packaging/MacOS
+ 	rm -r openafs-$(VERSION)/src/WINNT
+ 	tar cf openafs_$(VERSION).orig.tar openafs-$(VERSION)
+ 	rm -r openafs-$(VERSION)
+ 	gzip -9 openafs_$(VERSION).orig.tar
  
  configure: configure-stamp
  configure-stamp:
+ 	@if test x"$(SYS_NAME)" = x"UNKNOWN" ; then exit 1 ; fi
  	dh_testdir
! 	afslogsdir=/var/log/openafs afslocaldir=/etc/openafs/server-local \
! 	    sh configure \
! 	    --with-afs-sysname=$(SYS_NAME) --disable-kernel-module \
! 	    --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \
! 	    --localstatedir=/var/lib --enable-supergroups \
! 	    --enable-largefile-fileserver --enable-debug --enable-lwp-debug \
! 	    $(DEBIAN_OPT_FLAGS)
! 	chmod a+x src/libafs/make_kbuild_makefile.pl         
  	touch configure-stamp
  
  build: configure-stamp build-stamp
  build-stamp:
  	dh_testdir
! 	mkdir -p $(CURDIR)/debian/tmp
! 	$(MAKE) install_nolibafs DESTDIR=$(CURDIR)/debian/tmp
! 	chmod +x debian/afs-rootvol debian/afs-newcell debian/doc/build-man
! 	cd debian/doc &amp;&amp; ./build-man
  	touch build-stamp
  
  clean:
  	dh_testdir
  	dh_testroot
! 	rm -f build-stamp configure-stamp
! 	rm -f build-modules-stamp configure-modules-stamp
! ifeq (Makefile,$(wildcard Makefile))
! 	$(MAKE) distclean
! endif
! 	rm -rf debian/doc/man1 debian/doc/man5 debian/doc/man8
  	dh_clean
  
  install: DH_OPTIONS=
  install: build
  	dh_testdir
  	dh_testroot
  	dh_installdirs
! 	dh_install
! 
! 	set -e; for pkg in $(LINTIAN_PACKAGES) ; do \
! 	    install -d debian/$$pkg/usr/share/lintian/overrides; \
! 	    install -m 644 -c debian/$$pkg.lintian \
! 	        debian/$$pkg/usr/share/lintian/overrides/$$pkg; \
! 	done
! 	set -e; for pkg in $(DOC_PACKAGES) ; do \
! 	    ln -s openafs-client debian/$$pkg/usr/share/doc/$$pkg; \
! 	done
! 
! 	mv debian/openafs-client/usr/bin/pagsh \
! 	    debian/openafs-client/usr/bin/pagsh.openafs
! 	mv debian/openafs-client/usr/share/man/man1/pagsh.1 \
! 	    debian/openafs-client/usr/share/man/man1/pagsh.openafs.1
! 	mv debian/openafs-client/usr/bin/up \
! 	    debian/openafs-client/usr/bin/afs-up
! 	mv debian/openafs-client/usr/share/man/man1/up.1 \
! 	    debian/openafs-client/usr/share/man/man1/afs-up.1
! 
! 	install -m 644 -c debian/tmp/usr/lib/pam_afs.so.1 \
! 	    debian/libpam-openafs-kaserver/lib/security/pam_afs.so
! 	install -m 644 -c debian/tmp/usr/lib/pam_afs.krb.so.1 \
! 	    debian/libpam-openafs-kaserver/lib/security/pam_afs.krb.so
! 
! 	install -d debian/openafs-dbserver/usr/share/man/man8
! 	/usr/bin/docbook-to-man debian/pt_util.sgml \
! 	    &gt;debian/openafs-dbserver/usr/share/man/man8/pt_util.8
! 	( cd debian &amp;&amp; pod2man --section 8 --center "Debian GNU/Linux" \
! 	    afs-rootvol ) \
! 	    &gt;debian/openafs-dbserver/usr/share/man/man8/afs-rootvol.8
! 	( cd debian &amp;&amp; pod2man --section 8 --center "Debian GNU/Linux" \
! 	    afs-newcell ) \
! 	    &gt;debian/openafs-dbserver/usr/share/man/man8/afs-newcell.8
  
! # Build architecture-independent files here.  Pass -i to all debhelper
! # commands in this target to reduce clutter.
  binary-indep: DH_OPTIONS=-i
  binary-indep: build install binary-source
  	dh_testdir
  	dh_testroot
! 	dh_installchangelogs NEWS
  	dh_installdocs
  	dh_link
  	dh_compress
  	dh_fixperms
  	dh_installdeb
  	dh_gencontrol
  	dh_md5sums
  	dh_builddeb
  
! # Build architecture-dependent files here.  Pass -a to all debhelper commands
! # in this target to reduce clutter.
  binary-arch: DH_OPTIONS=-a
  binary-arch: build install
  	dh_testdir
  	dh_testroot
! 	dh_installchangelogs NEWS
  	dh_installdocs
! 	dh_installdebconf
  	DH_OPTIONS= dh_installinit -popenafs-client -r -- defaults 25 18
  	DH_OPTIONS= dh_installinit -popenafs-fileserver -r
  	dh_link
+ 	dh_strip
  	dh_compress
  	dh_fixperms
  	chmod 700 debian/openafs-client/var/cache/openafs
  	chmod 700 debian/openafs-dbserver/var/lib/openafs/db
+ 	chmod 700 debian/openafs-fileserver/etc/openafs/server
  	chmod 700 debian/openafs-fileserver/var/lib/openafs/cores
! 	dh_perl
  	dh_installdeb
  	dh_shlibdeps
  	dh_gencontrol
  	dh_md5sums
  	dh_builddeb
  
! binary: binary-indep binary-arch
  
+ #####################  Building openafs-modules-source  ######################
  
  binary-source:
! 	dh_testdir
! 	dh_testroot
  	-rm -rf debian/$(srcpkg) debian/substvars
  	install -d debian/$(srcpkg)/usr/src/modules/$(package)
! 	find . \( -name \*.o -o -path ./debian/$(srcpkg) -o -path \*/CVS \
! 	    -o -path \*/.svn -o -path ./src/WINNT  \
! 	    -o -path ./obj -o -path ./$(SYS_NAME)  \
! 	    -o \( -path ./debian/\* -type d \) \
! 	    -o -path ./debian/\*debhelper \) -prune -o -print | \
! 	        cpio -admp debian/$(srcpkg)/usr/src/modules/$(package)
! 	cd debian/$(srcpkg)/usr/src/modules/$(package) &amp;&amp; \
! 	    $(MAKE) -f debian/rules clean &amp;&amp; \
! 	    mv debian/kern-sysname debian/sysname
! 	-cd debian/$(srcpkg)/usr/src/modules/$(package) &amp;&amp; \
! 	    rm -rf src/libafs/rx src/libafs/afs src/libafs/afsint
! 	chown -R root.src debian/$(srcpkg)
  	find debian/$(srcpkg) -type d | xargs chmod 755
  	find debian/$(srcpkg) -type f -perm -100 | xargs chmod 755
  	find debian/$(srcpkg) -type f -not -perm -100 | xargs chmod 644
+ 	chmod 775 debian/$(srcpkg)/usr/src/modules
  	cd debian/$(srcpkg)/usr/src &amp;&amp; \
! 	    tar cf $(package).tar modules &amp;&amp; \
! 	    rm -r modules
  	gzip -9 debian/$(srcpkg)/usr/src/$(package).tar
  	chmod 644 debian/$(srcpkg)/usr/src/$(package).tar.gz
  
! ####################  Module package support (make-kpkg)  ####################
! 
! kdist_configure: configure-modules-stamp
! 
! kdist_image: build-modules-stamp
! 	$(ROOT_CMD) $(MAKE) $(MFLAGS) -f debian/rules binary-modules
! 	$(ROOT_CMD) $(MAKE) $(MFLAGS) -f debian/rules clean
! 
! kdist: build-modules-stamp
! 	$(ROOT_CMD) $(MAKE) $(MFLAGS) -f debian/rules binary-modules
! 	KSRC="$(KSRC)" KMAINT="$(KMAINT)" KEMAIL="$(KEMAIL)" \
! 	    sh -v debian/genchanges.sh
! 	$(ROOT_CMD) $(MAKE) $(MFLAGS) -f debian/rules clean
! 
! kdist_clean:
! 	$(ROOT_CMD) $(MAKE) $(MFLAGS) -f debian/rules clean
  
! ########################  Kernel module build rules  #########################
! 
! configure-modules: configure-modules-stamp
! configure-modules-stamp:
! 	@if test x"$(SYS_NAME)" = x"UNKNOWN" ; then exit 1 ; fi
! 	@if test x"$(KVERS)" = x ; then \
! 	    echo 'No version in $(KSRC)/include/linux/version.h' &gt;&amp;2 ; \
! 	    exit 1 ; \
! 	fi
! 	sh debian/prep-modules $(KSRC)
! 	sh configure --with-afs-sysname=$(SYS_NAME) \
! 	    --with-linux-kernel-headers=$(KSRC) --prefix=`pwd`/debian/tmp \
! 	    --enable-debug --enable-lwp-debug --enable-kernel-debug \
! 	    $(DEBIAN_OPT_FLAGS) $(DEBIAN_KERN_FLAGS)
! 	touch configure-modules-stamp
! 
! build-modules: build-modules-stamp
! build-modules-stamp: configure-modules-stamp
! 	make only_libafs
  	touch build-modules-stamp
  
! install-modules: build-modules-stamp
! 	dh_testdir
! 	dh_testroot
! 	dh_clean -k
! 	cd src/libafs &amp;&amp; make install
! 	install -d -g root -o root -m 755 $(moduledir)
! 	install -g root -o root -m 755 debian/tmp/lib/openafs/*o $(moduledir)/
! 	if test -f $(moduledir)/openafs.o \
! 	        -a ! -f $(moduledir)/openafs.mp.o ; then \
! 	    ln $(moduledir)/openafs.o $(moduledir)/openafs.mp.o || exit 1 ; \
! 	fi
  
! binary-modules: install-modules
! 	dh_testdir
! 	dh_testroot
! 	dh_installchangelogs NEWS
! 	dh_installdocs
! 	dh_installmodules
! 	dh_strip
! 	dh_link
! 	dh_compress
! 	dh_fixperms
! 	dh_installdeb
! 	dh_gencontrol -- -v`cat debian/VERSION`
! 	dh_md5sums
! 	dh_builddeb --destdir="$(KPKG_DEST_DIR)"
! 
! .PHONY: build clean binary-indep binary-arch binary install configure
! .PHONY: kdist_configure kdist_image kdist kdist_clean binary-source
Index: openafs/src/packaging/Debian/sysname
diff -c openafs/src/packaging/Debian/sysname:1.1 openafs/src/packaging/Debian/sysname:1.3
*** openafs/src/packaging/Debian/sysname:1.1	Mon Aug 26 16:52:03 2002
--- openafs/src/packaging/Debian/sysname	Thu Mar 23 16:06:18 2006
***************
*** 1,28 ****
  #!/bin/sh
! case `arch` in
!     alpha)
! 	echo alpha_linux_22
! 	;;
  i[3456]86)
! 	echo i386_linux22
! ;;
!     ia64)
      echo ia64_linux24
! ;;
!     parisc*)
! 	echo parisc_linux24
! 	;;
!     ppc)
! 	echo ppc_linux22
! 	;;
!     sparc|sparc64)
! 	echo sparc_linux22
! 	;;
!     s390)
!     echo s390_linux22
!     ;;
! 	*)
! 	echo ERROr:  sysname not yet known
! 	exit 1
! 
  esac
--- 1,40 ----
  #!/bin/sh
! # Maps Debian architectures to AFS sysnames for building the clients and
! # libraries.  This doesn't worry about the kernel version; kern-sysname
! # does that when building the kernel module.
! #
! # Not all architectures are listed, only those that OpenAFS supports.
! 
! case `dpkg --print-installation-architecture` in
! alpha)
!     echo alpha_linux_24
!     ;;
! amd64)
!     echo amd64_linux24
!     ;;
! hppa)
!     echo parisc_linux24
!     ;;
  i[3456]86)
!     echo i386_linux24
!     ;;
! ia64)
      echo ia64_linux24
!     ;;
! powerpc)
!     echo ppc_linux24
!     ;;
! ppc64)
!     echo ppc64_linux24
!     ;;
! s390)
!     echo s390_linux24
!     ;;
! sparc|sparc64)
!     echo sparc_linux24
!     ;;
! *)
!     echo "ERROR: unsupported architecture" &gt;&amp;2
!     echo UNKNOWN
!     exit 1
  esac
Index: openafs/src/packaging/Debian/doc/build-man
diff -c /dev/null openafs/src/packaging/Debian/doc/build-man:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/doc/build-man	Thu Mar 23 15:19:12 2006
***************
*** 0 ****
--- 1,56 ----
+ #!/bin/sh
+ #
+ # Install man pages, but fixing up paths as we go.  All of the man pages
+ # are written to use the Transarc paths, and this script fixes those paths to
+ # be correct for the chosen configure options as the man pages are installed.
+ 
+ set -e
+ 
+ manpage="$1"
+ dest="$2"
+ 
+ afsbackupdir=/var/lib/openafs/backup
+ afsbosconfigdir=/etc/openafs
+ afsconfdir=/etc/openafs/server
+ afsdbdir=/var/lib/openafs/db
+ afslocaldir=/etc/openafs/server-local
+ afslogsdir=/var/log/openafs
+ afssrvlibexecdir=/usr/lib/openafs
+ viceetcdir=/etc/openafs
+ 
+ # Build a particular man page.  Takes the section title, the section number,
+ # the filename of the POD page, and the output file.
+ buildpage () {
+     pod2man -c "$1" -r OpenAFS -s "$2" "$3" | \
+         sed -e "s%/usr/afs/local/BosConfig%${afsbosconfigdir}/BosConfig%g" \
+             -e "s%/usr/afs/etc%${afsconfdir}%g" \
+             -e "s%/usr/afs/backup%${afsbackupdir}%g" \
+             -e "s%/usr/afs/bin%${afssrvlibexecdir}%g" \
+             -e "s%/usr/afs/db%${afsdbdir}%g" \
+             -e "s%/usr/afs/local%${afslocaldir}%g" \
+             -e "s%/usr/afs/logs%${afslogsdir}%g" \
+             -e "s%/usr/vice/etc%${viceetcdir}%g" &gt; "$4"
+ }
+ 
+ # Create the output directories.
+ mkdir -p man1 man5 man8
+ 
+ # Do the work with lots of calls to buildpage.
+ cd pod1
+ for f in *.pod ; do
+     buildpage 'AFS Command Reference' 1 "$f" \
+         ../man1/`echo "$f" | sed 's/\.pod$//'`.1
+ done
+ cd ..
+ cd pod5
+ for f in *.pod ; do
+     buildpage 'AFS File Reference' 5 "$f" \
+         ../man5/`echo "$f" | sed 's/\.pod$//'`.5
+ done
+ cd ..
+ cd pod8
+ for f in *.pod ; do
+     buildpage 'AFS Command Reference' 8 "$f" \
+         ../man8/`echo "$f" | sed 's/\.pod$//'`.8
+ done
+ cd ..
Index: openafs/src/packaging/Debian/patches/README
diff -c /dev/null openafs/src/packaging/Debian/patches/README:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/patches/README	Thu Mar 23 15:19:14 2006
***************
*** 0 ****
--- 1,9 ----
+ This directory contains patches relative to the upstream OpenAFS source.
+ It is not used automatically as part of the build process and is not
+ guaranteed to be completely up-to-date; it is intended as documentation of
+ significant divergences, a place to store patches that should be sent
+ upstream, and a place to document the current status of patches.
+ 
+ Simple Debian-specific changes that aren't of interest to upstream will
+ not be included here, such as updating config.{guess,sub} or changing
+ paths to fit with the FHS.
Index: openafs/src/packaging/Debian/patches/module-name
diff -c /dev/null openafs/src/packaging/Debian/patches/module-name:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/patches/module-name	Thu Mar 23 15:19:14 2006
***************
*** 0 ****
--- 1,49 ----
+ Upstream uses libafs as the module name, mostly for historic reasons.  It
+ also uses a different module name depending on whether the module is built
+ for SMP systems, something that Debian deals with by creating separate
+ packages.  This patch changes the name of the module to openafs and
+ removes the separate name for the SMP version.
+ 
+ Probably not acceptable upstream.
+ 
+ --- openafs-1.3.87.orig/src/libafs/MakefileProto.LINUX.in
+ +++ openafs-1.3.87/src/libafs/MakefileProto.LINUX.in
+ @@ -216,8 +216,8 @@
+  
+  # Below this line are targets when in the COMMON directory:
+  # For Linux there is no kernel NFS server.
+ -LIBAFS = libafs-${CLIENT}.${LINUX_MODULE_EXT}
+ -LIBAFS_MP = libafs-${CLIENT}.mp.${LINUX_MODULE_EXT}
+ +LIBAFS = openafs.${LINUX_MODULE_EXT}
+ +LIBAFS_MP = openafs.${LINUX_MODULE_EXT}
+  LIBAFS_EP = libafs-${CLIENT}.ep.${LINUX_MODULE_EXT}
+  LIBAFS_BM = libafs-${CLIENT}.bm.${LINUX_MODULE_EXT}
+  
+ @@ -226,10 +226,8 @@
+  INST_LIBAFS_EP = ${DESTDIR}${afskerneldir}/${LIBAFS_EP}
+  INST_LIBAFS_BM = ${DESTDIR}${afskerneldir}/${LIBAFS_BM}
+  
+ -DEST_LIBAFS = ${DEST}/root.client/usr/vice/etc/modload/${LIBAFS}
+ -DEST_LIBAFS_MP = ${DEST}/root.client/usr/vice/etc/modload/${LIBAFS_MP}
+ -DEST_LIBAFS_EP = ${DEST}/root.client/usr/vice/etc/modload/${LIBAFS_EP}
+ -DEST_LIBAFS_BM = ${DEST}/root.client/usr/vice/etc/modload/${LIBAFS_BM}
+ +DEST_LIBAFS = ${DEST}/root.client/usr/vice/etc/modload/openafs.o
+ +DEST_LIBAFS_MP = ${DEST}/root.client/usr/vice/etc/modload/openafs.mp.o
+  
+  
+  libafs:	$(LIBAFS) 
+ @@ -245,11 +243,11 @@
+  	echo BM Build Complete
+  
+  &lt;linux26 linux_26 umlinux26&gt;
+ -${LIBAFS} ${LIBAFS_MP} ${LIBAFS_EP} ${LIBAFS_BM}: libafs.ko
+ -	cp libafs.ko $@
+ +${LIBAFS} ${LIBAFS_MP} ${LIBAFS_EP} ${LIBAFS_BM}: openafs.ko
+ +	cp openafs.ko $@
+  
+  .FORCE:
+ -libafs.ko: .FORCE
+ +openafs.ko: .FORCE
+  	env EXTRA_CFLAGS="${EXTRA_CFLAGS}" @TOP_SRCDIR@/libafs/make_kbuild_makefile.pl ${KDIR} $@ @TOP_OBJDIR@/src/config/Makefile.config Makefile.afs Makefile.common
+  	env EXTRA_CFLAGS="${EXTRA_CFLAGS}" $(MAKE) -C ${LINUX_KERNEL_PATH} M=@TOP_OBJDIR@/src/libafs/${KDIR} modules
+          
Index: openafs/src/packaging/Debian/patches/pam
diff -c /dev/null openafs/src/packaging/Debian/patches/pam:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/patches/pam	Thu Mar 23 15:19:14 2006
***************
*** 0 ****
--- 1,158 ----
+ The standard upstream source builds the PAM modules against static
+ libraries, which means they contain non-PIC code.  This isn't allowed by
+ Debian Policy and doesn't work on some supported platforms.
+ 
+ Two approaches for fixing this have been tried.  One is to rebuild the
+ various object files that are part of the libraries PIC and then link with
+ those object files.  The other, which this implements, is to link with the
+ object files used to create the libafsauthent and libafsrpc shared
+ libraries (which can't be shipped since they don't have a stable API or
+ correct SONAME).  The latter means that the PAM modules must also be
+ linked with libpthread, but that's a feature since that means they'll work
+ with sshd built threaded.
+ 
+ Not submitted upstream yet.  The call to rx_Init should be submitted
+ upstream and would probably be accepted.  Upstream would probably rather
+ link the PAM modules against the shared libraries rather than accepting
+ this hack, which is unsuitable for Debian until the shared libraries are
+ handled more consistently.
+ 
+ --- openafs-1.3.87.orig/src/pam/Makefile.in
+ +++ openafs-1.3.87/src/pam/Makefile.in
+ @@ -25,7 +25,17 @@
+  	  afs_pam_msg.o afs_message.o AFS_component_version_number.o
+     OBJS = $(SHOBJS) test_pam.o
+  INCLUDES=-I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} 
+ -CFLAGS =  ${DEBUG} ${INCLUDES} ${PAM_CFLAGS}
+ +CFLAGS =  ${DEBUG} ${INCLUDES} ${PAM_CFLAGS} ${MT_CFLAGS}
+ +
+ +# For Debian, we link directly with the object files that would have gone
+ +# into the libafsrpc and libafsauthent shared libraries.  The shared libraries
+ +# themselves cannot be used because the interface isn't stable and they have
+ +# no SONAME, but this is the easiest way of getting PIC objects built with the
+ +# pthread API.
+ +SHLIB_OBJS	:= `ls ../shlibafsauthent/*.o | grep -v version_num` \
+ +		   `ls ../shlibafsrpc/*.o | grep -v version_num`
+ +KRB_SHLIB_OBJS	:= `ls ../shlibafsauthent/*.o | egrep -v 'version_num|ktc.o'` \
+ +		   `ls ../shlibafsrpc/*.o | grep -v version_num`
+  
+  all: test_pam ${TOP_LIBDIR}/pam_afs.so.1 ${TOP_LIBDIR}/pam_afs.krb.so.1
+  
+ @@ -39,14 +49,18 @@
+  	${CC} ${CFLAGS} -c ${srcdir}/afs_auth.c -o afs_auth.o
+  
+  afs_auth_krb.o: afs_auth.c afs_pam_msg.h afs_message.h afs_util.h
+ -	${CC} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/afs_auth.c -o afs_auth_krb.o
+ +	${CC} ${CFLAGS} -DAFS_KERBEROS_ENV  -c ${srcdir}/afs_auth.c -o afs_auth_krb.o
+  
+  afs_util.o: afs_util.c afs_pam_msg.h afs_message.h afs_util.h
+  	${CC} ${CFLAGS} -c ${srcdir}/afs_util.c -o afs_util.o
+  
+ +
+  afs_util_krb.o: afs_util.c afs_pam_msg.h afs_message.h afs_util.h
+  	${CC} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/afs_util.c -o afs_util_krb.o
+  
+ +ktc.o: ${srcdir}/../auth/ktc.c
+ +	${CC} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/../auth/ktc.c
+ +
+  pam_afs.so.1: $(SHOBJS) afs_setcred.o afs_auth.o afs_util.o
+  	set -x; \
+  	case "$(SYS_NAME)" in \
+ @@ -59,8 +73,9 @@
+  			afs_setcred.o afs_auth.o afs_util.o \
+  			$(SHOBJS) $(LIBS) ;; \
+  	*linux*) \
+ -		$(CC) $(LDFLAGS) -o $@ afs_setcred.o \
+ -			afs_auth.o afs_util.o $(SHOBJS) $(LIBS) ;;\
+ +		$(CC) $(LDFLAGS) $(PAM_CFLAGS) -o $@ afs_setcred.o \
+ +			afs_auth.o afs_util.o $(SHOBJS) $(SHLIB_OBJS) \
+ +			$(MT_LIBS) -lpam -lresolv;;\
+  	*fbsd*| *nbsd*) \
+  		$(CC) $(LDFLAGS) -o $@ afs_setcred.o \
+  			afs_auth.o afs_util.o $(SHOBJS) $(LIBS) ;;\
+ @@ -68,7 +83,7 @@
+  		echo No link line for system $(SYS_NAME). ;; \
+  	esac
+  
+ -pam_afs.krb.so.1: $(SHOBJS) afs_setcred_krb.o afs_auth_krb.o afs_util_krb.o
+ +pam_afs.krb.so.1: $(SHOBJS) afs_setcred_krb.o afs_auth_krb.o afs_util_krb.o ktc.o
+  	set -x; \
+  	case "$(SYS_NAME)" in \
+  	hp_ux* | ia64_hpux*) \
+ @@ -81,7 +96,8 @@
+  			$(SHOBJS) $(LDFLAGS) $(KLIBS) ;; \
+  	*linux*) \
+  		$(CC) $(LDFLAGS) -o $@ afs_setcred_krb.o \
+ -			afs_auth_krb.o afs_util_krb.o $(SHOBJS) $(KLIBS) ;;\
+ +			afs_auth_krb.o afs_util_krb.o ktc.o $(SHOBJS) \
+ +			$(KRB_SHLIB_OBJS) $(MT_LIBS) -lpam -lresolv;;\
+  	*fbsd*| *nbsd*) \
+  		$(CC) $(LDFLAGS) -o $@ afs_setcred_krb.o \
+  			afs_auth_krb.o afs_util_krb.o $(SHOBJS) $(KLIBS) ;;\
+ --- openafs-1.3.87.orig/src/pam/afs_setcred.c
+ +++ openafs-1.3.87/src/pam/afs_setcred.c
+ @@ -52,7 +52,7 @@
+      int refresh_token = 0;
+      int set_expires = 0;	/* the default is to not to set the env variable */
+      int use_klog = 0;
+ -    int i;
+ +    int i, code;
+      struct pam_conv *pam_convp = NULL;
+      char my_password_buf[256];
+      char *cell_ptr = NULL;
+ @@ -281,6 +281,11 @@
+  #endif
+  	}
+  
+ +	if ((code = rx_Init(0)) != 0) {
+ +	    pam_afs_syslog(LOG_ERR, PAMAFS_KAERROR, code);
+ +	    RET(PAM_AUTH_ERR);
+ +	}
+ +
+  	if (flags &amp; PAM_REFRESH_CRED) {
+  	    if (use_klog) {
+  		auth_ok = !do_klog(user, password, "00:00:01", cell_ptr);
+ --- openafs-1.3.87.orig/src/pam/afs_auth.c
+ +++ openafs-1.3.87/src/pam/afs_auth.c
+ @@ -314,6 +314,10 @@
+  	    if (cpid &lt;= 0) {	/* The child process */
+  		if (logmask &amp;&amp; LOG_MASK(LOG_DEBUG))
+  		    syslog(LOG_DEBUG, "in child");
+ +		if ((code = rx_Init(0)) != 0) {
+ +		    pam_afs_syslog(LOG_ERR, PAMAFS_KAERROR, code);
+ +		    exit(0);
+ +		}
+  		if (refresh_token || set_token)
+  		    code = ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION, user,	/* kerberos name */
+  						      NULL,	/* instance */
+ @@ -363,6 +367,10 @@
+  	    pam_afs_syslog(LOG_ERR, PAMAFS_PAMERROR, errno);
+  	}
+      } else {			/* dont_fork, used by httpd */
+ +	if ((code = rx_Init(0)) != 0) {
+ +	    pam_afs_syslog(LOG_ERR, PAMAFS_KAERROR, code);
+ +	    RET(PAM_AUTH_ERR);
+ +	}
+  	if (logmask &amp;&amp; LOG_MASK(LOG_DEBUG))
+  	    syslog(LOG_DEBUG, "dont_fork");
+  	if (refresh_token || set_token)
+ --- openafs-1.3.87.orig/Makefile.in
+ +++ openafs-1.3.87/Makefile.in
+ @@ -507,8 +507,6 @@
+  # pthread based user space RX library
+  shlibafsrpc: rx rxkad des
+  	case ${SYS_NAME} in \
+ -	amd64_linux24) \
+ -		echo Skipping shlibafsrpc for amd64_linux24 ;; \
+  	alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux11*|ia64_hpux*) \
+  	${COMPILE_PART1} shlibafsrpc ${COMPILE_PART2} ;; \
+  	*) \
+ @@ -517,8 +515,6 @@
+  
+  shlibafsauthent: ubik auth kauth shlibafsrpc
+  	case ${SYS_NAME} in \
+ -	amd64_linux24) \
+ -		echo Skipping shlibafsauthent for amd64_linux24 ;; \
+  	alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux11*|ia64_hpux*) \
+  	${COMPILE_PART1} shlibafsauthent ${COMPILE_PART2} ;; \
+  	*) \
Index: openafs/src/packaging/Debian/po/POTFILES.in
diff -c /dev/null openafs/src/packaging/Debian/po/POTFILES.in:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/po/POTFILES.in	Thu Mar 23 15:19:16 2006
***************
*** 0 ****
--- 1,2 ----
+ [type: gettext/rfc822deb] openafs-client.templates
+ [type: gettext/rfc822deb] openafs-fileserver.templates
Index: openafs/src/packaging/Debian/po/cs.po
diff -c /dev/null openafs/src/packaging/Debian/po/cs.po:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/po/cs.po	Thu Mar 23 15:19:16 2006
***************
*** 0 ****
--- 1,279 ----
+ #
+ #    Translators, if you are not familiar with the PO format, gettext
+ #    documentation is worth reading, especially sections dedicated to
+ #    this format, e.g. by running:
+ #         info -n '(gettext)PO Files'
+ #         info -n '(gettext)Header Entry'
+ #
+ #    Some information specific to po-debconf are available at
+ #            /usr/share/doc/po-debconf/README-trans
+ #         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+ #
+ #    Developers do not need to manually edit POT or PO files.
+ #
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: openafs 1.4rc1-1\n"
+ "Report-Msgid-Bugs-To: \n"
+ "POT-Creation-Date: 2005-08-18 12:47-0700\n"
+ "PO-Revision-Date: 2005-08-19 08:01+0200\n"
+ "Last-Translator: Martin Sin &lt;martin.sin@seznam.cz&gt;\n"
+ "Language-Team: Czech &lt;debian-l10n-czech@lists.debian.org&gt;\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=utf-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid "What hosts are DB servers for your home cell?"
+ msgstr "KterÃ© poÄÃ­taÄe jsou DB servery pro vaÅ¡i domovskou buÅˆku?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid ""
+ "AFS uses the file /etc/openafs/CellServDB to hold the list of servers that "
+ "should be contacted to find parts of a cell.  The cell you claim this "
+ "workstation belongs to is not in that file.  Enter the host names of the "
+ "database servers separated by spaces. IMPORTANT: If you are creating a new "
+ "cell and this machine is to be a database server in that cell, only enter "
+ "this machine's name; add the other servers later after they are functioning. "
+ "Also, do not enable the AFS client to start at boot on this server until the "
+ "cell is configured.  When you are ready you can edit /etc/openafs/afs.conf."
+ "client to enable the client."
+ msgstr ""
+ "AFS pouÅ¾Ã­vÃ¡ k uchovÃ¡vÃ¡nÃ­ seznamu serverÅ¯, kterÃ© majÃ­ bÃ½t kontaktovÃ¡ny pÅ™i "
+ "hledÃ¡nÃ­ ÄÃ¡stÃ­ buÅˆky, soubor /etc/openafs/CellServDB. BuÅˆka, do kterÃ© tato "
+ "stanice patÅ™Ã­, nenÃ­ ve zmÃ­nÄ›nÃ©m souboru uvedena. Zadejte mezerami oddÄ›lenÃ¡ "
+ "jmÃ©na databÃ¡zovÃ½ch serverÅ¯. DÅ®LEÅ½ITÃ‰: pokud vytvÃ¡Å™Ã­te novou buÅˆku a tento "
+ "poÄÃ­taÄ bude databÃ¡zovÃ½m serverem tÃ©to buÅˆky, pak staÄÃ­ pouze zadat jmÃ©no "
+ "poÄÃ­taÄe; ostatnÃ­ servery pÅ™idejte pozdÄ›ji aÅ¾ po jejich zprovoznÄ›nÃ­. Dokud "
+ "nebude buÅˆka nastavena, tak na tomto serveru nepovolujte spuÅ¡tÄ›nÃ­ AFS "
+ "klienta pÅ™i startu serveru. AÅ¾ budete pÅ™ipraveni, mÅ¯Å¾ete klienta povolit "
+ "Ãºpravou souboru /etc/openafs/afs.conf.client."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid "What AFS cell does this workstation belong to?"
+ msgstr "Ke kterÃ© buÅˆce AFS bude tento poÄÃ­taÄ nÃ¡leÅ¾et?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid ""
+ "AFS filespace is organized into cells or administrative domains. Each "
+ "workstation belongs to one cell.  Usually the cell is the DNS domain name of "
+ "the site."
+ msgstr ""
+ "SouborovÃ½ prostor systÃ©mu AFS je uspoÅ™Ã¡dÃ¡n do bunÄ›k nebo administrativnÃ­ch "
+ "domÃ©n. KaÅ¾dÃ¡ stanice patÅ™Ã­ jednÃ© buÅˆce. Obvykle je buÅˆkou domÃ©novÃ© jmÃ©no "
+ "skupiny."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid "How large is your AFS cache (kB)?"
+ msgstr "Jak velkÃ¡ je vaÅ¡e cache AFS (v kB)?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid ""
+ "AFS uses an area of the disk to cache remote files for faster access.  This "
+ "cache will be mounted on /var/cache/openafs.  It is important that the cache "
+ "not overfill the partition it is located on.  Often, people find it useful "
+ "to dedicate a partition to their AFS cache."
+ msgstr ""
+ "AFS pouÅ¾Ã­vÃ¡ urÄitÃ½ prostor na disku pro cachovÃ¡nÃ­ vzdÃ¡lenÃ½ch souborÅ¯, aby k "
+ "nim mÄ›l rychlejÅ¡Ã­ pÅ™Ã­stup. Tato cache bude pÅ™ipojena do /var/cache/openafs. "
+ "Je dÅ¯leÅ¾itÃ©, aby cache nepÅ™eplnila oblast na kterÃ© je umÃ­stÄ›na. ÄŒasto je "
+ "uÅ¾iteÄnÃ© umÃ­stit cache AFS do svÃ© vlastnÃ­ diskovÃ© oblasti."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid "Run Openafs client now and at boot?"
+ msgstr "Spustit klienta Openafs nynÃ­ a pÅ™i zavÃ¡dÄ›nÃ­ poÄÃ­taÄe?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid ""
+ "Should the Openafs filesystem be started and mounted at boot? Normally, most "
+ "users who install the openafs-client package expect to run it at boot.  "
+ "However, if you are planning on setting up a new cell or are on a laptop, "
+ "you may not want it started at boot time.  If you choose not to start AFS at "
+ "boot, run /etc/init.d/openafs-client force-start to start the client when "
+ "you wish to run it."
+ msgstr ""
+ "MÃ¡ bÃ½t souborovÃ½ systÃ©m Openafs spuÅ¡tÄ›n a pÅ™ipojen pÅ™i startu poÄÃ­taÄe? "
+ "VÄ›tÅ¡ina uÅ¾ivatelÅ¯, kteÅ™Ã­ instalujÃ­ balÃ­Äek openafs-client, oÄekÃ¡vÃ¡, Å¾e se "
+ "AFS spustÃ­ hned pÅ™i startu poÄÃ­taÄe. SamozÅ™ejmÄ›, pokud plÃ¡nujete nastavenÃ­ "
+ "novÃ© buÅˆky, nebo pokud pouÅ¾Ã­vÃ¡te laptop, pak byste zÅ™ejmÄ› AFS pÅ™i startu "
+ "spouÅ¡tÄ›t nechtÄ›li. ZvolÃ­te-li moÅ¾nost nespouÅ¡tÄ›t AFS pÅ™i startu poÄÃ­taÄe, "
+ "mÅ¯Å¾ete klienta spustit ruÄnÄ› pÅ™Ã­kazem /etc/init.d/openafs-client force-start."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid "Look up AFS cells in DNS?"
+ msgstr "Hledat buÅˆky AFS v DNS?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid ""
+ "In order to contact an AFS cell, you need the IP addresses of the cell's "
+ "database servers.  Normally, this information is read from /etc/openafs/"
+ "CellServDB.  However, if Openafs cannot find a cell in that file, it can use "
+ "DNS to look for AFSDB records that contain the information."
+ msgstr ""
+ "Pro kontaktovÃ¡nÃ­ buÅˆky AFS potÅ™ebujete znÃ¡t IP adresu databÃ¡zovÃ©ho serveru "
+ "buÅˆky. Obvykle lze tuto informaci pÅ™eÄÃ­st ze souboru /etc/openafs/"
+ "CellServDB. NicmÃ©nÄ› pokud Openafs nemÅ¯Å¾e najÃ­t buÅˆku v tomto souboru, mÅ¯Å¾e "
+ "pouÅ¾Ã­t DNS pro vyhledÃ¡nÃ­ AFSDB zÃ¡znamÅ¯, kterÃ© obsahujÃ­ poÅ¾adovanÃ© informace."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid "Encrypt authenticated traffic with AFS fileserver?"
+ msgstr "Å&nbsp;ifrovat autentikovanÃ½ provoz se souborovÃ½m serverem AFS?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid ""
+ "AFS provides a weak form of encryption that can optionally be used between a "
+ "client and the fileservers.  While this encryption is weaker than DES and "
+ "thus is not sufficient for highly confidential data, it does provide some "
+ "confidentiality and is likely to make the job of a casual attacker "
+ "significantly more difficult."
+ msgstr ""
+ "AFS poskytuje slabou formu Å¡ifrovÃ¡nÃ­, kterÃ¡ mÅ¯Å¾e bÃ½t nepovinnÄ› pouÅ¾ita mezi "
+ "klientem a souborovÃ½m serverem. PÅ™estoÅ¾e je toto Å¡ifrovÃ¡nÃ­ slabÅ¡Ã­ neÅ¾ DES a "
+ "tedy nenÃ­ dostateÄnÃ© pro velmi dÅ¯vÄ›rnÃ¡ data, poskytuje urÄitou formu utajenÃ­ "
+ "a urÄitÄ› tak ztÃ­Å¾Ã­ prÃ¡ci nÃ¡hodnÃ©mu ÃºtoÄnÃ­kovi."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid "Dynamically generate the contents of /afs?"
+ msgstr "Vygenerovat obsah /afs dynamicky?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "/afs generally contains an entry for each cell that a client can talk to. "
+ "Traditionally, these entries were generated by servers in the client's home "
+ "cell.  However, OpenAFS clients can generate the contents of /afs "
+ "dynamically based on the contents of /etc/openafs/CellServDB and DNS."
+ msgstr ""
+ "/afs obvykle obsahuje zÃ¡znam pro kaÅ¾dou buÅˆku, se kterou mÅ¯Å¾e klient "
+ "hovoÅ™it. TradiÄnÄ› jsou tyto zÃ¡znamy vytvÃ¡Å™eny servery v mateÅ™skÃ© buÅˆce "
+ "klienta. Klienti OpenAFS vÅ¡ak mohou generovat obsah adresÃ¡Å™e /afs dynamicky "
+ "na zÃ¡kladÄ› souboru /etc/openafs/CellServDB a systÃ©mu DNS."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "If you generate /afs dynamically, you may need to create /etc/openafs/"
+ "CellAlias to include aliases for common cells.  (The syntax of this file is "
+ "one line per alias, with the cell name, a space, and then the alias for that "
+ "cell.)"
+ msgstr ""
+ "Pokud vytvÃ¡Å™Ã­te /afs dynamicky, moÅ¾nÃ¡ budete muset vytvoÅ™it /etc/openafs/"
+ "CellAlias pro zaÄlenÄ›nÃ­ aliasÅ¯ bÄ›Å¾nÃ½ch bunÄ›k. (Syntaxe tohoto souboru je "
+ "jeden Å™Ã¡dek na alias, kterÃ½ se sklÃ¡dÃ¡ ze jmÃ©na buÅˆky, mezery a pak nÃ¡sleduje "
+ "alias pro tuto buÅˆku.)"
+ 
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid "Use fakestat to avoid hangs when listing /afs?"
+ msgstr "PouÅ¾Ã­t fakestat pro obejitÃ­ zatuhnutÃ­ pÅ™i vÃ½pisu /afs?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid ""
+ "Because AFS is a global file space, operations on the /afs directory can "
+ "generate significant network traffic.  If some AFS cells are unavailable "
+ "then looking at /afs using ls or a graphical file browser may hang your "
+ "machine for minutes.  AFS has an option to simulate answers to these "
+ "operations locally to avoid these hangs.  You want this option under most "
+ "circumstances."
+ msgstr ""
+ "ProtoÅ¾e je AFS globÃ¡lnÃ­ souborovÃ½ prostor, mohou operace na adresÃ¡Å™i /afs "
+ "vÃ½zraznÄ› zvÃ½Å¡it provoz na sÃ­ti. Pokud jsou nÄ›kterÃ© buÅˆky AFS nedosaÅ¾itelnÃ©, "
+ "pak mÅ¯Å¾e prohlÃ­Å¾enÃ­ /afs pomocÃ­ pÅ™Ã­kazu ls nebo grafickÃ©ho prohlÃ­Å¾eÄe "
+ "zpÅ¯sobit zatuhnutÃ­ poÄÃ­taÄe na dobu nÄ›kolika minut. AFS mÃ¡ volbu, kterÃ¡ "
+ "simuluje odpovÄ›di pro tyto operace a tak se snaÅ¾Ã­ vyhnout popsanÃ½m vÃ½padkÅ¯m. "
+ "Tuto volbu budete chtÃ­t pouÅ¾Ã­t ve vÄ›tÅ¡inÄ› pÅ™Ã­padÅ¯."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid "What cell does this server serve files for?"
+ msgstr "KterÃ½m buÅˆkÃ¡m mÃ¡ tento server poskytovat soubory?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid ""
+ "AFS fileservers belong to a cell.  They have the key for that cell's "
+ "Kerberos service and serve volumes into that cell.  Normally, this cell is "
+ "the same cell as the workstation's client belongs to."
+ msgstr ""
+ "SouborovÃ© servery AFS nÃ¡leÅ¾Ã­ buÅˆce. Servery majÃ­ klÃ­Ä ke sluÅ¾bÄ› Kerberos "
+ "danÃ© buÅˆky a v rÃ¡mci buÅˆky nabÃ­zejÃ­ souborovÃ© svazky. Tato buÅˆka je obvykle "
+ "shodnÃ¡ s buÅˆkou, ke kterÃ© patÅ™Ã­ klient na pracovnÃ­ stanici."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid "Upgrading will move files to new locations; continue?"
+ msgstr "UpgradovÃ¡nÃ­ pÅ™esune soubory do novÃ©ho umÃ­stÄ›nÃ­; pokraÄovat?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid ""
+ "Between Openafs 1.1 and Openafs 1.2, several files moved.  In particular, "
+ "files in /etc/openafs/server-local have been distributed to other "
+ "locations.  The BosConfig file is now located in /etc/openafs and the other "
+ "files are located in /var/lib/openafs.  If you continue with this upgrade, "
+ "these files will be moved.  You should use the bos restart command to reload "
+ "your servers.  Any configuration changes made before you do so will be lost."
+ msgstr ""
+ "Verze Openafs 1.1 a Openafs 1.2 majÃ­ pÅ™esunuty nÄ›kterÃ© soubory. PÅ™esnÄ›ji "
+ "Å™eÄeno: soubory z /etc/openafs/server-local byly pÅ™esunuty jinam. "
+ "KonfiguraÄnÃ­ soubor BosConfig je nynÃ­ umÃ­stÄ›n v /etc/openafs, ostatnÃ­ "
+ "soubory jsou uloÅ¾eny v adresÃ¡Å™i /var/lib/openafs. Pokud budete pokraÄovat v "
+ "aktualizaci, budou tyto soubory pÅ™esunuty. K opÄ›tovnÃ©mu naÄtenÃ­ vaÅ¡ich "
+ "serverÅ¯ mÅ¯Å¾ete pouÅ¾Ã­t pÅ™ikaz bos, kterÃ½ provede restart. JakÃ¡koliv zmÄ›na "
+ "konfigurace provedenÃ¡ pÅ™ed tÃ­mto restartem bude ztracena."
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid "OpenAFS file server probably does not work!"
+ msgstr "SouborovÃ½ server OpenAFS pravdÄ›podobnÄ› nepracuje!"
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid ""
+ "You are running the OpenAFS file server package on an alpha.  This probably "
+ "doesn't work; the DES code is flaky on the alpha, along with the threaded "
+ "file server.  Likely, the fileserver will simply fail to start, but if it "
+ "does load, data corruption may result.  You have been warned."
+ msgstr ""
+ "SouborovÃ½ server OpenAFS bÄ›Å¾Ã­ na Aplha systÃ©mu, coÅ¾ pravdÄ›podobnÄ› nebude "
+ "fungovat; DES kÃ³d se ve spojenÃ­ s vlÃ¡kny na souborovÃ©m serveru chovÃ¡ "
+ "podivnÄ›. SouborovÃ½ server nejpravdÄ›podobnÄ›ji vÅ¯bec nespustÃ­ nespustÃ­, ale "
+ "pokud nabÄ›hne, mÅ¯Å¾e dojÃ­t ke ztrÃ¡tÄ› dat. Byli jste varovÃ¡ni."
Index: openafs/src/packaging/Debian/po/de.po
diff -c /dev/null openafs/src/packaging/Debian/po/de.po:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/po/de.po	Thu Mar 23 15:19:16 2006
***************
*** 0 ****
--- 1,225 ----
+ #
+ #    Translators, if you are not familiar with the PO format, gettext
+ #    documentation is worth reading, especially sections dedicated to
+ #    this format, e.g. by running:
+ #         info -n '(gettext)PO Files'
+ #         info -n '(gettext)Header Entry'
+ #
+ #    Some information specific to po-debconf are available at
+ #            /usr/share/doc/po-debconf/README-trans
+ #         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+ #
+ #    Developers do not need to manually edit POT or PO files.
+ #
+ #, fuzzy
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: PACKAGE VERSION\n"
+ "Report-Msgid-Bugs-To: \n"
+ "POT-Creation-Date: 2005-08-18 12:47-0700\n"
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+ "Last-Translator: FULL NAME &lt;EMAIL@ADDRESS&gt;\n"
+ "Language-Team: LANGUAGE &lt;LL@li.org&gt;\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=ISO-8859-15\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid "What hosts are DB servers for your home cell?"
+ msgstr ""
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid ""
+ "AFS uses the file /etc/openafs/CellServDB to hold the list of servers that "
+ "should be contacted to find parts of a cell.  The cell you claim this "
+ "workstation belongs to is not in that file.  Enter the host names of the "
+ "database servers separated by spaces. IMPORTANT: If you are creating a new "
+ "cell and this machine is to be a database server in that cell, only enter "
+ "this machine's name; add the other servers later after they are functioning. "
+ "Also, do not enable the AFS client to start at boot on this server until the "
+ "cell is configured.  When you are ready you can edit /etc/openafs/afs.conf."
+ "client to enable the client."
+ msgstr ""
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ #, fuzzy
+ msgid "What AFS cell does this workstation belong to?"
+ msgstr "Für welche Zelle liefert der Server Dateien?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid ""
+ "AFS filespace is organized into cells or administrative domains. Each "
+ "workstation belongs to one cell.  Usually the cell is the DNS domain name of "
+ "the site."
+ msgstr ""
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid "How large is your AFS cache (kB)?"
+ msgstr ""
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid ""
+ "AFS uses an area of the disk to cache remote files for faster access.  This "
+ "cache will be mounted on /var/cache/openafs.  It is important that the cache "
+ "not overfill the partition it is located on.  Often, people find it useful "
+ "to dedicate a partition to their AFS cache."
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid "Run Openafs client now and at boot?"
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid ""
+ "Should the Openafs filesystem be started and mounted at boot? Normally, most "
+ "users who install the openafs-client package expect to run it at boot.  "
+ "However, if you are planning on setting up a new cell or are on a laptop, "
+ "you may not want it started at boot time.  If you choose not to start AFS at "
+ "boot, run /etc/init.d/openafs-client force-start to start the client when "
+ "you wish to run it."
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid "Look up AFS cells in DNS?"
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid ""
+ "In order to contact an AFS cell, you need the IP addresses of the cell's "
+ "database servers.  Normally, this information is read from /etc/openafs/"
+ "CellServDB.  However, if Openafs cannot find a cell in that file, it can use "
+ "DNS to look for AFSDB records that contain the information."
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid "Encrypt authenticated traffic with AFS fileserver?"
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid ""
+ "AFS provides a weak form of encryption that can optionally be used between a "
+ "client and the fileservers.  While this encryption is weaker than DES and "
+ "thus is not sufficient for highly confidential data, it does provide some "
+ "confidentiality and is likely to make the job of a casual attacker "
+ "significantly more difficult."
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid "Dynamically generate the contents of /afs?"
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "/afs generally contains an entry for each cell that a client can talk to. "
+ "Traditionally, these entries were generated by servers in the client's home "
+ "cell.  However, OpenAFS clients can generate the contents of /afs "
+ "dynamically based on the contents of /etc/openafs/CellServDB and DNS."
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "If you generate /afs dynamically, you may need to create /etc/openafs/"
+ "CellAlias to include aliases for common cells.  (The syntax of this file is "
+ "one line per alias, with the cell name, a space, and then the alias for that "
+ "cell.)"
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid "Use fakestat to avoid hangs when listing /afs?"
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid ""
+ "Because AFS is a global file space, operations on the /afs directory can "
+ "generate significant network traffic.  If some AFS cells are unavailable "
+ "then looking at /afs using ls or a graphical file browser may hang your "
+ "machine for minutes.  AFS has an option to simulate answers to these "
+ "operations locally to avoid these hangs.  You want this option under most "
+ "circumstances."
+ msgstr ""
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid "What cell does this server serve files for?"
+ msgstr "Für welche Zelle liefert der Server Dateien?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid ""
+ "AFS fileservers belong to a cell.  They have the key for that cell's "
+ "Kerberos service and serve volumes into that cell.  Normally, this cell is "
+ "the same cell as the workstation's client belongs to."
+ msgstr ""
+ "AFS-Dateiserver gehören zu einer Zelle. Die Server haben den Schlüssel für "
+ "den Kerberos-Service der Zelle und stellen Volumes für die Zelle bereit. "
+ "Normalerweise ist die Zelle identisch mit der des Clients"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid "Upgrading will move files to new locations; continue?"
+ msgstr ""
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid ""
+ "Between Openafs 1.1 and Openafs 1.2, several files moved.  In particular, "
+ "files in /etc/openafs/server-local have been distributed to other "
+ "locations.  The BosConfig file is now located in /etc/openafs and the other "
+ "files are located in /var/lib/openafs.  If you continue with this upgrade, "
+ "these files will be moved.  You should use the bos restart command to reload "
+ "your servers.  Any configuration changes made before you do so will be lost."
+ msgstr ""
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid "OpenAFS file server probably does not work!"
+ msgstr ""
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid ""
+ "You are running the OpenAFS file server package on an alpha.  This probably "
+ "doesn't work; the DES code is flaky on the alpha, along with the threaded "
+ "file server.  Likely, the fileserver will simply fail to start, but if it "
+ "does load, data corruption may result.  You have been warned."
+ msgstr ""
Index: openafs/src/packaging/Debian/po/fr.po
diff -c /dev/null openafs/src/packaging/Debian/po/fr.po:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/po/fr.po	Thu Mar 23 15:19:16 2006
***************
*** 0 ****
--- 1,292 ----
+ # translation of fr.po to French
+ #
+ #    Translators, if you are not familiar with the PO format, gettext
+ #    documentation is worth reading, especially sections dedicated to
+ #    this format, e.g. by running:
+ #         info -n '(gettext)PO Files'
+ #         info -n '(gettext)Header Entry'
+ #
+ #    Some information specific to po-debconf are available at
+ #            /usr/share/doc/po-debconf/README-trans
+ #         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+ #
+ #    Developers do not need to manually edit POT or PO files.
+ #
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: openafs 1.4rc1-1\n"
+ "Report-Msgid-Bugs-To: \n"
+ "POT-Creation-Date: 2005-08-18 12:47-0700\n"
+ "PO-Revision-Date: 2005-08-22 15:11+0200\n"
+ "Last-Translator: Christian Perrier &lt;bubulle@debian.org&gt;\n"
+ "Language-Team: French &lt;debian-l10n-french@lists.debian.org&gt;\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=ISO-8859-15\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ "X-Generator: KBabel 1.9.1\n"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid "What hosts are DB servers for your home cell?"
+ msgstr ""
+ "Hôtes serveurs de bases de données pour votre cellule locale («&nbsp;home "
+ "cell&nbsp;»)&nbsp;:"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid ""
+ "AFS uses the file /etc/openafs/CellServDB to hold the list of servers that "
+ "should be contacted to find parts of a cell.  The cell you claim this "
+ "workstation belongs to is not in that file.  Enter the host names of the "
+ "database servers separated by spaces. IMPORTANT: If you are creating a new "
+ "cell and this machine is to be a database server in that cell, only enter "
+ "this machine's name; add the other servers later after they are functioning. "
+ "Also, do not enable the AFS client to start at boot on this server until the "
+ "cell is configured.  When you are ready you can edit /etc/openafs/afs.conf."
+ "client to enable the client."
+ msgstr ""
+ "AFS utilise le fichier /etc/openafs/CellServDB pour conserver la liste des "
+ "serveurs à contacter pour trouver les constituants d'une cellule. La cellule "
+ "dont ce poste de travail est censé faire partie n'est pas indiquée dans ce "
+ "fichier. Veuillez indiquer les noms des serveurs de bases de données, "
+ "séparés par des espaces. IMPORTANT&nbsp;: si vous créez une nouvelle cellule et "
+ "que cette machine doit être un serveur de bases de données dans cette "
+ "cellule, veuillez seulement indiquer le nom de cette machine. N'ajoutez les "
+ "autres serveurs que plus tard, lorsqu'ils seront opérationnels. Enfin, "
+ "n'activez pas le client AFS au démarrage tant que cette cellule n'est pas "
+ "configurée. Quand vous serez prêt, vous pourrez modifier /etc/openafs/afs."
+ "conf.client pour mettre en service le client."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid "What AFS cell does this workstation belong to?"
+ msgstr "Cellule AFS dont ce poste de travail fait partie&nbsp;:"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid ""
+ "AFS filespace is organized into cells or administrative domains. Each "
+ "workstation belongs to one cell.  Usually the cell is the DNS domain name of "
+ "the site."
+ msgstr ""
+ "L'espace des fichiers AFS est organisé en cellules ou domaines "
+ "administratifs. Chaque poste de travail appartient à une cellule. "
+ "Habituellement, la cellule est le nom de domaine du site."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid "How large is your AFS cache (kB)?"
+ msgstr "Taille de votre cache pour AFS (en kilo-octets)&nbsp;:"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid ""
+ "AFS uses an area of the disk to cache remote files for faster access.  This "
+ "cache will be mounted on /var/cache/openafs.  It is important that the cache "
+ "not overfill the partition it is located on.  Often, people find it useful "
+ "to dedicate a partition to their AFS cache."
+ msgstr ""
+ "AFS utilise une partie du disque pour mettre en cache des fichiers distants "
+ "et accélérer les accès. Ce cache sera monté sur /var/cache/openafs. Il est "
+ "important que le cache ne remplisse pas la partition sur laquelle il est "
+ "situé. De nombreux utilisateurs choisissent de dédier une partition pour le "
+ "cache d'AFS."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid "Run Openafs client now and at boot?"
+ msgstr "Lancer le client AFS maintenant, puis à chaque démarrage&nbsp;?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid ""
+ "Should the Openafs filesystem be started and mounted at boot? Normally, most "
+ "users who install the openafs-client package expect to run it at boot.  "
+ "However, if you are planning on setting up a new cell or are on a laptop, "
+ "you may not want it started at boot time.  If you choose not to start AFS at "
+ "boot, run /etc/init.d/openafs-client force-start to start the client when "
+ "you wish to run it."
+ msgstr ""
+ "Veuillez indiquer si le système de fichiers Openafs doit être mis en service "
+ "et monté au démarrage. Normalement, la majorité des utilisateurs qui "
+ "installent le paquet openafs-client s'attendent à ce qu'il soit lancé au "
+ "démarrage. Cependant, si vous prévoyez de mettre en service une nouvelle "
+ "cellule ou si vous utilisez un ordinateur portable, vous ne souhaitez peut-"
+ "être pas le lancer au démarrage. Si vous préférez ne pas le lancer au "
+ "démarrage, utilisez la commande «&nbsp;/etc/init.d/openafs-client force-start&nbsp;» "
+ "pour le lancer quand vous en aurez besoin."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid "Look up AFS cells in DNS?"
+ msgstr "Faut-il chercher les cellules AFS dans le DNS&nbsp;?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid ""
+ "In order to contact an AFS cell, you need the IP addresses of the cell's "
+ "database servers.  Normally, this information is read from /etc/openafs/"
+ "CellServDB.  However, if Openafs cannot find a cell in that file, it can use "
+ "DNS to look for AFSDB records that contain the information."
+ msgstr ""
+ "Afin de contacter une cellule AFS, vous avez besoin des adresses IP de ses "
+ "serveurs de bases de données. Cette information est normalement extraite de /"
+ "etc/openafs/CellServDB. Cependant, si Openafs ne peut pas trouver de cellule "
+ "dans ce fichier, il peut utiliser le DNS pour rechercher des enregistrements "
+ "AFSDB qui fourniront cette information."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid "Encrypt authenticated traffic with AFS fileserver?"
+ msgstr "Faut-il chiffrer le trafic authentifié avec le serveur de fichiers AFS&nbsp;?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid ""
+ "AFS provides a weak form of encryption that can optionally be used between a "
+ "client and the fileservers.  While this encryption is weaker than DES and "
+ "thus is not sufficient for highly confidential data, it does provide some "
+ "confidentiality and is likely to make the job of a casual attacker "
+ "significantly more difficult."
+ msgstr ""
+ "AFS offre un mode de chiffrement faible qu'il est possible d'utiliser entre "
+ "un client et les serveurs de fichiers. Bien que ce chiffrement soit plus "
+ "faible que DES, et donc insuffisant pour des données hautement "
+ "confidentielles, il fournit une certaine forme de confidentialité et peut "
+ "rendre une attaque non préparée nettement plus difficile."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid "Dynamically generate the contents of /afs?"
+ msgstr "Faut-il gérer le contenu de /afs dynamiquement&nbsp;?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "/afs generally contains an entry for each cell that a client can talk to. "
+ "Traditionally, these entries were generated by servers in the client's home "
+ "cell.  However, OpenAFS clients can generate the contents of /afs "
+ "dynamically based on the contents of /etc/openafs/CellServDB and DNS."
+ msgstr ""
+ "Le répertoire /afs contient généralement une entrée par cellule accessible à "
+ "un client donné. Traditionnellement, ces entrées ont été créées par les "
+ "serveurs dans la cellule locale de chaque client. Cependant, OpenAFS peut "
+ "gérer dynamiquement le contenu de /afs en se servant de /etc/openafs/"
+ "CellServDB et du DNS."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "If you generate /afs dynamically, you may need to create /etc/openafs/"
+ "CellAlias to include aliases for common cells.  (The syntax of this file is "
+ "one line per alias, with the cell name, a space, and then the alias for that "
+ "cell.)"
+ msgstr ""
+ "Si vous créez /afs de manière dynamique, vous aurez peut-être à créer /etc/"
+ "openafs/CellAlias pour inclure les alias des cellules communes. Ce fichier comporte une ligne par alias, avec le nom de la cellule, un espace et l'alias utilisé pour la cellule."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid "Use fakestat to avoid hangs when listing /afs?"
+ msgstr "Utiliser fakestat pour éviter les erreurs à l'affichage du contenu de /afs&nbsp;?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid ""
+ "Because AFS is a global file space, operations on the /afs directory can "
+ "generate significant network traffic.  If some AFS cells are unavailable "
+ "then looking at /afs using ls or a graphical file browser may hang your "
+ "machine for minutes.  AFS has an option to simulate answers to these "
+ "operations locally to avoid these hangs.  You want this option under most "
+ "circumstances."
+ msgstr ""
+ "Comme AFS est un espace global de fichiers, les opérations sur /afs peuvent "
+ "générer un trafic réseau non négligeable. Si certaines cellules sont "
+ "indisponibles, l'affichage de /afs avec ls ou avec un gestionnaire de "
+ "fichiers graphique peut stopper votre machine pour quelques minutes. AFS "
+ "comporte une option permettant de simuler les réponses à ces requêtes pour "
+ "éviter ces plantages. Cette option est utile dans la plupart des cas."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid "What cell does this server serve files for?"
+ msgstr "Cellule pour laquelle ce serveur est un serveur de fichiers&nbsp;:"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid ""
+ "AFS fileservers belong to a cell.  They have the key for that cell's "
+ "Kerberos service and serve volumes into that cell.  Normally, this cell is "
+ "the same cell as the workstation's client belongs to."
+ msgstr ""
+ "Les serveurs de fichiers AFS appartiennent à une cellule. Ils possèdent la "
+ "clé pour le service Kerberos de cette cellule et y mettent à disposition des "
+ "volumes. Normalement, cette cellule est la même que celle à laquelle "
+ "appartient le client."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid "Upgrading will move files to new locations; continue?"
+ msgstr "Faut-il procéder au déplacement de fichiers requis pour la mise à jour&nbsp;?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid ""
+ "Between Openafs 1.1 and Openafs 1.2, several files moved.  In particular, "
+ "files in /etc/openafs/server-local have been distributed to other "
+ "locations.  The BosConfig file is now located in /etc/openafs and the other "
+ "files are located in /var/lib/openafs.  If you continue with this upgrade, "
+ "these files will be moved.  You should use the bos restart command to reload "
+ "your servers.  Any configuration changes made before you do so will be lost."
+ msgstr ""
+ "Entre les versions 1.1 et 1.2 d'OpenAFS, de nombreux fichiers ont été "
+ "déplacés. Les fichiers de /etc/openafs/server-local ont notamment été "
+ "répartis sur d'autres emplacements. Le fichier BosConfig est désormais placé "
+ "dans /etc/openafs et les autres fichiers sont dans /var/lib/openafs. Si vous "
+ "poursuivez la mise à jour, ces fichiers seront déplacés. Vous devez utiliser "
+ "la commande «&nbsp;bos restart&nbsp;» pour redémarrer vos serveurs. Toutes les "
+ "modifications de configuration que vous ferez avant d'avoir effectué ces "
+ "opérations seront perdues."
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid "OpenAFS file server probably does not work!"
+ msgstr "Le serveur de fichiers OpenAFS ne fonctionne probablement pas"
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid ""
+ "You are running the OpenAFS file server package on an alpha.  This probably "
+ "doesn't work; the DES code is flaky on the alpha, along with the threaded "
+ "file server.  Likely, the fileserver will simply fail to start, but if it "
+ "does load, data corruption may result.  You have been warned."
+ msgstr ""
+ "Vous utilisez le paquet du serveur de fichier OpenAFS sur une plateforme "
+ "alpha. Cela ne fonctionne probablement pas&nbsp;; le code DES est défectueux sur "
+ "ces plateformes de même que le serveur de fichiers à processus légers. Il "
+ "est probable que le serveur refusera tout simplement de démarrer. Cependant, "
+ "s'il démarre quand même, des corruptions de données peuvent avoir lieu."
+ 
Index: openafs/src/packaging/Debian/po/pt_BR.po
diff -c /dev/null openafs/src/packaging/Debian/po/pt_BR.po:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/po/pt_BR.po	Thu Mar 23 15:19:16 2006
***************
*** 0 ****
--- 1,293 ----
+ #
+ #    Translators, if you are not familiar with the PO format, gettext
+ #    documentation is worth reading, especially sections dedicated to
+ #    this format, e.g. by running:
+ #         info -n '(gettext)PO Files'
+ #         info -n '(gettext)Header Entry'
+ #
+ #    Some information specific to po-debconf are available at
+ #            /usr/share/doc/po-debconf/README-trans
+ #         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+ #
+ #    Developers do not need to manually edit POT or PO files.
+ #
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: openafs\n"
+ "Report-Msgid-Bugs-To: debian-l10n-portuguese@lists.debian.org\n"
+ "POT-Creation-Date: 2005-08-18 12:47-0700\n"
+ "PO-Revision-Date: 2005-08-26 18:53-0300\n"
+ "Last-Translator: André Luís Lopes &lt;andrelop@debian.org&gt;\n"
+ "Language-Team: Debian-BR Project &lt;debian-l10n-portuguese@lists.debian.org&gt;\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=ISO-8859-1\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid "What hosts are DB servers for your home cell?"
+ msgstr "Quais hosts são servidor DB para sua célula home ?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid ""
+ "AFS uses the file /etc/openafs/CellServDB to hold the list of servers that "
+ "should be contacted to find parts of a cell.  The cell you claim this "
+ "workstation belongs to is not in that file.  Enter the host names of the "
+ "database servers separated by spaces. IMPORTANT: If you are creating a new "
+ "cell and this machine is to be a database server in that cell, only enter "
+ "this machine's name; add the other servers later after they are functioning. "
+ "Also, do not enable the AFS client to start at boot on this server until the "
+ "cell is configured.  When you are ready you can edit /etc/openafs/afs.conf."
+ "client to enable the client."
+ msgstr ""
+ "O AFS usa o arquivo /etc/openafs/CellServDB para armazenar a lista de "
+ "servidores que deverão ser contactados para se encontrar partes de uma "
+ "célula. A célula que você diz que essa estação de trabalho pertence não está "
+ "nesse arquivo. Informe os nomes de hosts dos servidore de base de dados "
+ "separados por espaços. IMPORTANTE : Caso você esteja criando uma nova célula "
+ "e esta máquina será um servidor de base de dados na célula, somente informe "
+ "o nome desta máquina. Adicione os outros servidores posteriormente depois "
+ "que os mesmos estejam funcionando. Adicionalmente, não habilite o cliente "
+ "AFS para inicialização em tempo de inicialização neste servidor até que a "
+ "célula esteja configurada. Quando você estiver terminado você poderá editar "
+ "o arquivo /etc/openafs/afs.conf.client para habilitar este cliente."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid "What AFS cell does this workstation belong to?"
+ msgstr "A qual célula AFS esta estação de trabalho pertence ?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid ""
+ "AFS filespace is organized into cells or administrative domains. Each "
+ "workstation belongs to one cell.  Usually the cell is the DNS domain name of "
+ "the site."
+ msgstr ""
+ "O espaço de arquivo AFS é organizado em células ou domínios administrativos. "
+ "Cada estação de trabalho pertence a uma célula. Normalmente a célula é o "
+ "nome de domínio DNS do site."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid "How large is your AFS cache (kB)?"
+ msgstr "Qual o tamanho de seu cache AFS (KB) ?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid ""
+ "AFS uses an area of the disk to cache remote files for faster access.  This "
+ "cache will be mounted on /var/cache/openafs.  It is important that the cache "
+ "not overfill the partition it is located on.  Often, people find it useful "
+ "to dedicate a partition to their AFS cache."
+ msgstr ""
+ "O AFS usa uma àrea do disco para fazer cache de arquivos remotos para acesso "
+ "mais rápido. Esse cache será montando em /var/cache/openafs. É importante "
+ "que o cache não ocupe toda a partrição na qual está localizado. Geralmente, "
+ "os usuários AFS acham útil dedicar uma partição para seus caches AFS."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid "Run Openafs client now and at boot?"
+ msgstr "Executar o cliente OpenAFS agora e em tempo de inicialização ?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid ""
+ "Should the Openafs filesystem be started and mounted at boot? Normally, most "
+ "users who install the openafs-client package expect to run it at boot.  "
+ "However, if you are planning on setting up a new cell or are on a laptop, "
+ "you may not want it started at boot time.  If you choose not to start AFS at "
+ "boot, run /etc/init.d/openafs-client force-start to start the client when "
+ "you wish to run it."
+ msgstr ""
+ "O sistema de arquivos OpenAFS deverá ser iniciado e montando em tempo de "
+ "inicialização ? Normalmente, a maioria dos usuários que instalam o pacote "
+ "openafs-client esperam executá-lo em tempo de inicialização. Porém, caso "
+ "você esteja planejando configurar uma nova célula ou esteja em um laptop, "
+ "você pode não desejar iniciar o OpenAFS em tempo de inicialização. Caso você "
+ "opte por não iniciar o AFS em tempo de inicialização, execute "
+ "/etc/init.d/openafs-cliente force-start para iniciar o cliente quando "
+ "desejar executá-lo."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid "Look up AFS cells in DNS?"
+ msgstr "Procurar células AFS no DNS ?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid ""
+ "In order to contact an AFS cell, you need the IP addresses of the cell's "
+ "database servers.  Normally, this information is read from /etc/openafs/"
+ "CellServDB.  However, if Openafs cannot find a cell in that file, it can use "
+ "DNS to look for AFSDB records that contain the information."
+ msgstr ""
+ "Para poder contactar uma célula AFS, você precisa dos endereços IP dos "
+ "servidores de base de dados da célula. Normalmente, esta informação é lida "
+ "de /etc/openafs/CellServDB. Porém, caso o OpenAFS não possa encontrar uma "
+ "célula nesse arquivo, o DNS poderá ser usado para pesquisar registros AFSDB "
+ "que contenham a informação."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid "Encrypt authenticated traffic with AFS fileserver?"
+ msgstr "Encriptar o tráfego autenticado com o servidor de arquivos AFS ?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid ""
+ "AFS provides a weak form of encryption that can optionally be used between a "
+ "client and the fileservers.  While this encryption is weaker than DES and "
+ "thus is not sufficient for highly confidential data, it does provide some "
+ "confidentiality and is likely to make the job of a casual attacker "
+ "significantly more difficult."
+ msgstr ""
+ "O AFS fornece uma forma fraca de encriptação que pode ser opcionalmente "
+ "usada entre o cliente e os servidor de arquivos. Enquanto esta encriptação é "
+ "mais fraca do que DES e portanto não é suficiente para dados altamente "
+ "confidenciais, essa encriptação fornece alguma confidencialidade e "
+ "provavelmente torna o trabalho de um atacante casual mais difícil."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid "Dynamically generate the contents of /afs?"
+ msgstr "Gerar dinamicamente o conteúdo de /afs ?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "/afs generally contains an entry for each cell that a client can talk to. "
+ "Traditionally, these entries were generated by servers in the client's home "
+ "cell.  However, OpenAFS clients can generate the contents of /afs "
+ "dynamically based on the contents of /etc/openafs/CellServDB and DNS."
+ msgstr ""
+ "O /afs geralmente contém uma entrada para cada célula com a qual o cliente "
+ "pode conversar. Tradicionalmente, essas entradas eram geradas por servidores "
+ "no célula home do cliente. Porém, clientes OpenAFS podem gerar o conteúdo "
+ "de /afs dinamicamente baseando-se no conteúdo de /etc/openafs/CellServDB e "
+ "do DNS."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "If you generate /afs dynamically, you may need to create /etc/openafs/"
+ "CellAlias to include aliases for common cells.  (The syntax of this file is "
+ "one line per alias, with the cell name, a space, and then the alias for that "
+ "cell.)"
+ msgstr ""
+ "Caso você gere o /afs dinamicamente, você pode precisar criar o /etc/openafs/"
+ "CellAlias para incluir apelidos (aliases) para células comuns. (A "
+ "sintaxe desse arquivo é uma linha por apelido, com o nome da célula, "
+ "um espaço e depois o apelido para a célula.)"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid "Use fakestat to avoid hangs when listing /afs?"
+ msgstr "Usar fakestat para evitar travadas na listagem do /afs ?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid ""
+ "Because AFS is a global file space, operations on the /afs directory can "
+ "generate significant network traffic.  If some AFS cells are unavailable "
+ "then looking at /afs using ls or a graphical file browser may hang your "
+ "machine for minutes.  AFS has an option to simulate answers to these "
+ "operations locally to avoid these hangs.  You want this option under most "
+ "circumstances."
+ msgstr ""
+ "Devido ao AFS ser um espaço de arquivos global, operações no diretório /afs "
+ "podem gerar um tráfego de rede significativo. Caso algumas células AFS não "
+ "estejam disponíveis, pesquisar o /afs usando o comando \"ls\" ou um "
+ "gerenciador de arquivos gráfico pode travar sua máquina por alguns minutos. "
+ "O AFS possui uma opção para simular respostas para essas operações "
+ "localmente para evitar essas travadas. Você irá desejar usar esta opção na "
+ "maioria dos casos."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid "What cell does this server serve files for?"
+ msgstr "Para qual célula este servidor serve arquivos ?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid ""
+ "AFS fileservers belong to a cell.  They have the key for that cell's "
+ "Kerberos service and serve volumes into that cell.  Normally, this cell is "
+ "the same cell as the workstation's client belongs to."
+ msgstr ""
+ "Servidor de arquivos AFS pertencem a uma célula. Eles possuem uma chave para "
+ "cada serviço Kerberos da célula e servem volumes dentro da célula. "
+ "Normalmente, essa célula é a mesma célula da qual a estação de trabalho faz "
+ "parte."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid "Upgrading will move files to new locations; continue?"
+ msgstr "Atualizar irá mover arquivo para novos locais. Continuar ?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid ""
+ "Between Openafs 1.1 and Openafs 1.2, several files moved.  In particular, "
+ "files in /etc/openafs/server-local have been distributed to other "
+ "locations.  The BosConfig file is now located in /etc/openafs and the other "
+ "files are located in /var/lib/openafs.  If you continue with this upgrade, "
+ "these files will be moved.  You should use the bos restart command to reload "
+ "your servers.  Any configuration changes made before you do so will be lost."
+ msgstr ""
+ "Entre as versões do OpenAFS 1.1 e do OpenAFS 1.2, diversos arquivos foram "
+ "movidos. Em particular, aruivos em /etc/openafs/server-local foram "
+ "distribuídos para outros locais. O arquivo BosConfig está agora localizado "
+ "em /etc/openafs e os outros arquivos estão localizados em /var/lib/openafs. "
+ "Caso você continue com esta atualização, esses arquivos serão movidos. Você "
+ "deverá usar o comando \"bos restart\" para recarregar seus servidores. "
+ "Quaisquer mudanças em configurações feitas antes que você tenha feito isso "
+ "serão perdidas."
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid "OpenAFS file server probably does not work!"
+ msgstr "Servidor de Arquivos OpenAFS provavelmente não funciona !"
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid ""
+ "You are running the OpenAFS file server package on an alpha.  This probably "
+ "doesn't work; the DES code is flaky on the alpha, along with the threaded "
+ "file server.  Likely, the fileserver will simply fail to start, but if it "
+ "does load, data corruption may result.  You have been warned."
+ msgstr ""
+ "Você está executando o pacote do servidor de arquivos OpenAFS em uma máquina "
+ "Alpha. Isso provavelmente não funcionará. O código DES é em conjunto com o "
+ "servidor de arquivos com suporte a threads é problemático em máquinas Alpha. "
+ "Provavelmente, o servidor de arquivos irá simplesmente falhar ao iniciar. "
+ "Caso consiga ser iniciado, poderá causar corrupção de dados. Você foi "
+ "avisado."
+ 
+ #~ msgid "50000"
+ #~ msgstr "50000"
Index: openafs/src/packaging/Debian/po/vi.po
diff -c /dev/null openafs/src/packaging/Debian/po/vi.po:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/Debian/po/vi.po	Thu Mar 23 15:19:16 2006
***************
*** 0 ****
--- 1,278 ----
+ # Vietnamese translation for openafs.
+ # Copyright Â© 2005 Free Software Foundation, Inc.
+ # Clytie Siddall &lt;clytie@riverland.net.au&gt;, 2005.
+ # 
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: openafs 1.4rc1-1\n"
+ "Report-Msgid-Bugs-To: \n"
+ "POT-Creation-Date: 2005-08-18 12:47-0700\n"
+ "PO-Revision-Date: 2005-08-19 16:26+0930\n"
+ "Last-Translator: Clytie Siddall &lt;clytie@riverland.net.au&gt;\n"
+ "Language-Team: Vietnamese &lt;gnomevi-list@lists.sourceforge.net&gt;\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=utf-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ "Plural-Forms: nplurals=1; plural=0\n"
+ "X-Generator: LocFactoryEditor 1.2.2\n"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid "What hosts are DB servers for your home cell?"
+ msgstr "MÃ¡y nÃ&nbsp;o cháº¡y trÃ¬nh phá»¥c vá»¥ cÆ¡ sá»Ÿ dá»¯ liá»‡u cho Ã´ chÃ­nh báº¡n?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:3
+ msgid ""
+ "AFS uses the file /etc/openafs/CellServDB to hold the list of servers that "
+ "should be contacted to find parts of a cell.  The cell you claim this "
+ "workstation belongs to is not in that file.  Enter the host names of the "
+ "database servers separated by spaces. IMPORTANT: If you are creating a new "
+ "cell and this machine is to be a database server in that cell, only enter "
+ "this machine's name; add the other servers later after they are functioning. "
+ "Also, do not enable the AFS client to start at boot on this server until the "
+ "cell is configured.  When you are ready you can edit /etc/openafs/afs.conf."
+ "client to enable the client."
+ msgstr ""
+ "AFS dÃ¹ng táº­p tin Â« /etc/openafs/CellServDB Â» Ä‘á»ƒ chá»©a danh sÃ¡ch cÃ¡c mÃ¡y phá»¥c vá»¥ "
+ "nÃªn Ä‘Æ°á»£c liÃªn há»‡ Ä‘á»ƒ tÃ¬m pháº§n Ã´. Báº¡n Ä‘Ã£ tuyÃªn bá»‘ mÃ¡y tráº¡m nÃ&nbsp;y thuá»™c má»™t Ã´ "
+ "khÃ´ng pháº£i trong táº­p tin áº¥y. HÃ£y nháº­p tÃªn mÃ¡y cá»§a nhá»¯ng mÃ¡y phá»¥c vá»¥ cÆ¡ sá»Ÿ dá»¯ "
+ "liá»‡u, Ä‘á»‹nh giá»›i báº±ng dáº¥u cÃ¡ch. QUAN TRá»ŒNG: náº¿u báº¡n Ä‘ang táº¡o má»™t Ã´ má»›i, vÃ&nbsp; "
+ "mÃ¡y nÃ&nbsp;y sáº½ lÃ&nbsp; má»™t mÃ¡y phá»¥c vá»¥ cÆ¡ sá»Ÿ dá»¯ liá»‡u trong Ã´ áº¥y, thÃ¬ báº¡n hÃ£y nháº­p chá»‰ "
+ "tÃªn mÃ¡y nÃ&nbsp;y thÃ´i. HÃ£y thÃªm nhá»¯ng mÃ¡y phá»¥c vá»¥ khÃ¡c láº§n sau, sau khi chÃºng "
+ "hoáº¡t Ä‘á»™ng. HÆ¡n ná»¯a, cÃ³ thá»ƒ hiá»‡u lá»±c trÃ¬nh khÃ¡ch AFS khá»Ÿi cháº¡y khi khá»Ÿi Ä‘á»™ng "
+ "mÃ¡y, chá»‰ sau khi cáº¥u hÃ¬nh Ã´ áº¥y. Khi báº¡n sáºµn sÃ&nbsp;ng thÃ¬ cÃ³ thá»ƒ hiá»‡u chá»‰nh táº­p "
+ "tin Â« /etc/openafs/afs.conf.client Â» Ä‘á»ƒ hiá»‡u lá»±c trÃ¬nh khÃ¡ch áº¥y."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid "What AFS cell does this workstation belong to?"
+ msgstr "MÃ¡y tráº¡m nÃ&nbsp;y thuá»™c Ã´ AFS nÃ&nbsp;o?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:16
+ msgid ""
+ "AFS filespace is organized into cells or administrative domains. Each "
+ "workstation belongs to one cell.  Usually the cell is the DNS domain name of "
+ "the site."
+ msgstr ""
+ "Khoáº£ng cÃ¡ch táº­p tin loáº¡i AFS Ä‘Æ°á»£c tá»• chá»©c ra nhiá»u Ã´ hay miá»n quáº£n lÃ½. Má»—i "
+ "mÃ¡y tráº¡m thuá»™c má»™t Ã´ riÃªng láº». ThÆ°á»ng Ã´ áº¥y lÃ&nbsp; tÃªn miá»n DNS cá»§a nÆ¡i Máº¡ng áº¥y."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid "How large is your AFS cache (kB)?"
+ msgstr "Báº¡n cÃ³ bá»™ nhá»› táº¡m AFS lá»›n bao nhiÃªu (theo kB)?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-client.templates:24
+ msgid ""
+ "AFS uses an area of the disk to cache remote files for faster access.  This "
+ "cache will be mounted on /var/cache/openafs.  It is important that the cache "
+ "not overfill the partition it is located on.  Often, people find it useful "
+ "to dedicate a partition to their AFS cache."
+ msgstr ""
+ "AFS dÃ¹ng má»™t vÃ¹ng trÃªn Ä‘Ä©a Ä‘á»ƒ lÆ°u táº¡m táº­p tin tá»« xa, mÃ&nbsp; cho phÃ©p truy cáº­p "
+ "nhanh hÆ¡n. Bá»™ nhá»› táº¡m nÃ&nbsp;y sáº½ Ä‘Æ°á»£c gáº¯n vÃ&nbsp;o Â« /var/cache/openafs Â». Quan trá»ng "
+ "lÃ&nbsp; bá»™ nhá»› táº¡m áº¥y khÃ´ng vÆ°á»£t quÃ¡ phÃ¢n vÃ¹ng á»Ÿ. ThÆ°á»ng cÃ³ Ã­ch khi dÃ¹ng má»™t phÃ¢n "
+ "vÃ¹ng chá»‰ cho bá»™ nhá»› táº¡m AFS thÃ´i."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid "Run Openafs client now and at boot?"
+ msgstr "Cháº¡y trÃ¬nh khÃ¡ch Openafs ngay bÃ¢y giá» vÃ&nbsp; cÅ©ng khi khá»Ÿi Ä‘á»™ng mÃ¡y khÃ´ng?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:34
+ msgid ""
+ "Should the Openafs filesystem be started and mounted at boot? Normally, most "
+ "users who install the openafs-client package expect to run it at boot.  "
+ "However, if you are planning on setting up a new cell or are on a laptop, "
+ "you may not want it started at boot time.  If you choose not to start AFS at "
+ "boot, run /etc/init.d/openafs-client force-start to start the client when "
+ "you wish to run it."
+ msgstr ""
+ "CÃ³ nÃªn khá»Ÿi cháº¡y vÃ&nbsp; gáº¯n há»‡ thá»‘ng táº­p tin Openafs khi khá»Ÿi Ä‘á»™ng mÃ¡y khÃ´ng? "
+ "BÃ¬nh thÆ°á»ng, pháº§n lá»›n ngÆ°á»i dÃ¹ng cÃ&nbsp;i Ä‘áº·t gÃ³i Â« openafs-client Â» thÃ¬ Ä‘á»‹nh "
+ "cháº¡y nÃ³ khi khá»Ÿi Ä‘á»™ng mÃ¡y. Tuy nhiÃªn, náº¿u báº¡n Ä‘á»‹nh thiáº¿t láº­p má»™t Ã´ má»›i, hoáº·c "
+ "cÃ³ dÃ¹ng má»™t mÃ¡y tÃ­nh xÃ¡ch tay, trong trÆ°á»ng há»£p áº¥y cÃ³ láº½ báº¡n khÃ´ng muá»‘n há»‡ "
+ "thá»‘ng táº­p tin áº¥y khá»Ÿi cháº¡y khi khá»Ÿi Ä‘á»™ng mÃ¡y. Náº¿u báº¡n chá»n khÃ´ng khá»Ÿi cháº¡y "
+ "AFS khi khá»Ÿi Ä‘á»™ng mÃ¡y thÃ¬ hÃ£y cháº¡y lá»‡nh Â« /etc/init.d/openafs-client force-"
+ "start Â» (buá»™c khá»Ÿi cháº¡y trÃ¬nh khÃ¡ch AFS) Ä‘á»ƒ khá»Ÿi cháº¡y trÃ¬nh khÃ¡ch khi mÃ&nbsp; báº¡n "
+ "muá»‘n cháº¡y nÃ³."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid "Look up AFS cells in DNS?"
+ msgstr "Tra cá»©u Ã´ AFS trong DNS khÃ´ng?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:45
+ msgid ""
+ "In order to contact an AFS cell, you need the IP addresses of the cell's "
+ "database servers.  Normally, this information is read from /etc/openafs/"
+ "CellServDB.  However, if Openafs cannot find a cell in that file, it can use "
+ "DNS to look for AFSDB records that contain the information."
+ msgstr ""
+ "Äá»ƒ liÃªn há»‡ má»™t Ã´ AFS, báº¡n cáº§n cÃ³ Ä‘á»‹a chá»‰ IP cá»§a má»i mÃ¡y phá»¥c vá»¥ cÆ¡ sá»Ÿ dá»¯ "
+ "liá»‡u cá»§a nÃ³. BÃ¬nh thÆ°á»ng, thÃ´ng tin nÃ&nbsp;y Ä‘Æ°á»£c Ä‘á»c tá»« táº­p tin Â« /etc/openafs/"
+ "CellServDB Â». Tuy nhiÃªn, náº¿u trÃ¬nh Openafs khÃ´ng tÃ¬m tháº¥y má»™t Ã´ nÃ&nbsp;o Ä‘Ã³ trong "
+ "táº­p tin áº¥y thÃ¬ nÃ³ cÃ³ thá»ƒ dÃ¹ng DNS (há»‡ thá»‘ng tÃªn miá»n) Ä‘á»ƒ tÃ¬m má»¥c ghi AFSDB "
+ "chá»©a thÃ´ng tin áº¥y."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid "Encrypt authenticated traffic with AFS fileserver?"
+ msgstr ""
+ "Máº­t mÃ£ hÃ³a cÃ¡c dá»¯ liá»‡u xÃ¡c thá»±c truyá»n vá»›i trÃ¬nh phá»¥c vá»¥ táº­p tin AFS khÃ´ng?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:55
+ msgid ""
+ "AFS provides a weak form of encryption that can optionally be used between a "
+ "client and the fileservers.  While this encryption is weaker than DES and "
+ "thus is not sufficient for highly confidential data, it does provide some "
+ "confidentiality and is likely to make the job of a casual attacker "
+ "significantly more difficult."
+ msgstr ""
+ "AFS cung cáº¥p má»™t cÃ¡ch máº­t mÃ£ yáº¿u mÃ&nbsp; tÃ¹y chá»n cÃ³ thá»ƒ Ä‘Æ°á»£c dÃ¹ng giá»¯a má»™t trÃ¬nh "
+ "khÃ¡ch nÃ&nbsp;o Ä‘Ã³ vÃ&nbsp; nhá»¯ng trÃ¬nh phá»¥c vá»¥ táº­p tin khÃ¡c. DÃ¹ cÃ¡ch máº·t mÃ£ nÃ&nbsp;y yáº¿u hÆ¡n "
+ "DES, vÃ¬ váº­y khÃ´ng Ä‘á»§ cho dá»¯ liá»‡u quan trá»ng, nÃ³ cÃ³ cung cáº¥p má»™t má»©c Ä‘á»™ riÃªng "
+ "tÆ°, thÃ¬ sáº½ lÃ&nbsp;m cho ngÆ°á»i táº¥n cÃ´ng gáº·p khÃ³ khÄƒn má»™t pháº§n."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid "Dynamically generate the contents of /afs?"
+ msgstr "Táº¡o ra ná»™i dung Â« /afs Â» má»™t cÃ¡ch Ä‘á»™ng khÃ´ng?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "/afs generally contains an entry for each cell that a client can talk to. "
+ "Traditionally, these entries were generated by servers in the client's home "
+ "cell.  However, OpenAFS clients can generate the contents of /afs "
+ "dynamically based on the contents of /etc/openafs/CellServDB and DNS."
+ msgstr ""
+ "ThÆ° má»¥c Â« /afs Â» thÆ°á»ng chá»©a má»™t má»¥c ghi cho má»—i Ã´ mÃ&nbsp; trÃ¬nh khÃ¡ch cÃ³ thá»ƒ liÃªn "
+ "há»‡. TrÆ°á»›c nÃ&nbsp;y, trÃ¬nh phá»¥c vá»¥ trong Ã´ chÃ­nh cá»§a trÃ¬nh khÃ¡c Ä‘Ã£ táº¡o ra má»¥c ghi "
+ "nÃ&nbsp;y. Tuy nhiÃªn, trÃ¬nh khÃ¡ch loáº¡i OpenAFS cÃ³ thá»ƒ táº¡o ra ná»™i dung Â« /afs Â» má»™t "
+ "cÃ¡ch Ä‘á»™ng, Ä‘á»±a vÃ&nbsp;o ná»™i dung Â« /etc/openafs/CellServDB Â» vÃ&nbsp; vÃ&nbsp;o DNS."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:65
+ msgid ""
+ "If you generate /afs dynamically, you may need to create /etc/openafs/"
+ "CellAlias to include aliases for common cells.  (The syntax of this file is "
+ "one line per alias, with the cell name, a space, and then the alias for that "
+ "cell.)"
+ msgstr ""
+ "Náº¿u báº¡n chá»n táº¡o ra Â« /afs Â» má»™t cÃ¡ch Ä‘á»™ng, cÃ³ láº½ báº¡n sáº½ cáº§n pháº£i táº¡o Â« etc/"
+ "openafs/CellAlias Â» (bÃ­ danh Ã´) Ä‘á»ƒ gá»“m bÃ­ danh cho cÃ¡c Ã´ chung. (CÃº phÃ¡p cá»§a táº­p tin nÃ&nbsp;y lÃ&nbsp; má»™t dÃ²ng cho má»—i bÃ­ danh, mÃ&nbsp; chá»©a tÃªn Ã´, rá»“i má»™t dáº¥u cÃ¡ch, rá»“i bÃ­ danh cho Ã´ Ä‘Ã³.)"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid "Use fakestat to avoid hangs when listing /afs?"
+ msgstr ""
+ "DÃ¹ng Â« fakestat Â» (thá»‘ng kÃª giáº£) Ä‘á»ƒ trÃ¡nh há»‡ thá»‘ng treo cá»©ng khi liá»‡t kÃª Â« /"
+ "afs Â» khÃ´ng?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-client.templates:79
+ msgid ""
+ "Because AFS is a global file space, operations on the /afs directory can "
+ "generate significant network traffic.  If some AFS cells are unavailable "
+ "then looking at /afs using ls or a graphical file browser may hang your "
+ "machine for minutes.  AFS has an option to simulate answers to these "
+ "operations locally to avoid these hangs.  You want this option under most "
+ "circumstances."
+ msgstr ""
+ "VÃ¬ AFS lÃ&nbsp; má»™t khoáº£ng cÃ¡ch toÃ&nbsp;n cá»¥c, thao tÃ¡c trÃªn thÆ° má»¥c Â« /afs Â» cÃ³ thá»ƒ táº¡o "
+ "ra nhiá»u táº£i cho máº¡ng. Náº¿u má»™t sá»‘ Ã´ AFS khÃ´ng sáºµn sÃ&nbsp;ng thÃ¬ viá»‡c xem Â« /afs Â» "
+ "dÃ¹ng lá»‡nh Â« ls Â» (liá»‡t kÃª) hoáº·c dÃ¹ng má»™t trÃ¬nh Ä‘á»“ há»a duyá»‡t táº­p tin thÃ¬ cÃ³ thá»ƒ "
+ "treo cá»©ng mÃ¡y báº¡n trong vÃ²ng nhiá»u phÃºt. AFS tÃ¹y chá»n cÃ³ thá»ƒ mÃ´ phá»ng tráº£ "
+ "lá»i cho thao tÃ¡c loáº¡i nÃ&nbsp;y má»™t cÃ¡ch Ä‘á»‹a phÆ°Æ¡ng, Ä‘á»ƒ trÃ¡nh treo cá»©ng há»‡ thá»‘ng "
+ "nhÆ° tháº¿. Äá»‡ nghi báº¡n sá»­ dá»¥ng tÃ¹y chá»n nÃ&nbsp;y: nÃ³ cáº§n thiáº¿t trong pháº§n lá»›n "
+ "trÆ°á»ng há»£p."
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid "What cell does this server serve files for?"
+ msgstr "TrÃ¬nh phá»¥c vá»¥ nÃ&nbsp;y phá»¥c vá»¥ táº­p tin cho Ã´ nÃ&nbsp;o?"
+ 
+ #. Type: string
+ #. Description
+ #: ../openafs-fileserver.templates:3
+ msgid ""
+ "AFS fileservers belong to a cell.  They have the key for that cell's "
+ "Kerberos service and serve volumes into that cell.  Normally, this cell is "
+ "the same cell as the workstation's client belongs to."
+ msgstr ""
+ "Má»i trÃ¬nh phá»¥c vá»¥ táº­p tin AFS thuá»™c má»™t Ã´ nÃ&nbsp;o Ä‘Ã³. TrÃ¬nh áº¥y cÃ³ khÃ³a cá»§a dá»‹ch "
+ "vá»¥ Kerberos cá»§a Ã´ nÃ&nbsp;y, vÃ&nbsp; phá»¥c vá»¥ khá»‘i Ä‘Ä©a vÃ&nbsp;o Ã´ nÃ&nbsp;y. BÃ¬nh thÆ°á»ng, Ã´ nÃ&nbsp;y lÃ&nbsp; "
+ "cÃ¹ng má»™t Ã´ vá»›i Ã´ sá»Ÿ há»¯u trÃ¬nh khÃ¡ch cá»§a mÃ¡y tráº¡m nÃ&nbsp;y."
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid "Upgrading will move files to new locations; continue?"
+ msgstr ""
+ "NÃ¢ng cáº¥p sáº½ di chuyá»ƒn táº­p tin sang vá»‹ trÃ­ má»›i: báº¡n cÃ³ muá»‘n tiáº¿p tá»¥c khÃ´ng?"
+ 
+ #. Type: boolean
+ #. Description
+ #: ../openafs-fileserver.templates:11
+ msgid ""
+ "Between Openafs 1.1 and Openafs 1.2, several files moved.  In particular, "
+ "files in /etc/openafs/server-local have been distributed to other "
+ "locations.  The BosConfig file is now located in /etc/openafs and the other "
+ "files are located in /var/lib/openafs.  If you continue with this upgrade, "
+ "these files will be moved.  You should use the bos restart command to reload "
+ "your servers.  Any configuration changes made before you do so will be lost."
+ msgstr ""
+ "Giá»¯a Openafs phiÃªn báº£n 1.1 vÃ&nbsp; 1.2, vÃ&nbsp;i táº­p tin Ä‘Ã£ Ä‘Æ°á»£c di chuyá»ƒn. Äáº·c biá»‡t, "
+ "nhá»¯ng táº­p tin trong Â« /etc/openafs/server-local Â» (trÃ¬nh phá»¥c vá»¥ Ä‘á»‹a phÆ°Æ¡ng) "
+ "Ä‘Ã£ Ä‘Æ°á»£c chia ra nhiá»u vá»‹ trÃ­ khÃ¡c. Táº­p tin Â« BosConfig Â» lÃºc nÃ&nbsp;y trong Â« /etc/"
+ "openafs Â», vÃ&nbsp; nhá»¯ng táº­p tin khÃ¡c cÃ³ trong Â« /var/lib/openafs Â». Náº¿u báº¡n chá»n "
+ "tiáº¿p tá»¥c nÃ¢ng cáº¥p, cÃ¡c táº­p tin áº¥y sáº½ Ä‘Æ°á»£c di chuyá»ƒn nhÆ° tháº¿. Báº¡n hÃ£y sá»­ dá»¥ng "
+ "lá»‡nh Â« bos restart Â» (khá»Ÿi cháº¡y láº¡i) Ä‘á»ƒ khá»Ÿi cháº¡y láº¡i cÃ¡c trÃ¬nh phá»¥c vá»¥ cá»§a "
+ "báº¡n. Má»i thay Ä‘á»•i cáº¥u hÃ¬nh Ä‘Æ°á»£c táº¡o trÆ°á»›c khi báº¡n khá»Ÿi cháº¡y láº¡i thÃ¬ sáº½ bá»‹ "
+ "máº¥t."
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid "OpenAFS file server probably does not work!"
+ msgstr "Ráº¥t cÃ³ thá»ƒ lÃ&nbsp; trÃ¬nh phá»¥c vá»¥ táº­p tin OpenAFS khÃ´ng hoáº¡t Ä‘á»™ng."
+ 
+ #. Type: note
+ #. Description
+ #: ../openafs-fileserver.templates:22
+ msgid ""
+ "You are running the OpenAFS file server package on an alpha.  This probably "
+ "doesn't work; the DES code is flaky on the alpha, along with the threaded "
+ "file server.  Likely, the fileserver will simply fail to start, but if it "
+ "does load, data corruption may result.  You have been warned."
+ msgstr ""
+ "Báº¡n cÃ³ cháº¡y gÃ³i tin trÃ¬nh phá»¥c vá»¥ táº­p tin OpenAFS trÃªn má»™t anfa. Ráº¥t cÃ³ thá»ƒ "
+ "lÃ&nbsp; nÃ³ khÃ´ng hoáº¡t Ä‘á»™ng vÃ¬ mÃ£ DES bá»‹ lá»—i trÃªn anfa, cÅ©ng vá»›i trÃ¬nh phá»¥c vá»¥ táº­p "
+ "tin theo máº¡ch. Ráº¥t cÃ³ thá»ƒ lÃ&nbsp; trÃ¬nh phá»¥c vá»¥ táº­p tin sáº½ khÃ´ng khá»Ÿi cháº¡y, nhÆ°ng "
+ "mÃ&nbsp; náº¿u nÃ³ cÃ³ pháº£i khá»Ÿi cháº¡y thÃ¬ dá»¯ liá»‡u cÃ³ thá»ƒ bá»‹ há»ng. Báº¡n Ä‘Ã£ nháº­n má»™t cáº£nh "
+ "bÃ¡o rá»“i."
Index: openafs/src/packaging/MacOS/Makefile
diff -c openafs/src/packaging/MacOS/Makefile:1.2 openafs/src/packaging/MacOS/Makefile:1.3
*** openafs/src/packaging/MacOS/Makefile:1.2	Fri Oct 24 02:26:13 2003
--- openafs/src/packaging/MacOS/Makefile	Thu Mar  9 01:34:46 2006
***************
*** 19,33 ****
  # 
  # @APPLE_LICENSE_HEADER_END@
  
! AFSINCLUDE = /Library/OpenAFS/Tools/include
! CFLAGS = -O -I$(AFSINCLUDE)
  LIBS = -framework Foundation
  ALL = afssettings
  
  all: $(ALL)
  
! afssettings : afssettings.m
  	cc $(CFLAGS) -o $@ $^ $(LIBS)
  
  clean:
! 	@rm -f *.o $(ALL)
--- 19,37 ----
  # 
  # @APPLE_LICENSE_HEADER_END@
  
! # We assume the either we are in src/packaging/MacOS (so ../.. should work
! # with #include &lt;afs/sysctl.h&gt;, or we are in a directory where configure
! # was run, so the afs/sysctl.h should be in the include subdirectory
! AFSINCLUDE = -I../.. -Iinclude
! CFLAGS = -Os $(AFSINCLUDE) $(ARCHFLAGS)
  LIBS = -framework Foundation
  ALL = afssettings
+ DIR = $(shell dirname $(MAKEFILE_LIST))
  
  all: $(ALL)
  
! afssettings : $(DIR)/afssettings.m
  	cc $(CFLAGS) -o $@ $^ $(LIBS)
  
  clean:
! 	@rm -f $(ALL)
Index: openafs/src/packaging/MacOS/OpenAFS.post_install
diff -c openafs/src/packaging/MacOS/OpenAFS.post_install:1.4 openafs/src/packaging/MacOS/OpenAFS.post_install:1.7
*** openafs/src/packaging/MacOS/OpenAFS.post_install:1.4	Sun Apr  3 15:13:11 2005
--- openafs/src/packaging/MacOS/OpenAFS.post_install	Wed Apr  5 09:45:58 2006
***************
*** 63,69 ****
    fi
  fi
  
! if [ -z "$done" ]; then
    # there are local changes to be merged
    if [ -f CellServDB -a -f CellServDB.master.last ]; then
      echo Merging CellServDB entries....
--- 63,69 ----
    fi
  fi
  
! if [ -z "$done" -a  -f CellServDB ]; then
    # there are local changes to be merged
    if [ -f CellServDB -a -f CellServDB.master.last ]; then
      echo Merging CellServDB entries....
***************
*** 73,79 ****
      # this is a new install, or an upgrade from pre-1.2.7
      echo "Installing new CellServDB"
      cp CellServDB.master CellServDB.master.last
!     cp CellServDB.master CellServDB
    fi
  fi
  
--- 73,81 ----
      # this is a new install, or an upgrade from pre-1.2.7
      echo "Installing new CellServDB"
      cp CellServDB.master CellServDB.master.last
!     if [ ! -e CellServDB ]; then
! 	cp CellServDB.master CellServDB
!     fi
    fi
  fi
  
Index: openafs/src/packaging/MacOS/OpenAFS.pre_upgrade
diff -c openafs/src/packaging/MacOS/OpenAFS.pre_upgrade:1.1 openafs/src/packaging/MacOS/OpenAFS.pre_upgrade:1.2
*** openafs/src/packaging/MacOS/OpenAFS.pre_upgrade:1.1	Mon Aug 26 16:24:11 2002
--- openafs/src/packaging/MacOS/OpenAFS.pre_upgrade	Thu Mar 23 11:07:30 2006
***************
*** 22,24 ****
--- 22,26 ----
      rm -f config/afsd.options
    fi
  fi
+ 
+ /Library/StartupItems/OpenAFS/OpenAFS stop
Index: openafs/src/packaging/MacOS/afssettings.m
diff -c openafs/src/packaging/MacOS/afssettings.m:1.2 openafs/src/packaging/MacOS/afssettings.m:1.3
*** openafs/src/packaging/MacOS/afssettings.m:1.2	Fri Oct 24 02:26:13 2003
--- openafs/src/packaging/MacOS/afssettings.m	Thu Mar  9 01:34:46 2006
***************
*** 1,5 ****
  /*
!  * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
   *
   * @APPLE_LICENSE_HEADER_START@
   * 
--- 1,5 ----
  /*
!  * Copyright (c) 2003, 2006 Apple Computer, Inc. All rights reserved.
   *
   * @APPLE_LICENSE_HEADER_START@
   * 
***************
*** 52,57 ****
--- 52,59 ----
      {@"Darwin14", AFS_SC_DARWIN_14, TypeNode, NULL},
      {@"Darwin60", AFS_SC_DARWIN_60, TypeNode, NULL},
      {@"Darwin70", AFS_SC_DARWIN_70, TypeNode, NULL},
+     {@"Darwin80", AFS_SC_DARWIN_80, TypeNode, NULL},
+     {@"Darwin90", AFS_SC_DARWIN_90, TypeNode, NULL},
      {NULL, 0, 0, NULL}
  };
  Setting s_first[] = {
***************
*** 79,90 ****
      int i;
  
      len = sizeof(max);
!     if(sysctl(oidmax, 3, &amp;max, &amp;len, NULL, NULL) &lt; 0)
  	err(1, "sysctl VFS_MAXTYPENUM");
      for(i = max; --i &gt;= 0; ) {
  	oidvfs[3] = i;
  	len = sizeof(conf);
! 	if(sysctl(oidvfs, 4, &amp;conf, &amp;len, NULL, NULL) &lt; 0)
  	    continue;
  	if(strcmp("afs", conf.vfc_name) == 0) {
  	    s_top.selector = conf.vfc_typenum;
--- 81,92 ----
      int i;
  
      len = sizeof(max);
!     if(sysctl(oidmax, 3, &amp;max, &amp;len, NULL, 0) &lt; 0)
  	err(1, "sysctl VFS_MAXTYPENUM");
      for(i = max; --i &gt;= 0; ) {
  	oidvfs[3] = i;
  	len = sizeof(conf);
! 	if(sysctl(oidvfs, 4, &amp;conf, &amp;len, NULL, 0) &lt; 0)
  	    continue;
  	if(strcmp("afs", conf.vfc_name) == 0) {
  	    s_top.selector = conf.vfc_typenum;
Index: openafs/src/packaging/MacOS/buildpkg.sh
diff -c openafs/src/packaging/MacOS/buildpkg.sh:1.11 openafs/src/packaging/MacOS/buildpkg.sh:1.13
*** openafs/src/packaging/MacOS/buildpkg.sh:1.11	Tue Feb 14 19:33:45 2006
--- openafs/src/packaging/MacOS/buildpkg.sh	Thu Mar 23 11:07:30 2006
***************
*** 1,13 ****
  #!/bin/sh
! # Portions Copyright (c) 2003 Apple Computer, Inc.  All rights reserved.
  
  if [ -z "$1" ]; then
!    echo Usage: buildpkg binary-dir
!   exit 1
! fi
! BINDEST=$1
! RESSRC=`pwd`
  majorvers=`uname -r | sed 's/\..*//'`
  if [ $majorvers -ge 7 ]; then
      SEP=:
      package=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
--- 1,33 ----
  #!/bin/sh
! # Portions Copyright (c) 2003, 2006 Apple Computer, Inc.  All rights reserved.
  
  if [ -z "$1" ]; then
!     echo Usage: buildpkg binary-dir
!     echo '  or'
!     echo 'Usage: buildpkg [-firstpass] binary-dir'
!     echo '            (customize pkgroot)'
!     echo '       buildpkg [-secondpass]'
!     exit 1
! fi
! 
! firstpass=yes
! secondpass=yes
! if [ "$1" = "-firstpass" ]; then
!     secondpass=no
!     shift
! elif [ "$1" = "-secondpass" ]; then
!     firstpass=no
!     shift
! fi
! 
! BINDEST=`cd $1 &amp;&amp; pwd`
! CURDIR=`pwd`
! RESSRC=`dirname $0`
! RESSRC=`cd $RESSRC &amp;&amp; pwd`
  majorvers=`uname -r | sed 's/\..*//'`
+ 
+ PKGROOT=$CURDIR/pkgroot
+ PKGRES=$CURDIR/pkgres
  if [ $majorvers -ge 7 ]; then
      SEP=:
      package=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
***************
*** 31,182 ****
      fi
  fi
  
! if [ -x /usr/bin/curl ]; then
  #    /usr/bin/curl -f -O http://www.central.org/dl/cellservdb/CellServDB
!     /usr/bin/curl -f -O http://dl.central.org/dl/cellservdb/CellServDB
! fi
! 
! if [ ! -f CellServDB ]; then
!    echo "A CellServDB file must be placed in the working directory"
!    die=1
! fi
! FILES="ReadMe.rtf License.rtf CellServDB.list OpenAFS.info OpenAFS.post_install OpenAFS.pre_upgrade csrvdbmerge.pl 2.0.txt"
! for f in $FILES; do
!    if [ ! -f $f ]; then
!      echo "file missing: " $f
!      die=1
!    fi
! done
! if [ "$die" ]; then
!   echo "Correct above errors; then retry"
!   exit 1
! fi
! if [ ! -f $BINDEST/bin/translate_et ]; then
!   die=1
! fi
! if [ ! -f $BINDEST/root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs ]; then
!   die=1
! fi
! if [ "$die" ]; then
!    echo $BINDEST " is not a valid binary dir. it should be the result of"
!    echo "make dest"
!    exit 1
! fi
! 
! PKGROOT=$RESSRC/pkgroot
! PKGRES=$RESSRC/pkgres
! rm -rf pkgroot pkgres
! mkdir -p $PKGROOT $PKGRES
! 
! mkdir $PKGROOT/Library
! chown -R root${SEP}admin $PKGROOT
! chmod -R 775 $PKGROOT
! mkdir $PKGROOT/Library/OpenAFS $PKGROOT/Library/OpenAFS/Tools
! cd $BINDEST
! pax -rw * $PKGROOT/Library/OpenAFS/Tools
! cd $RESSRC
! mkdir $PKGROOT/Library/StartupItems 
! mkdir $PKGROOT/Library/StartupItems/OpenAFS
! cp $BINDEST/root.client/usr/vice/etc/afs.rc  $PKGROOT/Library/StartupItems/OpenAFS/OpenAFS
! chmod a+x $PKGROOT/Library/StartupItems/OpenAFS/OpenAFS
! cp $BINDEST/root.client/usr/vice/etc/StartupParameters.plist  $PKGROOT/Library/StartupItems/OpenAFS/StartupParameters.plist
! chown -R root${SEP}admin $PKGROOT/Library
! chmod -R o-w $PKGROOT/Library
! chmod -R g+w $PKGROOT/Library
! chown -R root${SEP}wheel $PKGROOT/Library/StartupItems
! chmod -R og-w $PKGROOT/Library/StartupItems
! chown -R root${SEP}wheel $PKGROOT/Library/OpenAFS/Tools
! chmod -R og-w $PKGROOT/Library/OpenAFS/Tools
! 
! mkdir $PKGROOT/private $PKGROOT/private/var $PKGROOT/private/var/db
! mkdir $PKGROOT/private/var/db/openafs $PKGROOT/private/var/db/openafs/cache
! mkdir $PKGROOT/private/var/db/openafs/etc $PKGROOT/private/var/db/openafs/etc/config
! cp $RESSRC/CellServDB $PKGROOT/private/var/db/openafs/etc/CellServDB.master
! echo openafs.org &gt; $PKGROOT/private/var/db/openafs/etc/ThisCell.sample
! if [ $majorvers -ge 7 ]; then
!     echo /afs:/var/db/openafs/cache:30000 &gt; $PKGROOT/private/var/db/openafs/etc/cacheinfo.sample
!     make AFSINCLUDE=$BINDEST/include
!     cp afssettings $PKGROOT/private/var/db/openafs/etc/config
!     cp settings.plist $PKGROOT/private/var/db/openafs/etc/config/settings.plist.orig
!     make clean
! else
!     echo /Network/afs:/var/db/openafs/cache:30000 &gt; $PKGROOT/private/var/db/openafs/etc/cacheinfo.sample
! fi
! echo '-afsdb -stat 2000 -dcache 800 -daemons 3 -volumes 70 -dynroot -fakestat-all' &gt; $PKGROOT/private/var/db/openafs/etc/config/afsd.options.sample
  
! strip -X -S $PKGROOT/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs
  
! cp -RP $PKGROOT/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext $PKGROOT/private/var/db/openafs/etc
! cp -RP $PKGROOT/Library/OpenAFS/Tools/root.client/usr/vice/etc/C $PKGROOT/private/var/db/openafs/etc
  
! chown -R root${SEP}wheel $PKGROOT/private
! chmod -R og-w $PKGROOT/private
! chmod  og-rx $PKGROOT/private/var/db/openafs/cache
  
! mkdir $PKGROOT/usr $PKGROOT/usr/bin $PKGROOT/usr/sbin
  
! BINLIST="fs klog klog.krb pagsh pagsh.krb pts sys tokens tokens.krb unlog unlog.krb aklog"
  
! # Should these be linked into /usr too?
! OTHER_BINLIST="bos cmdebug rxgen translate_et udebug xstat_cm_test xstat_fs_test"
! OTHER_ETCLIST="vos rxdebug"
  
! for f in $BINLIST; do
!    ln -s ../../Library/OpenAFS/Tools/bin/$f $PKGROOT/usr/bin/$f
! done
! ln -s ../../Library/OpenAFS/Tools/bin/kpasswd $PKGROOT/usr/bin/kpasswd.afs
  
! ln -s ../../Library/OpenAFS/Tools/root.client/usr/vice/etc/afsd $PKGROOT/usr/sbin/afsd
  
! chown -R root${SEP}wheel $PKGROOT/usr
! chmod -R og-w $PKGROOT/usr
  
! if [ $majorvers -ge 7 ]; then
!     cp OpenAFS.post_install $PKGRES/postinstall
!     cp OpenAFS.pre_upgrade $PKGRES/preupgrade
!     cp OpenAFS.post_install $PKGRES/postupgrade
!     if [ $majorvers -ge 8 ]; then
!         cp InstallationCheck $PKGRES
!         mkdir $PKGRES/English.lproj
!         cp InstallationCheck $PKGRES/English.lproj
!         chmod a+x $PKGRES/InstallationCheck
      fi
!     chmod a+x $PKGRES/postinstall $PKGRES/postupgrade $PKGRES/preupgrade
! else
!     cp OpenAFS.post_install OpenAFS.pre_upgrade $PKGRES
!     cp OpenAFS.post_install $PKGRES/OpenAFS.post_upgrade
!     chmod a+x $PKGRES/OpenAFS.post_install $PKGRES/OpenAFS.post_upgrade $PKGRES/OpenAFS.pre_upgrade
! fi
! cp License.rtf ReadMe.rtf $PKGRES
! cp csrvdbmerge.pl $PKGRES
! chmod a+x $PKGRES/csrvdbmerge.pl
! cp CellServDB.list $PKGRES
! chown -R root${SEP}wheel $PKGRES
! rm -rf OpenAFS.pkg
! if [ $majorvers -ge 7 ]; then
!     echo $package -build -p $RESSRC/OpenAFS.pkg -f $PKGROOT -r $PKGRES \
! 	-i OpenAFS.Info.plist -d OpenAFS.Description.plist
!     $package -build -p $RESSRC/OpenAFS.pkg -f $PKGROOT -r $PKGRES \
! 	-i OpenAFS.Info.plist -d OpenAFS.Description.plist
! else
!     echo $package $PKGROOT OpenAFS.info -r $PKGRES
!     $package $PKGROOT OpenAFS.info -r $PKGRES
!     #old versions of package didn't handle this properly
!     if [ ! -r OpenAFS.pkg/Contents ]; then
! 	    mkdir OpenAFS.pkg/Contents OpenAFS.pkg/Contents/Resources
! 	    mv OpenAFS.pkg/OpenAFS.* OpenAFS.pkg/Contents/Resources
! 	    mv OpenAFS.pkg/*.rtf OpenAFS.pkg/Contents/Resources
! 	    mv OpenAFS.pkg/csrvdbmerge.pl OpenAFS.pkg/Contents/Resources
! 	    mv OpenAFS.pkg/CellServDB* OpenAFS.pkg/Contents/Resources
      fi
- fi
  
! rm -rf pkgroot pkgres
! mkdir dmg
! mv OpenAFS.pkg dmg
! rm -rf OpenAFS.dmg
! hdiutil create -srcfolder dmg -volname OpenAFS -anyowners OpenAFS.dmg
! rm -rf dmg
! # Unfortunately, sudo sets $USER to root, so I can't chown the 
! #.pkg dir back to myself
! #chown -R $USER OpenAFS.pkg
--- 51,210 ----
      fi
  fi
  
! if [ $firstpass = yes ]; then
!     if [ -x /usr/bin/curl ]; then
  #    /usr/bin/curl -f -O http://www.central.org/dl/cellservdb/CellServDB
! 	/usr/bin/curl -f -O http://dl.central.org/dl/cellservdb/CellServDB
!     fi
  
!     if [ ! -f CellServDB ]; then
!        echo "A CellServDB file must be placed in the working directory"
!        die=1
!     fi
!     FILES="ReadMe.rtf License.rtf CellServDB.list OpenAFS.info OpenAFS.post_install OpenAFS.pre_upgrade csrvdbmerge.pl 2.0.txt"
!     for f in $FILES; do
!        if [ ! -f $RESSRC/$f ]; then
! 	 echo "file missing: " $RESSRC/$f
! 	 die=1
!        fi
!     done
!     if [ "$die" ]; then
!       echo "Correct above errors; then retry"
!       exit 1
!     fi
!     if [ ! -f $BINDEST/bin/translate_et ]; then
!       die=1
!     fi
!     if [ ! -f $BINDEST/root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs ]; then
!       die=1
!     fi
!     if [ "$die" ]; then
!        echo $BINDEST " is not a valid binary dir. it should be the result of"
!        echo "make dest"
!        exit 1
!     fi
  
!     rm -rf $PKGROOT
!     mkdir $PKGROOT
  
!     mkdir -p $PKGROOT/Library
!     chown root${SEP}admin $PKGROOT
!     chmod 775 $PKGROOT $PKGROOT/Library
!     mkdir -p $PKGROOT/Library/OpenAFS/Tools
!     (cd $BINDEST &amp;&amp; pax -rw * $PKGROOT/Library/OpenAFS/Tools)
!     cd $RESSRC
!     mkdir -p $PKGROOT/Library/StartupItems/OpenAFS
!     cp $BINDEST/root.client/usr/vice/etc/afs.rc  $PKGROOT/Library/StartupItems/OpenAFS/OpenAFS
!     chmod a+x $PKGROOT/Library/StartupItems/OpenAFS/OpenAFS
!     cp $BINDEST/root.client/usr/vice/etc/StartupParameters.plist  $PKGROOT/Library/StartupItems/OpenAFS/StartupParameters.plist
!     chown -R root${SEP}admin $PKGROOT/Library
!     chmod -R o-w $PKGROOT/Library
!     chmod -R g+w $PKGROOT/Library
!     chown -R root${SEP}wheel $PKGROOT/Library/StartupItems
!     chmod -R og-w $PKGROOT/Library/StartupItems
!     chown -R root${SEP}wheel $PKGROOT/Library/OpenAFS/Tools
!     chmod -R og-w $PKGROOT/Library/OpenAFS/Tools
! 
!     mkdir -p $PKGROOT/private/var/db/openafs/cache
!     mkdir -p $PKGROOT/private/var/db/openafs/etc/config
!     cp $CURDIR/CellServDB $PKGROOT/private/var/db/openafs/etc/CellServDB.master
!     echo openafs.org &gt; $PKGROOT/private/var/db/openafs/etc/ThisCell.sample
!     if [ $majorvers -ge 7 ]; then
! 	echo /afs:/var/db/openafs/cache:30000 &gt; $PKGROOT/private/var/db/openafs/etc/cacheinfo.sample
! 	(cd $CURDIR &amp;&amp; \
! 	cp afssettings $PKGROOT/private/var/db/openafs/etc/config )
! 	cp settings.plist $PKGROOT/private/var/db/openafs/etc/config/settings.plist.orig
!     else
! 	echo /Network/afs:/var/db/openafs/cache:30000 &gt; $PKGROOT/private/var/db/openafs/etc/cacheinfo.sample
!     fi
!     echo '-afsdb -stat 2000 -dcache 800 -daemons 3 -volumes 70 -dynroot -fakestat-all' &gt; $PKGROOT/private/var/db/openafs/etc/config/afsd.options.sample
  
!     strip -X -S $PKGROOT/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs
  
!     cp -RP $PKGROOT/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext $PKGROOT/private/var/db/openafs/etc
!     cp -RP $PKGROOT/Library/OpenAFS/Tools/root.client/usr/vice/etc/C $PKGROOT/private/var/db/openafs/etc
  
!     chown -R root${SEP}wheel $PKGROOT/private
!     chmod -R og-w $PKGROOT/private
!     chmod  og-rx $PKGROOT/private/var/db/openafs/cache
  
!     mkdir -p $PKGROOT/usr/bin $PKGROOT/usr/sbin
  
!     BINLIST="fs klog klog.krb pagsh pagsh.krb pts sys tokens tokens.krb unlog unlog.krb aklog"
  
! # Should these be linked into /usr too?
!     OTHER_BINLIST="bos cmdebug rxgen translate_et udebug xstat_cm_test xstat_fs_test"
!     OTHER_ETCLIST="vos rxdebug"
  
!     for f in $BINLIST; do
!        ln -s ../../Library/OpenAFS/Tools/bin/$f $PKGROOT/usr/bin/$f
!     done
!     ln -s ../../Library/OpenAFS/Tools/bin/kpasswd $PKGROOT/usr/bin/kpasswd.afs
! 
!     ln -s ../../Library/OpenAFS/Tools/root.client/usr/vice/etc/afsd $PKGROOT/usr/sbin/afsd
! 
!     mkdir -p $PKGROOT/Library/Kerberos\ Plug-Ins
!     ln -s ../../Library/OpenAFS/Tools/root.client/Library/Kerberos\ Plug-Ins/aklog.loginLogout $PKGROOT/Library/Kerberos\ Plug-Ins/
! 
!     chown -R root${SEP}wheel $PKGROOT/usr
!     chmod -R og-w $PKGROOT/usr
! fi
! 
! if [ $secondpass = yes ]; then
!     rm -rf $PKGRES
!     mkdir $PKGRES
! 
!     cd $RESSRC
!     if [ $majorvers -ge 7 ]; then
! 	cp OpenAFS.post_install $PKGRES/postinstall
! 	cp OpenAFS.pre_upgrade $PKGRES/preupgrade
! 	cp OpenAFS.post_install $PKGRES/postupgrade
! 	if [ $majorvers -ge 8 ]; then
! 	    cp InstallationCheck $PKGRES
! 	    mkdir -p $PKGRES/English.lproj
! 	    cp InstallationCheck $PKGRES/English.lproj
! 	    chmod a+x $PKGRES/InstallationCheck
! 	fi
! 	chmod a+x $PKGRES/postinstall $PKGRES/postupgrade $PKGRES/preupgrade
!     else
! 	cp OpenAFS.post_install OpenAFS.pre_upgrade $PKGRES
! 	cp OpenAFS.post_install $PKGRES/OpenAFS.post_upgrade
! 	chmod a+x $PKGRES/OpenAFS.post_install $PKGRES/OpenAFS.post_upgrade $PKGRES/OpenAFS.pre_upgrade
      fi
!     cp License.rtf ReadMe.rtf $PKGRES
!     cp csrvdbmerge.pl $PKGRES
!     chmod a+x $PKGRES/csrvdbmerge.pl
!     cp CellServDB.list $PKGRES
!     chown -R root${SEP}wheel $PKGRES
!     rm -rf $CURDIR/OpenAFS.pkg
!     if [ $majorvers -ge 7 ]; then
! 	echo $package -build -p $CURDIR/OpenAFS.pkg -f $PKGROOT -r $PKGRES \
! 	    -i OpenAFS.Info.plist -d OpenAFS.Description.plist
! 	$package -build -p $CURDIR/OpenAFS.pkg -f $PKGROOT -r $PKGRES \
! 	    -i OpenAFS.Info.plist -d OpenAFS.Description.plist
!     else
! 	echo $package $PKGROOT $RESSRC/OpenAFS.info -r $PKGRES
! 	(cd $CURDIR &amp;&amp; $package $PKGROOT $RESSRC/OpenAFS.info -r $PKGRES)
! 	#old versions of package didn't handle this properly
! 	if [ ! -r $CURDIR/OpenAFS.pkg/Contents ]; then
! 		mkdir -p $CURDIR/OpenAFS.pkg/Contents/Resources
! 		mv $CURDIR/OpenAFS.pkg/OpenAFS.* $CURDIR/OpenAFS.pkg/Contents/Resources
! 		mv $CURDIR/OpenAFS.pkg/*.rtf $CURDIR/OpenAFS.pkg/Contents/Resources
! 		mv $CURDIR/OpenAFS.pkg/csrvdbmerge.pl $CURDIR/OpenAFS.pkg/Contents/Resources
! 		mv $CURDIR/OpenAFS.pkg/CellServDB* $CURDIR/OpenAFS.pkg/Contents/Resources
! 	fi
      fi
  
!     rm -rf $PKGROOT $PKGRES
!     mkdir $CURDIR/dmg
!     mv $CURDIR/OpenAFS.pkg $CURDIR/dmg
!     rm -rf $CURDIR/OpenAFS.dmg
!     hdiutil create -srcfolder $CURDIR/dmg -volname OpenAFS -anyowners $CURDIR/OpenAFS.dmg
!     rm -rf $CURDIR/dmg
!     # Unfortunately, sudo sets $USER to root, so I can't chown the 
!     #.pkg dir back to myself
!     #chown -R $USER $CURDIR/OpenAFS.pkg
! else
!     echo "First pass completed.  Customize pkgroot and then run:"
!     echo "    $0 -secondpass"
! fi
Index: openafs/src/packaging/MacOS/universal.sh
diff -c /dev/null openafs/src/packaging/MacOS/universal.sh:1.1
*** /dev/null	Thu Apr 27 12:42:30 2006
--- openafs/src/packaging/MacOS/universal.sh	Thu Mar 23 11:07:30 2006
***************
*** 0 ****
--- 1,23 ----
+ #!/bin/sh
+ 
+ if [ -z "$1" ]; then
+     echo Usage: universal topdir
+     exit 1
+ fi
+ 
+ BINDEST=`cd $1 &amp;&amp; pwd`
+ CURDIR=`pwd`
+ majorvers=`uname -r | sed 's/\..*//'`
+ 
+ DIRLIST="root.server/usr/afs/bin bin etc lib root.client/usr/vice/etc/afsd root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs"
+ mkdir $CURDIR/u_darwin_80
+ 
+ (cd $BINDEST/ppc_darwin_80; tar cf - .)|(cd $CURDIR/u_darwin_80; tar xf -)
+ (cd $BINDEST/x86_darwin_80; tar cf - .)|(cd $CURDIR/u_darwin_80; tar xf -)
+ 
+ for d in $DIRLIST; do
+     for f in `cd $CURDIR/u_darwin_80/dest &amp;&amp; find $d -type f -print`; do
+ 	/bin/rm -f $CURDIR/u_darwin_80/dest/$f
+ 	lipo $BINDEST/ppc_darwin_80/dest/$f $BINDEST/x86_darwin_80/dest/$f -create -output $CURDIR/u_darwin_80/dest/$f
+     done
+ done
Index: openafs/src/packaging/OpenBSD/buildpkg.sh
diff -c openafs/src/packaging/OpenBSD/buildpkg.sh:1.3 openafs/src/packaging/OpenBSD/buildpkg.sh:1.4
*** openafs/src/packaging/OpenBSD/buildpkg.sh:1.3	Mon Jul  7 18:30:46 2003
--- openafs/src/packaging/OpenBSD/buildpkg.sh	Fri Apr 21 10:58:38 2006
***************
*** 1,4 ****
! # $Id: buildpkg.sh,v 1.3 2003/07/07 22:30:46 rees Exp $
  
  SRC=../../../../..
  umask 022
--- 1,6 ----
! # $Id: buildpkg.sh,v 1.4 2006/04/21 14:58:38 rees Exp $
! 
! # This doesn't actually build a package any more
  
  SRC=../../../../..
  umask 022
***************
*** 30,33 ****
  
  echo '/afs:/usr/vice/cache:96000' &gt;usr/vice/etc/cacheinfo
  
! pkg_create -v -h -f packinglist -c -OpenAFS -d desc -p / -s $PWD openafs-client
--- 32,37 ----
  
  echo '/afs:/usr/vice/cache:96000' &gt;usr/vice/etc/cacheinfo
  
! tar chfvz openafs-client.tgz usr/vice
! 
! #pkg_create -v -h -f packinglist -c -OpenAFS -d desc -p / -s $PWD openafs-client
Index: openafs/src/packaging/OpenBSD/postinstall
diff -c openafs/src/packaging/OpenBSD/postinstall:1.3 openafs/src/packaging/OpenBSD/postinstall:1.4
*** openafs/src/packaging/OpenBSD/postinstall:1.3	Wed Mar 24 17:53:19 2004
--- openafs/src/packaging/OpenBSD/postinstall	Fri Apr 21 10:58:38 2006
***************
*** 1,10 ****
! # $Id: postinstall,v 1.3 2004/03/24 22:53:19 rees Exp $
  
  umask 022
  if [ ! -d /afs ]; then
    mkdir /afs
  fi
  
  strip -x /usr/vice/bin/*
  
  echo "Fetching CellServDB..."
--- 1,18 ----
! # $Id: postinstall,v 1.4 2006/04/21 14:58:38 rees Exp $
! 
! if [ `id -u` != "0" ]; then
!   echo "Must be root; current id="`id -u`
!   exit 1
! fi
  
  umask 022
  if [ ! -d /afs ]; then
    mkdir /afs
  fi
  
+ chown root.bin /usr/vice /usr/vice/cache
+ chown -R root.bin /usr/vice/bin /usr/vice/etc
+ 
  strip -x /usr/vice/bin/*
  
  echo "Fetching CellServDB..."
Index: openafs/src/pam/Makefile.in
diff -c openafs/src/pam/Makefile.in:1.13 openafs/src/pam/Makefile.in:1.14
*** openafs/src/pam/Makefile.in:1.13	Sun May 29 23:35:52 2005
--- openafs/src/pam/Makefile.in	Wed Apr 26 11:36:29 2006
***************
*** 25,31 ****
  	  afs_pam_msg.o afs_message.o AFS_component_version_number.o
     OBJS = $(SHOBJS) test_pam.o
  INCLUDES=-I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} 
! CFLAGS =  ${DEBUG} ${INCLUDES} ${PAM_CFLAGS}
  
  all: test_pam ${TOP_LIBDIR}/pam_afs.so.1 ${TOP_LIBDIR}/pam_afs.krb.so.1
  
--- 25,31 ----
  	  afs_pam_msg.o afs_message.o AFS_component_version_number.o
     OBJS = $(SHOBJS) test_pam.o
  INCLUDES=-I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} 
! CFLAGS =  ${PAM_DBG} ${PAM_OPTMZ} ${INCLUDES} ${PAM_CFLAGS}
  
  all: test_pam ${TOP_LIBDIR}/pam_afs.so.1 ${TOP_LIBDIR}/pam_afs.krb.so.1
  
Index: openafs/src/procmgmt/test/Makefile.in
diff -c openafs/src/procmgmt/test/Makefile.in:1.3 openafs/src/procmgmt/test/Makefile.in:1.4
*** openafs/src/procmgmt/test/Makefile.in:1.3	Thu Nov  1 00:00:35 2001
--- openafs/src/procmgmt/test/Makefile.in	Thu Mar  9 01:34:46 2006
***************
*** 9,15 ****
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  
! CFLAGS = $(DBUG) -I${SRCDIR}/include ${XCFLAGS}
  
  ########################################################################
  # build tests
--- 9,15 ----
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  
! CFLAGS = $(DBUG) -I${SRCDIR}/include ${XCFLAGS} ${ARCHFLAGS}
  
  ########################################################################
  # build tests
Index: openafs/src/ptserver/ptprocs.c
diff -c openafs/src/ptserver/ptprocs.c:1.28 openafs/src/ptserver/ptprocs.c:1.29
*** openafs/src/ptserver/ptprocs.c:1.28	Wed Dec  7 20:13:37 2005
--- openafs/src/ptserver/ptprocs.c	Mon Mar 13 10:09:40 2006
***************
*** 51,57 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/ptprocs.c,v 1.28 2005/12/08 01:13:37 jaltman Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;ctype.h&gt;
--- 51,57 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/ptprocs.c,v 1.29 2006/03/13 15:09:40 jaltman Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;ctype.h&gt;
***************
*** 181,187 ****
  	    goto done;
  #endif
  	if (tcell[0])
! 	    foreign = afs_is_foreign_ticket_name(tcell,name,inst,pr_realmName);
  
  	strncpy(vname, name, sizeof(vname));
  	if (ilen = strlen(inst)) {
--- 181,187 ----
  	    goto done;
  #endif
  	if (tcell[0])
! 	    foreign = afs_is_foreign_ticket_name(name,inst,tcell,pr_realmName);
  
  	strncpy(vname, name, sizeof(vname));
  	if (ilen = strlen(inst)) {
***************
*** 2324,2330 ****
  	    strcat(vname, inst);
  	}
  	if ((clen = strlen(tcell))) {
! 	    int foreign = afs_is_foreign_ticket_name(tcell,name,inst,pr_realmName);
  
  	    if (foreign) {
  		if (strlen(vname) + 1 + clen &gt;= sizeof(vname))
--- 2324,2330 ----
  	    strcat(vname, inst);
  	}
  	if ((clen = strlen(tcell))) {
! 	    int foreign = afs_is_foreign_ticket_name(name,inst,tcell,pr_realmName);
  
  	    if (foreign) {
  		if (strlen(vname) + 1 + clen &gt;= sizeof(vname))
Index: openafs/src/ptserver/pts.c
diff -c openafs/src/ptserver/pts.c:1.14 openafs/src/ptserver/pts.c:1.15
*** openafs/src/ptserver/pts.c:1.14	Wed Oct 13 10:23:25 2004
--- openafs/src/ptserver/pts.c	Mon Mar 13 18:15:44 2006
***************
*** 23,29 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/pts.c,v 1.14 2004/10/13 14:23:25 jaltman Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
--- 23,29 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/pts.c,v 1.15 2006/03/13 23:15:44 rees Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
***************
*** 73,93 ****
  } *shead;
  
  int
! Interactive(register struct cmd_syndesc *as)
  {
      finished = 0;
      return 0;
  }
  
  int
! Quit(register struct cmd_syndesc *as)
  {
      finished = 1;
      return 0;
  }
  
  int
! Source(register struct cmd_syndesc *as)
  {
      FILE *fd;
      struct sourcestack *sp;
--- 73,93 ----
  } *shead;
  
  int
! Interactive(struct cmd_syndesc *as, char *arock)
  {
      finished = 0;
      return 0;
  }
  
  int
! Quit(struct cmd_syndesc *as, char *arock)
  {
      finished = 1;
      return 0;
  }
  
  int
! Source(struct cmd_syndesc *as, char *arock)
  {
      FILE *fd;
      struct sourcestack *sp;
***************
*** 115,121 ****
  }
  
  int
! Sleep(register struct cmd_syndesc *as)
  {
      int delay;
      if (!as-&gt;parms[0].items) {
--- 115,121 ----
  }
  
  int
! Sleep(struct cmd_syndesc *as, char *arock)
  {
      int delay;
      if (!as-&gt;parms[0].items) {
***************
*** 153,159 ****
  }
  
  int
! GetGlobals(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      char *cell;
--- 153,159 ----
  }
  
  int
! GetGlobals(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      char *cell;
***************
*** 185,191 ****
  }
  
  int
! CleanUp(register struct cmd_syndesc *as)
  {
  #if defined(SUPERGROUPS)
      if (as &amp;&amp; !strcmp(as-&gt;name, "help"))
--- 185,191 ----
  }
  
  int
! CleanUp(struct cmd_syndesc *as, char *arock)
  {
  #if defined(SUPERGROUPS)
      if (as &amp;&amp; !strcmp(as-&gt;name, "help"))
***************
*** 207,213 ****
  }
  
  int
! CreateGroup(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      afs_int32 id;
--- 207,213 ----
  }
  
  int
! CreateGroup(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      afs_int32 id;
***************
*** 267,273 ****
  }
  
  int
! CreateUser(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      afs_int32 id;
--- 267,273 ----
  }
  
  int
! CreateUser(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      afs_int32 id;
***************
*** 492,498 ****
  
  
  int
! AddToGroup(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      struct cmd_item *u, *g;
--- 492,498 ----
  
  
  int
! AddToGroup(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      struct cmd_item *u, *g;
***************
*** 513,519 ****
  }
  
  int
! RemoveFromGroup(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      struct cmd_item *u, *g;
--- 513,519 ----
  }
  
  int
! RemoveFromGroup(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      struct cmd_item *u, *g;
***************
*** 534,540 ****
  }
  
  int
! ListMembership(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      idlist ids;
--- 534,540 ----
  }
  
  int
! ListMembership(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      idlist ids;
***************
*** 579,585 ****
  }
  
  int
! Delete(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      idlist ids;
--- 579,585 ----
  }
  
  int
! Delete(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      idlist ids;
***************
*** 618,624 ****
  int flags_shift[5] = { 2, 1, 2, 2, 1 };	/* bits for each */
  
  int
! CheckEntry(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      afs_int32 rcode = 1;
--- 618,624 ----
  int flags_shift[5] = { 2, 1, 2, 2, 1 };	/* bits for each */
  
  int
! CheckEntry(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      afs_int32 rcode = 1;
***************
*** 717,723 ****
  }
  
  int
! ListEntries(struct cmd_syndesc *as)
  {
      afs_int32 code = 0;
      afs_int32 flag, startindex, nentries, nextstartindex;
--- 717,723 ----
  }
  
  int
! ListEntries(struct cmd_syndesc *as, char *arock)
  {
      afs_int32 code = 0;
      afs_int32 flag, startindex, nentries, nextstartindex;
***************
*** 754,760 ****
  }
  
  int
! ChownGroup(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      char *name;
--- 754,760 ----
  }
  
  int
! ChownGroup(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      char *name;
***************
*** 770,776 ****
  }
  
  int
! ChangeName(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      char *oldname;
--- 770,776 ----
  }
  
  int
! ChangeName(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      char *oldname;
***************
*** 786,792 ****
  }
  
  int
! ListMax(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      afs_int32 maxUser, maxGroup;
--- 786,792 ----
  }
  
  int
! ListMax(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      afs_int32 maxUser, maxGroup;
***************
*** 807,813 ****
  }
  
  int
! SetMax(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      afs_int32 maxid;
--- 807,813 ----
  }
  
  int
! SetMax(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      afs_int32 maxid;
***************
*** 847,853 ****
  }
  
  int
! SetFields(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      idlist ids;
--- 847,853 ----
  }
  
  int
! SetFields(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      idlist ids;
***************
*** 942,948 ****
  }
  
  int
! ListOwned(register struct cmd_syndesc *as)
  {
      register afs_int32 code;
      idlist ids;
--- 942,948 ----
  }
  
  int
! ListOwned(struct cmd_syndesc *as, char *arock)
  {
      register afs_int32 code;
      idlist ids;
***************
*** 1162,1168 ****
  #if defined(SUPERGROUPS)
      finished = 1;
      if (code = cmd_Dispatch(argc, argv)) {
! 	CleanUp(0);
  	exit(1);
      }
      source = stdin;
--- 1162,1168 ----
  #if defined(SUPERGROUPS)
      finished = 1;
      if (code = cmd_Dispatch(argc, argv)) {
! 	CleanUp(NULL, NULL);
  	exit(1);
      }
      source = stdin;
***************
*** 1197,1203 ****
  	parsev[0] = savec;
  	cmd_FreeArgv(parsev);
      }
!     CleanUp(0);
      exit(0);
  
  #else /* SUPERGROUPS */
--- 1197,1203 ----
  	parsev[0] = savec;
  	cmd_FreeArgv(parsev);
      }
!     CleanUp(NULL, NULL);
      exit(0);
  
  #else /* SUPERGROUPS */
Index: openafs/src/ptserver/ptserver.c
diff -c openafs/src/ptserver/ptserver.c:1.24 openafs/src/ptserver/ptserver.c:1.25
*** openafs/src/ptserver/ptserver.c:1.24	Wed Feb  1 11:09:19 2006
--- openafs/src/ptserver/ptserver.c	Tue Feb 21 23:07:39 2006
***************
*** 112,118 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/ptserver.c,v 1.24 2006/02/01 16:09:19 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #ifdef	AFS_AIX32_ENV
--- 112,118 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/ptserver.c,v 1.25 2006/02/22 04:07:39 jaltman Exp $");
  
  #include &lt;afs/stds.h&gt;
  #ifdef	AFS_AIX32_ENV
***************
*** 166,171 ****
--- 166,172 ----
  char *pr_realmName;
  
  int restricted = 0;
+ int rxMaxMTU = -1;
  
  static struct afsconf_cell info;
  
***************
*** 349,354 ****
--- 350,369 ----
  	    } else
  		printf("Warning: auditlog %s not writable, ignored.\n", fileName);
  	}
+ 	else if (!strncmp(arg, "-rxmaxmtu", alen)) {
+ 	    if ((a + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for -rxmaxmtu\n");
+ 		PT_EXIT(1);
+ 	    }
+ 	    rxMaxMTU = atoi(argv[++a]);
+ 	    if ((rxMaxMTU &lt; RX_MIN_PACKET_SIZE) ||
+ 		 (rxMaxMTU &gt; RX_MAX_PACKET_DATA_SIZE)) {
+ 		printf("rxMaxMTU %d% invalid; must be between %d-%d\n",
+ 			rxMaxMTU, RX_MIN_PACKET_SIZE,
+ 			RX_MAX_PACKET_DATA_SIZE);
+ 		PT_EXIT(1);
+ 	    }
+ 	} 
  	else if (*arg == '-') {
  	    /* hack in help flag support */
  
***************
*** 359,365 ****
  		   "[-syslog[=FACILITY]] "
  		   "[-p &lt;number of processes&gt;] [-rebuild] "
  		   "[-groupdepth &lt;depth&gt;] "
! 		   "[-restricted] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-default_access default_user_access default_group_access] "
  		   "[-help]\n");
--- 374,380 ----
  		   "[-syslog[=FACILITY]] "
  		   "[-p &lt;number of processes&gt;] [-rebuild] "
  		   "[-groupdepth &lt;depth&gt;] "
! 		   "[-restricted] [-rxmaxmtu &lt;bytes&gt;]"
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-default_access default_user_access default_group_access] "
  		   "[-help]\n");
***************
*** 368,374 ****
  		   "[-auditlog &lt;log path&gt;] "
  		   "[-p &lt;number of processes&gt;] [-rebuild] "
  		   "[-default_access default_user_access default_group_access] "
! 		   "[-restricted] "
  		   "[-groupdepth &lt;depth&gt;] " "[-help]\n");
  #endif
  #else
--- 383,389 ----
  		   "[-auditlog &lt;log path&gt;] "
  		   "[-p &lt;number of processes&gt;] [-rebuild] "
  		   "[-default_access default_user_access default_group_access] "
! 		   "[-restricted] [-rxmaxmtu &lt;bytes&gt;]"
  		   "[-groupdepth &lt;depth&gt;] " "[-help]\n");
  #endif
  #else
***************
*** 379,391 ****
  		   "[-p &lt;number of processes&gt;] [-rebuild] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-default_access default_user_access default_group_access] "
! 		   "[-restricted] "
  		   "[-help]\n");
  #else /* AFS_NT40_ENV */
  	    printf("Usage: ptserver [-database &lt;db path&gt;] "
  		   "[-auditlog &lt;log path&gt;] "
  		   "[-default_access default_user_access default_group_access] "
! 		   "[-restricted] "
  		   "[-p &lt;number of processes&gt;] [-rebuild] " "[-help]\n");
  #endif
  #endif
--- 394,406 ----
  		   "[-p &lt;number of processes&gt;] [-rebuild] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-default_access default_user_access default_group_access] "
! 		   "[-restricted] [-rxmaxmtu &lt;bytes&gt;]"
  		   "[-help]\n");
  #else /* AFS_NT40_ENV */
  	    printf("Usage: ptserver [-database &lt;db path&gt;] "
  		   "[-auditlog &lt;log path&gt;] "
  		   "[-default_access default_user_access default_group_access] "
! 		   "[-restricted] [-rxmaxmtu &lt;bytes&gt;]"
  		   "[-p &lt;number of processes&gt;] [-rebuild] " "[-help]\n");
  #endif
  #endif
***************
*** 499,504 ****
--- 514,523 ----
      /* Disable jumbograms */
      rx_SetNoJumbo();
  
+     if (rxMaxMTU != -1) {
+ 	rx_SetMaxMTU(rxMaxMTU);
+     }
+ 
      tservice =
  	rx_NewService(0, PRSRV, "Protection Server", sc, 3,
  		      PR_ExecuteRequest);
Index: openafs/src/ptserver/ptuser.c
diff -c openafs/src/ptserver/ptuser.c:1.24 openafs/src/ptserver/ptuser.c:1.25
*** openafs/src/ptserver/ptuser.c:1.24	Fri Jul  8 15:58:25 2005
--- openafs/src/ptserver/ptuser.c	Fri Mar  3 15:27:23 2006
***************
*** 15,21 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/ptuser.c,v 1.24 2005/07/08 19:58:25 shadow Exp $");
  
  #if defined(UKERNEL)
  #include "afs/sysincludes.h"
--- 15,21 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/ptuser.c,v 1.25 2006/03/03 20:27:23 rees Exp $");
  
  #if defined(UKERNEL)
  #include "afs/sysincludes.h"
***************
*** 66,72 ****
  static char *whoami = "libprot";
  
  afs_int32
! pr_Initialize(IN afs_int32 secLevel, IN char *confDir, IN char *cell)
  {
      afs_int32 code;
      struct rx_connection *serverconns[MAXSERVERS];
--- 66,72 ----
  static char *whoami = "libprot";
  
  afs_int32
! pr_Initialize(IN afs_int32 secLevel, IN const char *confDir, IN char *cell)
  {
      afs_int32 code;
      struct rx_connection *serverconns[MAXSERVERS];
Index: openafs/src/ptserver/ptuser.h
diff -c openafs/src/ptserver/ptuser.h:1.2 openafs/src/ptserver/ptuser.h:1.3
*** openafs/src/ptserver/ptuser.h:1.2	Sun Apr 17 22:28:31 2005
--- openafs/src/ptserver/ptuser.h	Fri Mar  3 15:27:23 2006
***************
*** 12,18 ****
  
  #include "afs/ptint.h"
  
! afs_int32 pr_Initialize(afs_int32 secLevel, char *confDir, char *cell);
  int pr_End(void);
  int pr_CreateUser(char name[PR_MAXNAMELEN], afs_int32 *id);
  int pr_CreateGroup(char name[PR_MAXNAMELEN], char owner[PR_MAXNAMELEN], afs_int32 *id);
--- 12,18 ----
  
  #include "afs/ptint.h"
  
! afs_int32 pr_Initialize(afs_int32 secLevel, const char *confDir, char *cell);
  int pr_End(void);
  int pr_CreateUser(char name[PR_MAXNAMELEN], afs_int32 *id);
  int pr_CreateGroup(char name[PR_MAXNAMELEN], char owner[PR_MAXNAMELEN], afs_int32 *id);
Index: openafs/src/ptserver/ubik.c
diff -c openafs/src/ptserver/ubik.c:1.7 openafs/src/ptserver/ubik.c:1.8
*** openafs/src/ptserver/ubik.c:1.7	Mon Dec  8 00:50:39 2003
--- openafs/src/ptserver/ubik.c	Thu Mar  9 01:34:47 2006
***************
*** 1,10 ****
! /* $Id: ubik.c,v 1.7 2003/12/08 05:50:39 shadow Exp $ */
  
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/ubik.c,v 1.7 2003/12/08 05:50:39 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;netinet/in.h&gt;
--- 1,10 ----
! /* $Id: ubik.c,v 1.8 2006/03/09 06:34:47 shadow Exp $ */
  
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ptserver/ubik.c,v 1.8 2006/03/09 06:34:47 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;netinet/in.h&gt;
***************
*** 46,52 ****
  	thdr.version.epoch = htonl(2);
  	thdr.version.counter = htonl(0);
  	thdr.magic = htonl(UBIK_MAGIC);
! 	thdr.size = htonl(HDRSIZE);
  	lseek(dbase_fd, 0, 0);
  	write(dbase_fd, &amp;thdr, sizeof(thdr));
  	fsync(dbase_fd);
--- 46,52 ----
  	thdr.version.epoch = htonl(2);
  	thdr.version.counter = htonl(0);
  	thdr.magic = htonl(UBIK_MAGIC);
! 	thdr.size = htons(HDRSIZE);
  	lseek(dbase_fd, 0, 0);
  	write(dbase_fd, &amp;thdr, sizeof(thdr));
  	fsync(dbase_fd);
Index: openafs/src/rx/Makefile.in
diff -c openafs/src/rx/Makefile.in:1.15 openafs/src/rx/Makefile.in:1.16
*** openafs/src/rx/Makefile.in:1.15	Sat Jan 11 02:34:49 2003
--- openafs/src/rx/Makefile.in	Thu Mar  9 01:34:48 2006
***************
*** 8,14 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} -DRXDEBUG
  
  #
  # Generic xdr objects (or, at least, xdr stuff that's not newly defined for rx).
--- 8,14 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${ARCHFLAGS} -DRXDEBUG
  
  #
  # Generic xdr objects (or, at least, xdr stuff that's not newly defined for rx).
Index: openafs/src/rx/rx_clock.h
diff -c openafs/src/rx/rx_clock.h:1.15 openafs/src/rx/rx_clock.h:1.16
*** openafs/src/rx/rx_clock.h:1.15	Fri Dec 23 20:07:48 2005
--- openafs/src/rx/rx_clock.h	Mon Feb 27 15:56:47 2006
***************
*** 14,20 ****
  #define _CLOCK_
  
  #ifdef	KERNEL
! #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV)
  #include "h/systm.h"
  #include "h/time.h"
  #endif /* System V */
--- 14,20 ----
  #define _CLOCK_
  
  #ifdef	KERNEL
! #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV)
  #include "h/systm.h"
  #include "h/time.h"
  #endif /* System V */
Index: openafs/src/rx/rx_clock_nt.c
diff -c openafs/src/rx/rx_clock_nt.c:1.11 openafs/src/rx/rx_clock_nt.c:1.12
*** openafs/src/rx/rx_clock_nt.c:1.11	Thu Sep 15 22:27:16 2005
--- openafs/src/rx/rx_clock_nt.c	Sun Mar  5 22:04:38 2006
***************
*** 14,20 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_clock_nt.c,v 1.11 2005/09/16 02:27:16 jaltman Exp $");
  
  #ifdef AFS_NT40_ENV
  #include &lt;stdio.h&gt;
--- 14,20 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_clock_nt.c,v 1.12 2006/03/06 03:04:38 jaltman Exp $");
  
  #ifdef AFS_NT40_ENV
  #include &lt;stdio.h&gt;
***************
*** 50,59 ****
  	OutputDebugString("No High Performance clock, exiting.\n");
  	exit(1);
      }
- 
      clockInitialized = 1;
!     (void)QueryPerformanceCounter(&amp;rxi_clock0);
! 
      clock_UpdateTime();
  }
  
--- 50,57 ----
  	OutputDebugString("No High Performance clock, exiting.\n");
  	exit(1);
      }
      clockInitialized = 1;
!     
      clock_UpdateTime();
  }
  
Index: openafs/src/rx/rx_kcommon.c
diff -c openafs/src/rx/rx_kcommon.c:1.55 openafs/src/rx/rx_kcommon.c:1.56
*** openafs/src/rx/rx_kcommon.c:1.55	Wed Jan 18 11:03:28 2006
--- openafs/src/rx/rx_kcommon.c	Wed Mar  8 00:04:36 2006
***************
*** 15,21 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_kcommon.c,v 1.55 2006/01/18 16:03:28 rees Exp $");
  
  #include "rx/rx_kcommon.h"
  
--- 15,21 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_kcommon.c,v 1.56 2006/03/08 05:04:36 jaltman Exp $");
  
  #include "rx/rx_kcommon.h"
  
***************
*** 131,139 ****
      if (!msg)
  	msg = "Unknown AFS panic";
  
!     dpf((msg, a1, a2, a3));
  #ifdef AFS_LINUX24_ENV
-     printk("AFS BUG at %s\n", msg); 
      * ((char *) 0) = 0; 
  #else
      panic(msg);
--- 131,138 ----
      if (!msg)
  	msg = "Unknown AFS panic";
  
!     printf(msg, a1, a2, a3);
  #ifdef AFS_LINUX24_ENV
      * ((char *) 0) = 0; 
  #else
      panic(msg);
Index: openafs/src/rx/rx_packet.c
diff -c openafs/src/rx/rx_packet.c:1.61 openafs/src/rx/rx_packet.c:1.62
*** openafs/src/rx/rx_packet.c:1.61	Sat Feb 18 01:01:27 2006
--- openafs/src/rx/rx_packet.c	Mon Apr 17 14:59:41 2006
***************
*** 15,21 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_packet.c,v 1.61 2006/02/18 06:01:27 jaltman Exp $");
  
  #ifdef KERNEL
  #if defined(UKERNEL)
--- 15,21 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_packet.c,v 1.62 2006/04/17 18:59:41 shadow Exp $");
  
  #ifdef KERNEL
  #if defined(UKERNEL)
***************
*** 1419,1425 ****
  	*port = from.sin_port;
  
  	dpf(("Dropped %d %s: %x.%u.%u.%u.%u.%u.%u flags %d len %d",
! 	      p-&gt;header.serial, rx_packetTypes[p-&gt;header.type - 1], ntohl(host), ntohs(port), p-&gt;header.serial, 
  	      p-&gt;header.epoch, p-&gt;header.cid, p-&gt;header.callNumber, p-&gt;header.seq, p-&gt;header.flags, 
  	      p-&gt;length));
  	rxi_TrimDataBufs(p, 1);
--- 1419,1425 ----
  	*port = from.sin_port;
  
  	dpf(("Dropped %d %s: %x.%u.%u.%u.%u.%u.%u flags %d len %d",
! 	      p-&gt;header.serial, rx_packetTypes[p-&gt;header.type - 1], ntohl(*host), ntohs(*port), p-&gt;header.serial, 
  	      p-&gt;header.epoch, p-&gt;header.cid, p-&gt;header.callNumber, p-&gt;header.seq, p-&gt;header.flags, 
  	      p-&gt;length));
  	rxi_TrimDataBufs(p, 1);
Index: openafs/src/rx/rx_queue.h
diff -c openafs/src/rx/rx_queue.h:1.5 openafs/src/rx/rx_queue.h:1.6
*** openafs/src/rx/rx_queue.h:1.5	Mon May 30 22:11:38 2005
--- openafs/src/rx/rx_queue.h	Fri Mar 17 14:54:40 2006
***************
*** 78,83 ****
--- 78,90 ----
  #define _RXQSP(q1,q2,i,a,b,c,d,x,y) if (!queue_IsEnd(q1,i-&gt;c)) \
      (((y-&gt;b-&gt;a=q2-&gt;a)-&gt;b=y-&gt;b), ((x-&gt;a-&gt;b=q2)-&gt;a=x-&gt;a), ((i-&gt;c=q1)-&gt;d=i))
  
+ /* This one moves a chain of elements from (s) to (e) from its
+  * current position to either before or after element (i)
+  * if (a,b,x,y) is (prev,next,s,e) then chain is moved before (i)
+  * if (a,b,x,y) is (next,prev,e,s) then chain is moved after (i) */
+ #define _RXQMV(i, s, e, a, b, x, y) if (i-&gt;a != y) \
+     (((e-&gt;next-&gt;prev=s-&gt;prev)-&gt;next=e-&gt;next), ((i-&gt;a-&gt;b=x)-&gt;a=i-&gt;a), ((y-&gt;b=i)-&gt;a=y))
+ 
  /* Basic remove operation.  Doesn't update the queue item to indicate it's been removed */
  #define _RXQR(i) ((_RXQ(i)-&gt;prev-&gt;next=_RXQ(i)-&gt;next)-&gt;prev=_RXQ(i)-&gt;prev)
  
***************
*** 120,125 ****
--- 127,138 ----
  #define queue_Replace(q1,q2) if (queue_IsEmpty(q2)) queue_Init(q1); else \
      (*_RXQ(q1) = *_RXQ(q2), _RXQ(q1)-&gt;next-&gt;prev = _RXQ(q1)-&gt;prev-&gt;next = _RXQ(q1), queue_Init(q2))
  
+ /* move a chain of elements beginning at (s) and ending at (e) before node (i) */
+ #define queue_MoveChainBefore(i, s, e) _RXQMV(_RXQ(i),_RXQ(s),_RXQ(e),prev,next,_RXQ(s),_RXQ(e))
+ 
+ /* move a chain of elements beginning at (s) and ending at (e) after node (i) */
+ #define queue_MoveChainAfter(i, s, e) _RXQMV(_RXQ(i),_RXQ(s),_RXQ(e),next,prev,_RXQ(e),_RXQ(s))
+ 
  /* Remove a queue element (*i) from it's queue.  The next field is 0'd, so that any further use of this q entry will hopefully cause a core dump.  Multiple removes of the same queue item are not supported */
  #define queue_Remove(i) (_RXQR(i), _RXQ(i)-&gt;next = 0)
  
***************
*** 155,160 ****
--- 168,177 ----
  /* Returns false if the item was removed from a queue OR is uninitialized (zero) */
  #define queue_IsOnQueue(i) (_RXQ(i)-&gt;next != 0)
  
+ /* Returns true if the item was removed from a queue OR is uninitialized (zero) */
+ /* Return false if the queue item is currently in a queue */
+ #define queue_IsNotOnQueue(i) (_RXQ(i)-&gt;next == 0)
+ 
  /* Returns true if the queue item (i) is the first element of the queue (q) */
  #define queue_IsFirst(q,i) (_RXQ(q)-&gt;first == _RXQ(i))
  
***************
*** 164,169 ****
--- 181,189 ----
  /* Returns true if the queue item (i) is the end of the queue (q), that is, i is the head of the queue */
  #define queue_IsEnd(q,i) (_RXQ(q) == _RXQ(i))
  
+ /* Returns false if the queue item (i) is the end of the queue (q), that is, i is the head of the queue */
+ #define queue_IsNotEnd(q,i) (_RXQ(q) != _RXQ(i))
+ 
  /* Prototypical loop to scan an entire queue forwards.  q is the queue
   * head, qe is the loop variable, next is a variable used to store the
   * queue entry for the next iteration of the loop, s is the user's
***************
*** 180,191 ****
--- 200,223 ----
  	!queue_IsEnd(q,	qe);				\
  	(qe) = (next), next = queue_Next(qe, s)
  
+ /* similar to queue_Scan except start at element 'start' instead of the beginning */
+ #define        queue_ScanFrom(q, start, qe, next, s)      \
+     (qe) = (struct s*)(start), next = queue_Next(qe, s);  \
+        !queue_IsEnd(q, qe);                               \
+        (qe) = (next), next = queue_Next(qe, s)
+ 
  /* This is similar to queue_Scan, but scans from the end of the queue to the beginning.  Next is the previous queue entry.  */
  #define	queue_ScanBackwards(q, qe, prev, s)		\
      (qe) = queue_Last(q, s), prev = queue_Prev(qe, s);	\
  	!queue_IsEnd(q,	qe);				\
  	(qe) = prev, prev = queue_Prev(qe, s)
  
+ /* This is similar to queue_ScanBackwards, but start at element 'start' instead of the end.  Next is the previous queue entry.  */
+ #define        queue_ScanBackwardsFrom(q, start, qe, prev, s)  \
+     (qe) = (struct s*)(start), prev = queue_Prev(qe, s);       \
+        !queue_IsEnd(q, qe);                                    \
+        (qe) = prev, prev = queue_Prev(qe, s)
+ 
  #define queue_Count(q, qe, nqe, s, n) 			\
      for (n=0, queue_Scan(q, qe, nqe, s), n++) {}
  #endif /* _RX_QUEUE_ */
Index: openafs/src/rx/rx_rdwr.c
diff -c openafs/src/rx/rx_rdwr.c:1.27 openafs/src/rx/rx_rdwr.c:1.29
*** openafs/src/rx/rx_rdwr.c:1.27	Sat Nov  5 01:48:18 2005
--- openafs/src/rx/rx_rdwr.c	Mon Feb 27 19:17:52 2006
***************
*** 15,21 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_rdwr.c,v 1.27 2005/11/05 06:48:18 jaltman Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
--- 15,21 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx_rdwr.c,v 1.29 2006/02/28 00:17:52 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
***************
*** 28,33 ****
--- 28,36 ----
  #include "h/types.h"
  #include "h/time.h"
  #include "h/stat.h"
+ #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV) 
+ #include "h/systm.h"
+ #endif
  #ifdef	AFS_OSF_ENV
  #include &lt;net/net_globals.h&gt;
  #endif /* AFS_OSF_ENV */
Index: openafs/src/rx/xdr.h
diff -c openafs/src/rx/xdr.h:1.13 openafs/src/rx/xdr.h:1.14
*** openafs/src/rx/xdr.h:1.13	Sat Nov  5 01:48:18 2005
--- openafs/src/rx/xdr.h	Thu Mar  9 01:34:48 2006
***************
*** 63,69 ****
  #define mem_free(ptr, bsize)	free(ptr)
  #endif
  
! #if defined(AFS_AMD64_LINUX24_ENV) || (defined(KERNEL) &amp;&amp; !defined(UKERNEL))
  #define xdr_void afs_xdr_void
  #define xdr_int afs_xdr_int
  #define xdr_u_int afs_xdr_u_int
--- 63,69 ----
  #define mem_free(ptr, bsize)	free(ptr)
  #endif
  
! #if defined(AFS_AMD64_LINUX24_ENV) || defined(AFS_DARWIN_ENV) || (defined(KERNEL) &amp;&amp; !defined(UKERNEL))
  #define xdr_void afs_xdr_void
  #define xdr_int afs_xdr_int
  #define xdr_u_int afs_xdr_u_int
***************
*** 88,93 ****
--- 88,94 ----
  #define xdr_vector afs_xdr_vector
  #define xdr_int64 afs_xdr_int64
  #define xdr_uint64 afs_xdr_uint64
+ #define xdr_pointer afs_xdr_pointer
  #endif
  
  #ifdef	KERNEL
Index: openafs/src/rx/xdr_rx.c
diff -c openafs/src/rx/xdr_rx.c:1.13 openafs/src/rx/xdr_rx.c:1.14
*** openafs/src/rx/xdr_rx.c:1.13	Tue May 24 19:12:52 2005
--- openafs/src/rx/xdr_rx.c	Thu Mar  2 17:42:56 2006
***************
*** 19,27 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/xdr_rx.c,v 1.13 2005/05/24 23:12:52 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
  #include "h/types.h"
  #include "h/uio.h"
--- 19,28 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/xdr_rx.c,v 1.14 2006/03/02 22:42:56 rees Exp $");
  
  #ifdef KERNEL
+ #include "afs/sysincludes.h"
  #ifndef UKERNEL
  #include "h/types.h"
  #include "h/uio.h"
***************
*** 49,55 ****
  #include "rx/xdr.h"
  #include "netinet/in.h"
  #else /* !UKERNEL */
- #include "afs/sysincludes.h"
  #include "rpc/types.h"
  #include "rpc/xdr.h"
  #endif /* !UKERNEL */
--- 50,55 ----
Index: openafs/src/rx/LINUX/rx_kmutex.c
diff -c openafs/src/rx/LINUX/rx_kmutex.c:1.10 openafs/src/rx/LINUX/rx_kmutex.c:1.13
*** openafs/src/rx/LINUX/rx_kmutex.c:1.10	Wed Sep 14 01:07:28 2005
--- openafs/src/rx/LINUX/rx_kmutex.c	Thu Mar  9 01:06:35 2006
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/LINUX/rx_kmutex.c,v 1.10 2005/09/14 05:07:28 shadow Exp $");
  
  #include "rx/rx_kcommon.h"
  #include "rx_kmutex.h"
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/LINUX/rx_kmutex.c,v 1.13 2006/03/09 06:06:35 shadow Exp $");
  
  #include "rx/rx_kcommon.h"
  #include "rx_kmutex.h"
***************
*** 26,32 ****
  void
  afs_mutex_init(afs_kmutex_t * l)
  {
! #if defined(AFS_LINUX24_ENV)
      init_MUTEX(&amp;l-&gt;sem);
  #else
      l-&gt;sem = MUTEX;
--- 26,34 ----
  void
  afs_mutex_init(afs_kmutex_t * l)
  {
! #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
!     mutex_init(&amp;l-&gt;mutex);
! #elif LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,4,0)
      init_MUTEX(&amp;l-&gt;sem);
  #else
      l-&gt;sem = MUTEX;
***************
*** 37,43 ****
--- 39,49 ----
  void
  afs_mutex_enter(afs_kmutex_t * l)
  {
+ #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
+     mutex_lock(&amp;l-&gt;mutex);
+ #else
      down(&amp;l-&gt;sem);
+ #endif
      if (l-&gt;owner)
  	osi_Panic("mutex_enter: 0x%x held by %d", l, l-&gt;owner);
      l-&gt;owner = current-&gt;pid;
***************
*** 46,52 ****
--- 52,62 ----
  int
  afs_mutex_tryenter(afs_kmutex_t * l)
  {
+ #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
+     if (mutex_trylock(&amp;l-&gt;mutex) == 0)
+ #else
      if (down_trylock(&amp;l-&gt;sem))
+ #endif
  	return 0;
      l-&gt;owner = current-&gt;pid;
      return 1;
***************
*** 58,64 ****
--- 68,78 ----
      if (l-&gt;owner != current-&gt;pid)
  	osi_Panic("mutex_exit: 0x%x held by %d", l, l-&gt;owner);
      l-&gt;owner = 0;
+ #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
+     mutex_unlock(&amp;l-&gt;mutex);
+ #else
      up(&amp;l-&gt;sem);
+ #endif
  }
  
  /* CV_WAIT and CV_TIMEDWAIT sleep until the specified event occurs, or, in the
***************
*** 99,105 ****
  
      while(seq == cv-&gt;seq) {
  	schedule();
! 	/* should we refrigerate? */
      }
  
      remove_wait_queue(&amp;cv-&gt;waitq, &amp;wait);
--- 113,135 ----
  
      while(seq == cv-&gt;seq) {
  	schedule();
! #ifdef AFS_LINUX26_ENV
! #ifdef CONFIG_PM
! 	if (
! #ifdef PF_FREEZE
! 	    current-&gt;flags &amp; PF_FREEZE
! #else
! 	    !current-&gt;todo
! #endif
! 	    )
! #ifdef LINUX_REFRIGERATOR_TAKES_PF_FREEZE
! 	    refrigerator(PF_FREEZE);
! #else
! 	    refrigerator();
! #endif
! 	    set_current_state(TASK_INTERRUPTIBLE);
! #endif
! #endif
      }
  
      remove_wait_queue(&amp;cv-&gt;waitq, &amp;wait);
Index: openafs/src/rx/LINUX/rx_kmutex.h
diff -c openafs/src/rx/LINUX/rx_kmutex.h:1.16 openafs/src/rx/LINUX/rx_kmutex.h:1.17
*** openafs/src/rx/LINUX/rx_kmutex.h:1.16	Fri Oct  7 13:22:19 2005
--- openafs/src/rx/LINUX/rx_kmutex.h	Thu Mar  9 01:06:35 2006
***************
*** 31,41 ****
  struct coda_inode_info {
  };
  #endif
! #include "linux/wait.h"
! #include "linux/sched.h"
  
  typedef struct afs_kmutex {
      struct semaphore sem;
      int owner;
  } afs_kmutex_t;
  
--- 31,51 ----
  struct coda_inode_info {
  };
  #endif
! #include &lt;linux/version.h&gt;
! #include &lt;linux/wait.h&gt;
! #include &lt;linux/sched.h&gt;
! #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
! #include &lt;linux/mutex.h&gt;
! #else
! #include &lt;asm/semaphore.h&gt;
! #endif
  
  typedef struct afs_kmutex {
+ #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,16)
+     struct mutex mutex;
+ #else
      struct semaphore sem;
+ #endif
      int owner;
  } afs_kmutex_t;
  
Index: openafs/src/rx/LINUX/rx_knet.c
diff -c openafs/src/rx/LINUX/rx_knet.c:1.30 openafs/src/rx/LINUX/rx_knet.c:1.32
*** openafs/src/rx/LINUX/rx_knet.c:1.30	Tue Jul 26 13:34:05 2005
--- openafs/src/rx/LINUX/rx_knet.c	Thu Mar  2 01:39:45 2006
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/LINUX/rx_knet.c,v 1.30 2005/07/26 17:34:05 shadow Exp $");
  
  #include &lt;linux/version.h&gt;
  #ifdef AFS_LINUX22_ENV
--- 16,22 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/LINUX/rx_knet.c,v 1.32 2006/03/02 06:39:45 shadow Exp $");
  
  #include &lt;linux/version.h&gt;
  #ifdef AFS_LINUX22_ENV
***************
*** 164,169 ****
--- 164,187 ----
      TO_KERNEL_SPACE();
  
      if (code &lt; 0) {
+ #ifdef AFS_LINUX26_ENV
+ #ifdef CONFIG_PM
+ 	if (
+ #ifdef PF_FREEZE
+ 	    current-&gt;flags &amp; PF_FREEZE
+ #else
+ 	    !current-&gt;todo
+ #endif
+ 	    )
+ #ifdef LINUX_REFRIGERATOR_TAKES_PF_FREEZE
+ 	    refrigerator(PF_FREEZE);
+ #else
+ 	    refrigerator();
+ #endif
+ 	    set_current_state(TASK_INTERRUPTIBLE);
+ #endif
+ #endif
+ 
  	/* Clear the error before using the socket again.
  	 * Oh joy, Linux has hidden header files as well. It appears we can
  	 * simply call again and have it clear itself via sock_error().
Index: openafs/src/rx/SUNOS/rx_knet.c
diff -c openafs/src/rx/SUNOS/rx_knet.c:1.1 openafs/src/rx/SUNOS/rx_knet.c:1.2
*** openafs/src/rx/SUNOS/rx_knet.c:1.1	Wed Aug 21 15:23:18 2002
--- openafs/src/rx/SUNOS/rx_knet.c	Wed Mar 22 15:08:01 2006
***************
*** 1 ****
! #error kernel code not supported on SunOS 4 
--- 1 ----
! #error kernel code not supported on SunOS 4 
Index: openafs/src/rx/bulk.example/Makefile.in
diff -c openafs/src/rx/bulk.example/Makefile.in:1.4 openafs/src/rx/bulk.example/Makefile.in:1.5
*** openafs/src/rx/bulk.example/Makefile.in:1.4	Wed May 14 10:30:51 2003
--- openafs/src/rx/bulk.example/Makefile.in	Thu Mar  9 01:34:49 2006
***************
*** 13,19 ****
  LIBRX=@TOP_OBJDIR@/lib/librx.a
  DESTDIR=@srcdir@
  LIBS=${LIBRX} ${TOP_OBJDIR}/lib/liblwp.a ${TOP_OBJDIR}/lib/libafsutil.a
! CFLAGS=-g ${COMMON_INCL} -DDEBUG ${XCFLAGS}
  
  all: bulk_client bulk_server
  
--- 13,19 ----
  LIBRX=@TOP_OBJDIR@/lib/librx.a
  DESTDIR=@srcdir@
  LIBS=${LIBRX} ${TOP_OBJDIR}/lib/liblwp.a ${TOP_OBJDIR}/lib/libafsutil.a
! CFLAGS=-g ${COMMON_INCL} -DDEBUG ${XCFLAGS} ${ARCHFLAGS}
  
  all: bulk_client bulk_server
  
Index: openafs/src/rx/bulktest/Makefile.in
diff -c openafs/src/rx/bulktest/Makefile.in:1.4 openafs/src/rx/bulktest/Makefile.in:1.5
*** openafs/src/rx/bulktest/Makefile.in:1.4	Tue Jul  1 15:23:55 2003
--- openafs/src/rx/bulktest/Makefile.in	Thu Mar  9 01:34:50 2006
***************
*** 14,20 ****
  DESTDIR=/usr/andy/
  INSTALL=${SRCDIR}/bin/install
  LIBS=${LIBRX} ${SRCDIR}/lib/liblwp.a
! CFLAGS=${DBG} -I.. -I. -I${SRCDIR}/include -DDEBUG ${XCFLAGS}
  
  all: bulk_client bulk_server
  
--- 14,20 ----
  DESTDIR=/usr/andy/
  INSTALL=${SRCDIR}/bin/install
  LIBS=${LIBRX} ${SRCDIR}/lib/liblwp.a
! CFLAGS=${DBG} -I.. -I. -I${SRCDIR}/include -DDEBUG ${XCFLAGS} ${ARCHFLAGS}
  
  all: bulk_client bulk_server
  
Index: openafs/src/rx/multi.example/Makefile.in
diff -c openafs/src/rx/multi.example/Makefile.in:1.4 openafs/src/rx/multi.example/Makefile.in:1.5
*** openafs/src/rx/multi.example/Makefile.in:1.4	Tue Jul  1 15:23:57 2003
--- openafs/src/rx/multi.example/Makefile.in	Thu Mar  9 01:34:51 2006
***************
*** 14,20 ****
  DESTDIR=/usr/andy/
  INSTALL=${SRCDIR}/bin/install
  LIBS=${LIBRX} ${SRCDIR}/lib/liblwp.a
! CFLAGS=${DBG} -I.. -I. -I${SRCDIR}/include -DDEBUG ${XCFLAGS}
  
  all: sample_client sample_server
  
--- 14,20 ----
  DESTDIR=/usr/andy/
  INSTALL=${SRCDIR}/bin/install
  LIBS=${LIBRX} ${SRCDIR}/lib/liblwp.a
! CFLAGS=${DBG} -I.. -I. -I${SRCDIR}/include -DDEBUG ${XCFLAGS} ${ARCHFLAGS}
  
  all: sample_client sample_server
  
Index: openafs/src/rx/simple.example/Makefile.in
diff -c openafs/src/rx/simple.example/Makefile.in:1.4 openafs/src/rx/simple.example/Makefile.in:1.5
*** openafs/src/rx/simple.example/Makefile.in:1.4	Tue Jul  1 15:23:58 2003
--- openafs/src/rx/simple.example/Makefile.in	Thu Mar  9 01:34:52 2006
***************
*** 14,20 ****
  DESTDIR=/usr/andy/
  INSTALL=${SRCDIR}/bin/install
  LIBS=${LIBRX} ${SRCDIR}/lib/liblwp.a
! CFLAGS=${DBG} -I. -I${SRCDIR}/include -DDEBUG ${XCFLAGS}
  
  all: sample_client sample_server
  
--- 14,20 ----
  DESTDIR=/usr/andy/
  INSTALL=${SRCDIR}/bin/install
  LIBS=${LIBRX} ${SRCDIR}/lib/liblwp.a
! CFLAGS=${DBG} -I. -I${SRCDIR}/include -DDEBUG ${XCFLAGS} ${ARCHFLAGS}
  
  all: sample_client sample_server
  
Index: openafs/src/rx/test/Makefile.in
diff -c openafs/src/rx/test/Makefile.in:1.6 openafs/src/rx/test/Makefile.in:1.7
*** openafs/src/rx/test/Makefile.in:1.6	Thu Nov  1 00:00:48 2001
--- openafs/src/rx/test/Makefile.in	Thu Mar  9 01:34:52 2006
***************
*** 15,21 ****
  LIBS= ${TOP_LIBDIR}/libcmd.a  ../librx.a ${TOP_LIBDIR}/liblwp.a \
  	 ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/libsys.a ${XLIBS}
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} -DRXDEBUG ${LDIRS} ${XCFLAGS}
  
  RXTESTOBJS = testclient.o testserver.o kstest.o kctest.o
  
--- 15,21 ----
  LIBS= ${TOP_LIBDIR}/libcmd.a  ../librx.a ${TOP_LIBDIR}/liblwp.a \
  	 ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/libsys.a ${XLIBS}
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} -DRXDEBUG ${LDIRS} ${XCFLAGS} ${ARCHFLAGS}
  
  RXTESTOBJS = testclient.o testserver.o kstest.o kctest.o
  
Index: openafs/src/rxdebug/Makefile.in
diff -c openafs/src/rxdebug/Makefile.in:1.4 openafs/src/rxdebug/Makefile.in:1.5
*** openafs/src/rxdebug/Makefile.in:1.4	Sat Jan 11 02:34:50 2003
--- openafs/src/rxdebug/Makefile.in	Thu Mar  9 01:34:53 2006
***************
*** 8,14 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} -DRXDEBUG
  
  LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcmd.a \
  	       ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libafsutil.a
--- 8,14 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${ARCHFLAGS} -DRXDEBUG
  
  LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcmd.a \
  	       ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libafsutil.a
Index: openafs/src/rxkad/rxkad_client.c
diff -c openafs/src/rxkad/rxkad_client.c:1.20 openafs/src/rxkad/rxkad_client.c:1.22
*** openafs/src/rxkad/rxkad_client.c:1.20	Mon May 30 00:55:31 2005
--- openafs/src/rxkad/rxkad_client.c	Mon Feb 27 19:17:54 2006
***************
*** 19,31 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_client.c,v 1.20 2005/05/30 04:55:31 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/stds.h"
  #ifndef UKERNEL
  #include "h/types.h"
  #include "h/time.h"
  #ifdef AFS_LINUX20_ENV
  #include "h/socket.h"
  #endif
--- 19,34 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_client.c,v 1.22 2006/02/28 00:17:54 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/stds.h"
  #ifndef UKERNEL
  #include "h/types.h"
  #include "h/time.h"
+ #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV) 
+ #include "h/systm.h"
+ #endif
  #ifdef AFS_LINUX20_ENV
  #include "h/socket.h"
  #endif
Index: openafs/src/rxkad/rxkad_common.c
diff -c openafs/src/rxkad/rxkad_common.c:1.27 openafs/src/rxkad/rxkad_common.c:1.29
*** openafs/src/rxkad/rxkad_common.c:1.27	Tue May 31 15:55:35 2005
--- openafs/src/rxkad/rxkad_common.c	Mon Feb 27 19:17:54 2006
***************
*** 23,35 ****
  #define INCLUDE_RXKAD_PRIVATE_DECLS
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_common.c,v 1.27 2005/05/31 19:55:35 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
  #include "afs/stds.h"
  #include "afs/afs_osi.h"
! #ifdef	AFS_AIX_ENV
  #include "h/systm.h"
  #endif
  #if defined(AFS_DARWIN60_ENV) || defined(AFS_OBSD_ENV)
--- 23,35 ----
  #define INCLUDE_RXKAD_PRIVATE_DECLS
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_common.c,v 1.29 2006/02/28 00:17:54 shadow Exp $");
  
  #ifdef KERNEL
  #ifndef UKERNEL
  #include "afs/stds.h"
  #include "afs/afs_osi.h"
! #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV) 
  #include "h/systm.h"
  #endif
  #if defined(AFS_DARWIN60_ENV) || defined(AFS_OBSD_ENV)
Index: openafs/src/rxkad/rxkad_server.c
diff -c openafs/src/rxkad/rxkad_server.c:1.17 openafs/src/rxkad/rxkad_server.c:1.21
*** openafs/src/rxkad/rxkad_server.c:1.17	Sun Nov  6 04:29:44 2005
--- openafs/src/rxkad/rxkad_server.c	Fri Apr 14 09:12:16 2006
***************
*** 15,24 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_server.c,v 1.17 2005/11/06 09:29:44 jaltman Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;time.h&gt;
  #ifdef AFS_NT40_ENV
  #include &lt;winsock2.h&gt;
--- 15,27 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/rxkad_server.c,v 1.21 2006/04/14 13:12:16 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
+ #if (defined(AFS_AIX_ENV) &amp;&amp; defined(KERNEL) &amp;&amp; !defined(UKERNEL)) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV) 
+ #include &lt;sys/systm.h&gt;
+ #endif
  #include &lt;time.h&gt;
  #ifdef AFS_NT40_ENV
  #include &lt;winsock2.h&gt;
***************
*** 325,332 ****
       * If the alternate decoder is not present, or returns -1, then
       * assume the ticket is of the default style.
       */
!     if (code == -1 &amp;&amp; (kvno == RXKAD_TKT_TYPE_KERBEROS_V5)
! 	|| (kvno == RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY)) {
  	code =
  	    tkt_DecodeTicket5(tix, tlen, tsp-&gt;get_key, tsp-&gt;get_key_rock,
  			      kvno, client.name, client.instance, client.cell,
--- 328,335 ----
       * If the alternate decoder is not present, or returns -1, then
       * assume the ticket is of the default style.
       */
!     if (code == -1 &amp;&amp; ((kvno == RXKAD_TKT_TYPE_KERBEROS_V5)
! 	|| (kvno == RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY))) {
  	code =
  	    tkt_DecodeTicket5(tix, tlen, tsp-&gt;get_key, tsp-&gt;get_key_rock,
  			      kvno, client.name, client.instance, client.cell,
Index: openafs/src/rxkad/ticket5.c
diff -c openafs/src/rxkad/ticket5.c:1.9 openafs/src/rxkad/ticket5.c:1.10
*** openafs/src/rxkad/ticket5.c:1.9	Wed Aug 18 21:07:49 2004
--- openafs/src/rxkad/ticket5.c	Wed Feb 22 00:07:48 2006
***************
*** 62,68 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/ticket5.c,v 1.9 2004/08/19 01:07:49 kolya Exp $");
  
  #if defined(UKERNEL)
  #include "../afs/sysincludes.h"
--- 62,68 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/ticket5.c,v 1.10 2006/02/22 05:07:48 jaltman Exp $");
  
  #if defined(UKERNEL)
  #include "../afs/sysincludes.h"
***************
*** 242,252 ****
  	v5_serv_kvno = *t5.enc_part.kvno;
      }
  
- 
-     code = (*get_key) (get_key_rock, v5_serv_kvno, &amp;serv_key);
-     if (code)
- 	goto unknown_key;
- 
      /* Check that the key type really fit into 8 bytes */
      switch (t5.enc_part.etype) {
      case ETYPE_DES_CBC_CRC:
--- 242,247 ----
***************
*** 262,267 ****
--- 257,266 ----
  	|| t5.enc_part.cipher.length % 8 != 0)
  	goto bad_ticket;
  
+     code = (*get_key) (get_key_rock, v5_serv_kvno, &amp;serv_key);
+     if (code)
+ 	goto unknown_key;
+ 
      /* Decrypt data here, save in plain, assume it will shrink */
      code =
  	krb5_des_decrypt(&amp;serv_key, t5.enc_part.etype,
Index: openafs/src/rxkad/domestic/crypt_conn.c
diff -c openafs/src/rxkad/domestic/crypt_conn.c:1.13 openafs/src/rxkad/domestic/crypt_conn.c:1.15
*** openafs/src/rxkad/domestic/crypt_conn.c:1.13	Mon May 30 00:55:34 2005
--- openafs/src/rxkad/domestic/crypt_conn.c	Mon Feb 27 19:17:55 2006
***************
*** 19,30 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/domestic/crypt_conn.c,v 1.13 2005/05/30 04:55:34 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/stds.h"
  #ifndef UKERNEL
  #include "h/types.h"
  #include "rx/rx.h"
  #include "netinet/in.h"
  #else /* !UKERNEL */
--- 19,33 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/domestic/crypt_conn.c,v 1.15 2006/02/28 00:17:55 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/stds.h"
  #ifndef UKERNEL
  #include "h/types.h"
+ #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV)
+ #include "h/systm.h"
+ #endif
  #include "rx/rx.h"
  #include "netinet/in.h"
  #else /* !UKERNEL */
Index: openafs/src/rxkad/domestic/fcrypt.c
diff -c openafs/src/rxkad/domestic/fcrypt.c:1.16 openafs/src/rxkad/domestic/fcrypt.c:1.18
*** openafs/src/rxkad/domestic/fcrypt.c:1.16	Thu Jun  2 01:20:23 2005
--- openafs/src/rxkad/domestic/fcrypt.c	Mon Feb 27 19:17:55 2006
***************
*** 20,31 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/domestic/fcrypt.c,v 1.16 2005/06/02 05:20:23 shadow Exp $");
  
  #define DEBUG 0
  #ifdef KERNEL
  #ifndef UKERNEL
  #include "afs/stds.h"
  #include "h/types.h"
  #if !defined(AFS_LINUX20_ENV) &amp;&amp; !defined(AFS_OBSD_ENV)
  #include "netinet/in.h"
--- 20,34 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rxkad/domestic/fcrypt.c,v 1.18 2006/02/28 00:17:55 shadow Exp $");
  
  #define DEBUG 0
  #ifdef KERNEL
  #ifndef UKERNEL
  #include "afs/stds.h"
+ #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV) 
+ #include "h/systm.h"
+ #endif
  #include "h/types.h"
  #if !defined(AFS_LINUX20_ENV) &amp;&amp; !defined(AFS_OBSD_ENV)
  #include "netinet/in.h"
Index: openafs/src/rxkad/test/Makefile.in
diff -c openafs/src/rxkad/test/Makefile.in:1.8 openafs/src/rxkad/test/Makefile.in:1.9
*** openafs/src/rxkad/test/Makefile.in:1.8	Sun Oct 27 20:18:40 2002
--- openafs/src/rxkad/test/Makefile.in	Thu Mar  9 01:34:54 2006
***************
*** 9,15 ****
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  
! CFLAGS=-g -I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
  
  HEADERS = ../rxkad.h stress.h stress_internal.h stress_errs.h
  
--- 9,15 ----
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  
! CFLAGS=-g -I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS}
  
  HEADERS = ../rxkad.h stress.h stress_internal.h stress_errs.h
  
Index: openafs/src/scout/scout.c
diff -c openafs/src/scout/scout.c:1.9 openafs/src/scout/scout.c:1.10
*** openafs/src/scout/scout.c:1.9	Tue Jul 15 19:16:48 2003
--- openafs/src/scout/scout.c	Thu Mar  9 01:34:55 2006
***************
*** 15,21 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/scout/scout.c,v 1.9 2003/07/15 23:16:48 shadow Exp $");
  
  #undef	IN
  #ifdef	AFS_AIX32_ENV
--- 15,21 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/scout/scout.c,v 1.10 2006/03/09 06:34:55 shadow Exp $");
  
  #undef	IN
  #ifdef	AFS_AIX32_ENV
***************
*** 1765,1771 ****
--- 1765,1775 ----
  	    return (-1);
  	}
  	memcpy(&amp;(curr_skt-&gt;sin_addr.s_addr), he-&gt;h_addr, 4);
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+ 	curr_skt-&gt;sin_family = AF_INET;		/*Internet family */
+ #else
  	curr_skt-&gt;sin_family = htons(AF_INET);	/*Internet family */
+ #endif
  	curr_skt-&gt;sin_port = htons(7000);	/*FileServer port */
  
  	/*
Index: openafs/src/sgistuff/Makefile.in
diff -c openafs/src/sgistuff/Makefile.in:1.8 openafs/src/sgistuff/Makefile.in:1.9
*** openafs/src/sgistuff/Makefile.in:1.8	Tue Aug 16 13:58:27 2005
--- openafs/src/sgistuff/Makefile.in	Thu Mar  9 01:34:56 2006
***************
*** 15,22 ****
  # Note that if afskauthlib.so gets installed on a client
  # machine then that will be used ..
  #
! CFLAGS=${OPTIMIZE} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
! LDFLAGS = ${OPTIMIZE} ${XLDFLAGS}
  LIBDIR=${TOP_LIBDIR}/
  AFSLIBS=${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libprot.a ${LIBDIR}/libubik.a \
  	  ${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libsys.a \
--- 15,22 ----
  # Note that if afskauthlib.so gets installed on a client
  # machine then that will be used ..
  #
! CFLAGS=${OPTIMIZE} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS}
! LDFLAGS = ${OPTIMIZE} ${XLDFLAGS} ${ARCHFLAGS}
  LIBDIR=${TOP_LIBDIR}/
  AFSLIBS=${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libprot.a ${LIBDIR}/libubik.a \
  	  ${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libsys.a \
Index: openafs/src/sia/Makefile.in
diff -c openafs/src/sia/Makefile.in:1.7 openafs/src/sia/Makefile.in:1.8
*** openafs/src/sia/Makefile.in:1.7	Sat Jan 11 02:34:55 2003
--- openafs/src/sia/Makefile.in	Thu Mar  9 01:34:57 2006
***************
*** 23,29 ****
  clean:
  	$(RM) -f test-reauth libafssiad.so libafssiad.krb.so *.s *.o *.b core *~ *.com *.ld AFS_component_version_number.c
  
! CFLAGS=${DBG} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
  
  ${DEST}/lib/afs/libafssiad.so: libafssiad.so
  	${INSTALL} $? $@
--- 23,29 ----
  clean:
  	$(RM) -f test-reauth libafssiad.so libafssiad.krb.so *.s *.o *.b core *~ *.com *.ld AFS_component_version_number.c
  
! CFLAGS=${DBG} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS}
  
  ${DEST}/lib/afs/libafssiad.so: libafssiad.so
  	${INSTALL} $? $@
Index: openafs/src/sys/Makefile.in
diff -c openafs/src/sys/Makefile.in:1.35 openafs/src/sys/Makefile.in:1.36
*** openafs/src/sys/Makefile.in:1.35	Sat Dec 10 13:28:05 2005
--- openafs/src/sys/Makefile.in	Thu Mar  9 01:34:57 2006
***************
*** 15,21 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=-I. -I${srcdir} ${DBUG} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR}  ${XCFLAGS}
  SFLAGS=-I${TOP_INCDIR}
  LIBS=libsys.a ${TOP_LIBDIR}/librx.a libsys.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a ${XLIBS}
  
--- 15,21 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=-I. -I${srcdir} ${DBUG} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR}  ${XCFLAGS} ${ARCHFLAGS}
  SFLAGS=-I${TOP_INCDIR}
  LIBS=libsys.a ${TOP_LIBDIR}/librx.a libsys.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a ${XLIBS}
  
***************
*** 24,57 ****
  RMTOBJS=rmtsysnet.o rmtsysc.o rmtsys.cs.o rmtsys.xdr.o rmtsys.ss.o rmtsyss.o 
  
  LIBAFSSETPAG = libafssetpag.${SHLIB_SUFFIX}.${LIBAFSSETPAGMAJOR}.${LIBAFSSETPAGMINOR}
  
  all: \
! 	rmtsysd \
! 	pagsh \
! 	pagsh.krb \
! 	${TOP_INCDIR}/afs/afssyscalls.h \
! 	${TOP_INCDIR}/afs/afs.exp \
! 	${TOP_INCDIR}/afs/xfsattrs.h \
! 	${TOP_LIBDIR}/afs.exp \
! 	${TOP_LIBDIR}/libsys.a \
! 	${TOP_LIBDIR}/${LIBAFSSETPAG} \
! 	${KERNELDIR}/afs \
! 	${KERNELDIR}/afs/xfsattrs.h \
! 	${UKERNELDIR}/afs \
! 	${UKERNELDIR}/afs/afsl.exp
  
  libsys.a: ${OBJECTS} ${RMTOBJS} afsl.exp AFS_component_version_number.o
  	-$(RM) -f $@
  	$(AR) crv $@ ${OBJECTS} ${RMTOBJS} \
  		AFS_component_version_number.o ${LIBSYS_AIX_EXP}
  	$(RANLIB) $@
! 	case "${SYS_NAME}" in                   	\
  		rs_aix*) 			        \
  			$(AR) crv $@ afsl.exp;;         \
  	esac
  
  ${LIBAFSSETPAG}: ${SHLIBOBJS}
! 	case ${SYS_NAME} in \
  	*_linux*) \
  	    ${SHLIB_LINKER} -Wl,-h,libafssetpag.so.${LIBAFSSETPAGMAJOR} \
  	        -o ${LIBAFSSETPAG} -Wl,--version-script=${srcdir}/mapfile \
--- 24,63 ----
  RMTOBJS=rmtsysnet.o rmtsysc.o rmtsys.cs.o rmtsys.xdr.o rmtsys.ss.o rmtsyss.o 
  
  LIBAFSSETPAG = libafssetpag.${SHLIB_SUFFIX}.${LIBAFSSETPAGMAJOR}.${LIBAFSSETPAGMINOR}
+ LIBAFSSETPAG_DARWIN = libafssetpag.${LIBAFSSETPAGMAJOR}.${SHLIB_SUFFIX}
  
  all: \
!     rmtsysd \
!     pagsh \
!     pagsh.krb \
!     ${TOP_INCDIR}/afs/afssyscalls.h \
!     ${TOP_INCDIR}/afs/afs.exp \
!     ${TOP_INCDIR}/afs/xfsattrs.h \
!     ${TOP_LIBDIR}/afs.exp \
!     ${TOP_LIBDIR}/libsys.a \
!     ${KERNELDIR}/afs \
!     ${KERNELDIR}/afs/xfsattrs.h \
!     ${UKERNELDIR}/afs \
!     ${UKERNELDIR}/afs/afsl.exp
! 	@set -x; case ${SYS_NAME} in \
! 	*_darwin_*) \
! 	    ${MAKE} '${TOP_LIBDIR}/${LIBAFSSETPAG_DARWIN}';; \
! 	*) \
! 	    ${MAKE} '${TOP_LIBDIR}/${LIBAFSSETPAG}';; \
! 	esac
  
  libsys.a: ${OBJECTS} ${RMTOBJS} afsl.exp AFS_component_version_number.o
  	-$(RM) -f $@
  	$(AR) crv $@ ${OBJECTS} ${RMTOBJS} \
  		AFS_component_version_number.o ${LIBSYS_AIX_EXP}
  	$(RANLIB) $@
! 	@set -x; case "${SYS_NAME}" in                   	\
  		rs_aix*) 			        \
  			$(AR) crv $@ afsl.exp;;         \
  	esac
  
  ${LIBAFSSETPAG}: ${SHLIBOBJS}
! 	@set -x; case ${SYS_NAME} in \
  	*_linux*) \
  	    ${SHLIB_LINKER} -Wl,-h,libafssetpag.so.${LIBAFSSETPAGMAJOR} \
  	        -o ${LIBAFSSETPAG} -Wl,--version-script=${srcdir}/mapfile \
***************
*** 66,75 ****
  	    ${SHLIB_LINKER} -o ${LIBAFSSETPAG} ${SHLIBOBJS};; \
  	esac
  
  tests:	pagsh pagsh.krb fixit iinc idec icreate iopen istat rmtsysd
  
  syscall.o: syscall.s
! 	case "$(SYS_NAME)" in \
  	 sun4c_51 | sun4c_52 | sun4m_51 | sun4m_52 | sun4c_53 | sun4m_53  | sun4_53 | sun4_52 | sun4_54 | sun4c_54 | sun4m_54 | sun4x_5? | sun4x_5?? | sunx86_5? | sunx86_5?? ) \
  		/usr/ccs/lib/cpp -P ${SFLAGS} ${srcdir}/syscall.s syscall.ss; \
  		as -o syscall.o syscall.ss;		\
--- 72,84 ----
  	    ${SHLIB_LINKER} -o ${LIBAFSSETPAG} ${SHLIBOBJS};; \
  	esac
  
+ ${LIBAFSSETPAG_DARWIN}: ${SHLIBOBJS}
+ 	${SHLIB_LINKER} -o ${LIBAFSSETPAG_DARWIN} ${ARCHFLAGS} -install_name ${libdir}/${LIBAFSSETPAG_DARWIN} -compatibility_version ${LIBAFSSETPAGMAJOR} -current_version ${LIBAFSSETPAGMAJOR}.${LIBAFSSETPAGMINOR} ${SHLIBOBJS}
+ 
  tests:	pagsh pagsh.krb fixit iinc idec icreate iopen istat rmtsysd
  
  syscall.o: syscall.s
! 	@set -x; case "$(SYS_NAME)" in \
  	 sun4c_51 | sun4c_52 | sun4m_51 | sun4m_52 | sun4c_53 | sun4m_53  | sun4_53 | sun4_52 | sun4_54 | sun4c_54 | sun4m_54 | sun4x_5? | sun4x_5?? | sunx86_5? | sunx86_5?? ) \
  		/usr/ccs/lib/cpp -P ${SFLAGS} ${srcdir}/syscall.s syscall.ss; \
  		as -o syscall.o syscall.ss;		\
***************
*** 171,177 ****
  
  
  xfsinode: xfsinode.c  AFS_component_version_number.c
! 	case "${SYS_NAME}" in \
  		sgi_62 | sgi_64 ) \
  		$(CC) -o xfsinode ${CFLAGS} ${srcdir}/xfsinode.c ${LIBS}
  	esac
--- 180,186 ----
  
  
  xfsinode: xfsinode.c  AFS_component_version_number.c
! 	@set -x; case "${SYS_NAME}" in \
  		sgi_62 | sgi_64 ) \
  		$(CC) -o xfsinode ${CFLAGS} ${srcdir}/xfsinode.c ${LIBS}
  	esac
***************
*** 180,189 ****
  	${INSTALL} ${LIBAFSSETPAG} ${TOP_LIBDIR}/${LIBAFSSETPAG}
  	-ln -f -s ${LIBAFSSETPAG} ${TOP_LIBDIR}/libafssetpag.${SHLIB_SUFFIX}
  	-ln -f -s ${LIBAFSSETPAG} ${TOP_LIBDIR}/libafssetpag.${SHLIB_SUFFIX}.${LIBAFSSETPAGMAJOR}
   
  
  afs.exp: ${srcdir}/afs4.exp ${srcdir}/afs5.exp
! 	case ${SYS_NAME} in \
  		rs_aix5* ) \
  			cp -p ${srcdir}/afs5.exp afs.exp ;; \
  		rs_aix* ) \
--- 189,203 ----
  	${INSTALL} ${LIBAFSSETPAG} ${TOP_LIBDIR}/${LIBAFSSETPAG}
  	-ln -f -s ${LIBAFSSETPAG} ${TOP_LIBDIR}/libafssetpag.${SHLIB_SUFFIX}
  	-ln -f -s ${LIBAFSSETPAG} ${TOP_LIBDIR}/libafssetpag.${SHLIB_SUFFIX}.${LIBAFSSETPAGMAJOR}
+ 
+ ${TOP_LIBDIR}/${LIBAFSSETPAG_DARWIN}: ${LIBAFSSETPAG_DARWIN}
+ 	${INSTALL} ${LIBAFSSETPAG_DARWIN} ${TOP_LIBDIR}/${LIBAFSSETPAG_DARWIN}
+ 	-ln -f -s ${LIBAFSSETPAG_DARWIN} ${TOP_LIBDIR}/libafssetpag.${SHLIB_SUFFIX}
+ 	-ln -f -s ${LIBAFSSETPAG_DARWIN} ${TOP_LIBDIR}/libafssetpag.${LIBAFSSETPAGMAJOR}.${LIBAFSSETPAGMINOR}.${SHLIB_SUFFIX}
   
  
  afs.exp: ${srcdir}/afs4.exp ${srcdir}/afs5.exp
! 	@set -x; case ${SYS_NAME} in \
  		rs_aix5* ) \
  			cp -p ${srcdir}/afs5.exp afs.exp ;; \
  		rs_aix* ) \
***************
*** 193,199 ****
  	esac
  
  afsl.exp: ${srcdir}/afsl4.exp ${srcdir}/afsl5.exp
! 	case ${SYS_NAME} in \
  		rs_aix5* ) \
  			cp -p ${srcdir}/afsl5.exp afsl.exp ;; \
  		rs_aix* ) \
--- 207,213 ----
  	esac
  
  afsl.exp: ${srcdir}/afsl4.exp ${srcdir}/afsl5.exp
! 	@set -x; case ${SYS_NAME} in \
  		rs_aix5* ) \
  			cp -p ${srcdir}/afsl5.exp afsl.exp ;; \
  		rs_aix* ) \
***************
*** 210,222 ****
  	${INSTALL} $? $@
  
  ${TOP_INCDIR}/afs/afs.exp: afs.exp
! 	case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
  
  ${TOP_LIBDIR}/afs.exp: afs.exp
! 	case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
--- 224,236 ----
  	${INSTALL} $? $@
  
  ${TOP_INCDIR}/afs/afs.exp: afs.exp
! 	@set -x; case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
  
  ${TOP_LIBDIR}/afs.exp: afs.exp
! 	@set -x; case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
***************
*** 231,237 ****
  	mkdir -p $@
  
  ${UKERNELDIR}/afs/afsl.exp: afsl.exp
! 	case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
--- 245,251 ----
  	mkdir -p $@
  
  ${UKERNELDIR}/afs/afsl.exp: afsl.exp
! 	@set -x; case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
***************
*** 250,263 ****
  	${UKERNELDIR}/afs/afsl.exp
  
  install: \
! 	${DESTDIR}${libdir}/afs/libsys.a \
! 	${DESTDIR}${libdir}/${LIBAFSSETPAG} \
! 	${DESTDIR}${sbindir}/rmtsysd \
! 	${DESTDIR}${includedir}/afs/afssyscalls.h \
! 	${DESTDIR}${bindir}/pagsh \
! 	${DESTDIR}${bindir}/pagsh.krb \
! 	${DESTDIR}${includedir}/afs/afs.exp \
! 	${DESTDIR}${includedir}/afs/xfsattrs.h
  
  ${DESTDIR}${libdir}/afs/libsys.a: libsys.a
  	${INSTALL} $? $@
--- 264,282 ----
  	${UKERNELDIR}/afs/afsl.exp
  
  install: \
!     ${DESTDIR}${libdir}/afs/libsys.a \
!     ${DESTDIR}${sbindir}/rmtsysd \
!     ${DESTDIR}${includedir}/afs/afssyscalls.h \
!     ${DESTDIR}${bindir}/pagsh \
!     ${DESTDIR}${bindir}/pagsh.krb \
!     ${DESTDIR}${includedir}/afs/afs.exp \
!     ${DESTDIR}${includedir}/afs/xfsattrs.h
! 	@set -x; case ${SYS_NAME} in \
! 	*_darwin_*) \
! 	    ${MAKE} '${DESTDIR}${libdir}/${LIBAFSSETPAG_DARWIN}';; \
! 	*) \
! 	    ${MAKE} '${DESTDIR}${libdir}/${LIBAFSSETPAG}';; \
! 	esac
  
  ${DESTDIR}${libdir}/afs/libsys.a: libsys.a
  	${INSTALL} $? $@
***************
*** 269,274 ****
--- 288,300 ----
  	-ln -f -s ${LIBAFSSETPAG} \
  	    ${DESTDIR}${libdir}/libafssetpag.${SHLIB_SUFFIX}.${LIBAFSSETPAGMAJOR}
  
+ ${DESTDIR}${libdir}/${LIBAFSSETPAG_DARWIN}: ${LIBAFSSETPAG_DARWIN}
+ 	${INSTALL} ${LIBAFSSETPAG_DARWIN} ${DESTDIR}${libdir}/${LIBAFSSETPAG_DARWIN}
+ 	-ln -f -s ${LIBAFSSETPAG_DARWIN} \
+ 		${DESTDIR}${libdir}/libafssetpag.${SHLIB_SUFFIX} ; \
+ 	-ln -f -s ${LIBAFSSETPAG_DARWIN} \
+ 		${DESTDIR}${libdir}/libafssetpag.${LIBAFSSETPAGMAJOR}.${LIBAFSSETPAGMINOR}.${SHLIB_SUFFIX} ;; \
+ 
  ${DESTDIR}${sbindir}/rmtsysd: rmtsysd
  	${INSTALL} -s $? $@
  
***************
*** 282,288 ****
  	${INSTALL} -s $? $@
  
  ${DESTDIR}${includedir}/afs/afs.exp: afs.exp
! 	case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
--- 308,314 ----
  	${INSTALL} -s $? $@
  
  ${DESTDIR}${includedir}/afs/afs.exp: afs.exp
! 	@set -x; case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
***************
*** 291,310 ****
  	${INSTALL} $? $@
  
  dest: \
! 	${DEST}/lib/afs/libsys.a \
! 	${TOP_LIBDIR}/${LIBAFSSETPAG} \
! 	${DEST}/etc/rmtsysd \
! 	${DEST}/bin/pagsh \
! 	${DEST}/bin/pagsh.krb \
! 	${DEST}/include/afs/afssyscalls.h \
! 	${DEST}/include/afs/afs.exp \
! 	${DEST}/include/afs/xfsattrs.h
  
  ${DEST}/lib/afs/libsys.a: libsys.a
  	${INSTALL} $? $@
  
  ${DEST}/include/afs/afs.exp: afs.exp
! 	case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
--- 317,341 ----
  	${INSTALL} $? $@
  
  dest: \
!     ${DEST}/lib/afs/libsys.a \
!     ${DEST}/etc/rmtsysd \
!     ${DEST}/bin/pagsh \
!     ${DEST}/bin/pagsh.krb \
!     ${DEST}/include/afs/afssyscalls.h \
!     ${DEST}/include/afs/afs.exp \
!     ${DEST}/include/afs/xfsattrs.h
! 	@set -x; case ${SYS_NAME} in \
! 	*_darwin_*) \
! 	    ${MAKE} '${TOP_LIBDIR}/${LIBAFSSETPAG_DARWIN}';; \
! 	*) \
! 	    ${MAKE} '${TOP_LIBDIR}/${LIBAFSSETPAG}';; \
! 	esac
  
  ${DEST}/lib/afs/libsys.a: libsys.a
  	${INSTALL} $? $@
  
  ${DEST}/include/afs/afs.exp: afs.exp
! 	@set -x; case ${SYS_NAME} in \
  		rs_aix* ) \
  			${INSTALL} $? $@ ;; \
  	esac
Index: openafs/src/sys/afssyscalls.c
diff -c openafs/src/sys/afssyscalls.c:1.12 openafs/src/sys/afssyscalls.c:1.13
*** openafs/src/sys/afssyscalls.c:1.12	Sat Oct 15 11:19:38 2005
--- openafs/src/sys/afssyscalls.c	Mon Feb 20 23:45:12 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/sys/afssyscalls.c,v 1.12 2005/10/15 15:19:38 shadow Exp $");
  
  #include &lt;signal.h&gt;
  #include &lt;sys/errno.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/sys/afssyscalls.c,v 1.13 2006/02/21 04:45:12 shadow Exp $");
  
  #include &lt;signal.h&gt;
  #include &lt;sys/errno.h&gt;
***************
*** 340,352 ****
      int errcode, rval;
  
  #if defined(AFS_LINUX20_ENV)
!     rval = proc_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, follow, &amp;errcode);
  
      if(rval)
!     errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
  #elif defined(AFS_DARWIN80_ENV)
!     if (ioctl_afs_syscall(AFSCALL_PIOCTL,(long)path,cmd,(long)cmarg,follow,0,0,&amp;errcode))
!         errcode=ENOSYS;
  #else
      errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
  #endif
--- 340,356 ----
      int errcode, rval;
  
  #if defined(AFS_LINUX20_ENV)
!     rval = proc_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, 
! 			    follow, &amp;errcode);
  
      if(rval)
! 	errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, 
! 			  follow);
  #elif defined(AFS_DARWIN80_ENV)
!     rval = ioctl_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg,
! 			     follow, 0, 0, &amp;errcode);
!     if (rval)
! 	errcode = rval;
  #else
      errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
  #endif
Index: openafs/src/sys/afssyscalls.h
diff -c openafs/src/sys/afssyscalls.h:1.10 openafs/src/sys/afssyscalls.h:1.11
*** openafs/src/sys/afssyscalls.h:1.10	Sat Oct 15 11:19:38 2005
--- openafs/src/sys/afssyscalls.h	Tue Apr 11 15:40:19 2006
***************
*** 26,32 ****
--- 26,37 ----
  #ifdef AFS_SGI62_ENV
  typedef uint64_t Inode;
  #else
+ #include &lt;sys/types.h&gt;
+ #if AFS_64BIT_ENV
+ typedef afs_uint64 Inode;
+ #else
  error Need 64 bit Inode defined.
+ #endif
  #endif				/* AFS_SGI62_ENV */
  #else /* AFS_64BIT_IOPS_ENV */
  typedef unsigned int Inode;
Index: openafs/src/sys/rmtsys.xg
diff -c openafs/src/sys/rmtsys.xg:1.2 openafs/src/sys/rmtsys.xg:1.3
*** openafs/src/sys/rmtsys.xg:1.2	Sat Nov  4 05:05:50 2000
--- openafs/src/sys/rmtsys.xg	Sat Feb 25 01:44:18 2006
***************
*** 10,16 ****
  package RMTSYS_
  statindex 10
  prefix	S
! #define MAXPATHLEN 80
  
  %#include &lt;rx/rx.h&gt;
  %#include &lt;rx/rx_null.h&gt;
--- 10,16 ----
  package RMTSYS_
  statindex 10
  prefix	S
! #define MAXPATHLEN 4096
  
  %#include &lt;rx/rx.h&gt;
  %#include &lt;rx/rx_null.h&gt;
***************
*** 29,35 ****
  	afs_int32	group1;
  };
  
! const MAXBUFFERLEN = 2048;	/* limited due to kernel buffer restrictions */
  typedef opaque rmtbulk&lt;MAXBUFFERLEN&gt;;
  
  SetPag(	IN	clientcred *cred,
--- 29,35 ----
  	afs_int32	group1;
  };
  
! const MAXBUFFERLEN = 16384;	/* limited due to kernel buffer restrictions */
  typedef opaque rmtbulk&lt;MAXBUFFERLEN&gt;;
  
  SetPag(	IN	clientcred *cred,
Index: openafs/src/tests/Makefile.in
diff -c openafs/src/tests/Makefile.in:1.12 openafs/src/tests/Makefile.in:1.13
*** openafs/src/tests/Makefile.in:1.12	Sat Jan 11 02:34:57 2003
--- openafs/src/tests/Makefile.in	Thu Mar  9 01:34:58 2006
***************
*** 3,10 ****
  
  SHELL		= /bin/sh
  
! CFLAGS		= ${DBG} ${OPTMZ} -I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
! LDFLAGS=${XLDFLAGS}
  
  INCDIRS=-I${TOP_OBJDIR}/src/config -I${TOP_INCDIR}/afs -I${TOP_INCDIR}
  INCLIBS=-L${SRCDIR}/lib/afs -L${TOP_LIBDIR}
--- 3,10 ----
  
  SHELL		= /bin/sh
  
! CFLAGS		= ${DBG} ${OPTMZ} -I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS}
! LDFLAGS=${XLDFLAGS} ${ARCHFLAGS}
  
  INCDIRS=-I${TOP_OBJDIR}/src/config -I${TOP_INCDIR}/afs -I${TOP_INCDIR}
  INCLIBS=-L${SRCDIR}/lib/afs -L${TOP_LIBDIR}
Index: openafs/src/tests/dumptool.c
diff -c openafs/src/tests/dumptool.c:1.4 openafs/src/tests/dumptool.c:1.5
*** openafs/src/tests/dumptool.c:1.4	Fri Dec 17 08:45:56 2004
--- openafs/src/tests/dumptool.c	Tue Apr  4 16:51:18 2006
***************
*** 1,5 ****
  /*
!  * $Id: dumptool.c,v 1.4 2004/12/17 13:45:56 shadow Exp $
   *
   * dumptool - A tool to manage MR-AFS dump files
   *
--- 1,5 ----
  /*
!  * $Id: dumptool.c,v 1.5 2006/04/04 20:51:18 shadow Exp $
   *
   * dumptool - A tool to manage MR-AFS dump files
   *
***************
*** 314,319 ****
--- 314,320 ----
      struct winsize win;
      FILE *f;
      int fd;
+     time_t tmv;
  
  #ifdef RESIDENCY
      for (i = 0; i &lt; RS_MAXRESIDENCIES; i++) {
***************
*** 486,494 ****
  	    printf(" needsSalvaged");
  	printf("\n");
  	printf("\tuniquifier = %lu\n", vol.uniquifier);
! 	printf("\tCreation date = %s", ctime((time_t *) &amp; vol.creationDate));
! 	printf("\tLast access date = %s", ctime((time_t *) &amp; vol.accessDate));
! 	printf("\tLast update date = %s", ctime((time_t *) &amp; vol.updateDate));
  	printf("\tVolume owner = %lu\n", vol.owner);
      }
  
--- 487,498 ----
  	    printf(" needsSalvaged");
  	printf("\n");
  	printf("\tuniquifier = %lu\n", vol.uniquifier);
! 	tmv = vol.creationDate;
! 	printf("\tCreation date = %s", ctime(&amp;tmv));
! 	tmv = vol.accessDate;
! 	printf("\tLast access date = %s", ctime(&amp;tmv));
! 	tmv = vol.updateDate;
! 	printf("\tLast update date = %s", ctime(&amp;tmv));
  	printf("\tVolume owner = %lu\n", vol.owner);
      }
  
Index: openafs/src/tsalvaged/Makefile.in
diff -c /dev/null openafs/src/tsalvaged/Makefile.in:1.1
*** /dev/null	Thu Apr 27 12:42:31 2006
--- openafs/src/tsalvaged/Makefile.in	Fri Mar 17 23:20:11 2006
***************
*** 0 ****
--- 1,200 ----
+ # Copyright 2000, International Business Machines Corporation and others.
+ # All Rights Reserved.
+ # 
+ # This software has been released under the terms of the IBM Public
+ # License.  For details, see the LICENSE file in the top-level source
+ # directory or online at http://www.openafs.org/dl/license10.html
+ #
+ # Portions Copyright (c) 2003 Apple Computer, Inc.
+ # Portions Copyright (c) 2006 Sine Nomine Associates
+ 
+ srcdir=@srcdir@
+ include @TOP_OBJDIR@/src/config/Makefile.config
+ 
+ CC=${MT_CC}
+ CFLAGS=${COMMON_CFLAGS} -I.. -DNINTERFACE ${MT_CFLAGS} -DRXDEBUG -DFSSYNC_BUILD_CLIENT \
+ 	-DSALVSYNC_BUILD_SERVER -DSALVSYNC_BUILD_CLIENT
+ 
+ CCRULE=${CC} ${CFLAGS} -c $?
+ 
+ VICED=../viced
+ VLSERVER=../vlserver
+ LWP=../lwp
+ LIBACL=../libacl
+ UTIL=../util
+ DIR=../dir
+ VOL=../vol
+ FSINT=../fsint
+ 
+ SALVAGEDOBJS=salvaged.o vol-salvage.o physio.o
+ 
+ DIROBJS=buffer.o dir.o salvage.o
+ 
+ LWPOBJS=lock.o threadname.o
+ 
+ UTILOBJS=assert.o uuid.o serverLog.o fileutil.o netutils.o dirpath.o volparse.o flipbase64.o softsig.o fstab.o
+ 
+ VLIBOBJS=vnode.o volume.o vutil.o partition.o fssync-client.o \
+ 	 clone.o nuke.o devname.o listinodes.o ihandle.o \
+ 	 namei_ops.o salvsync-server.o salvsync-client.o \
+ 	 daemon_com.o
+ 
+ OBJECTS= ${SALVAGEDOBJS} ${UTILOBJS} ${VLIBOBJS} ${DIROBJS} ${LWPOBJS}
+ 
+ FSSDEBUG_OBJS = fssync-debug.o physio.o common.o ${UTILOBJS} ${VLIBOBJS} ${DIROBJS} ${LWPOBJS}
+ 
+ SSSDEBUG_OBJS = salvsync-debug.o physio.o common.o ${UTILOBJS} ${VLIBOBJS} ${DIROBJS} ${LWPOBJS}
+ 
+ LIBS=${TOP_LIBDIR}/libafsauthent.a ${TOP_LIBDIR}/libafsrpc.a ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/libcmd.a
+ 
+ INSTALL_TARGS = ${DESTDIR}${afssrvlibexecdir}/salvageserver \
+ 		${DESTDIR}${afssrvsbindir}/fssync-debug \
+ 		${DESTDIR}${afssrvsbindir}/salvsync-debug
+ 
+ DEST_TARGS =	${DEST}/root.server/usr/afs/bin/salvageserver \
+ 		${DEST}/root.server/usr/afs/bin/fssync-debug \
+ 		${DEST}/root.server/usr/afs/bin/salvsync-debug
+ 
+ all: salvageserver fssync-debug salvsync-debug
+ 
+ salvaged.o: ${VOL}/salvaged.c
+ 	${CCRULE}
+ 
+ vol-salvage.o: ${VOL}/vol-salvage.c
+ 	${CCRULE}
+ 
+ physio.o: ${VOL}/physio.c
+ 	${CCRULE}
+ 
+ fssync-debug.o: ${VOL}/fssync-debug.c
+ 	${CCRULE}
+ 
+ salvsync-debug.o: salvsync-debug.c
+ 	${CCRULE}
+ 
+ assert.o: ${UTIL}/assert.c
+ 	${CCRULE}
+ 
+ uuid.o: ${UTIL}/uuid.c
+ 	${CCRULE}
+ 
+ serverLog.o: ${UTIL}/serverLog.c
+ 	${CCRULE}
+ 
+ fileutil.o: ${UTIL}/fileutil.c
+ 	${CCRULE}
+ 
+ volparse.o: ${UTIL}/volparse.c
+ 	${CCRULE}
+ 
+ flipbase64.o: ${UTIL}/flipbase64.c
+ 	${CCRULE}
+ 
+ netutils.o: ${UTIL}/netutils.c
+ 	${CCRULE}
+ 
+ dirpath.o: ${UTIL}/dirpath.c
+ 	${CCRULE}
+ 
+ softsig.o: ${UTIL}/softsig.c
+ 	${CCRULE}
+ 
+ buffer.o: ${DIR}/buffer.c
+ 	${CCRULE}
+ 
+ dir.o: ${DIR}/dir.c
+ 	${CCRULE}
+ 
+ salvage.o: ${DIR}/salvage.c
+ 	${CCRULE}
+ 
+ lock.o: ${LWP}/lock.c
+ 	${CCRULE}
+ 
+ threadname.o: ${LWP}/threadname.c
+ 	${CCRULE}
+ 
+ vnode.o: ${VOL}/vnode.c
+ 	${CCRULE}
+ 
+ volume.o: ${VOL}/volume.c
+ 	${CCRULE}
+ 
+ vutil.o: ${VOL}/vutil.c
+ 	${CCRULE}
+ 
+ partition.o: ${VOL}/partition.c
+ 	${CCRULE}
+ 
+ fssync-client.o: ${VOL}/fssync-client.c
+ 	${CCRULE}
+ 
+ salvsync-server.o: ${VOL}/salvsync-server.c
+ 	${CCRULE}
+ 
+ salvsync-client.o: ${VOL}/salvsync-client.c
+ 	${CCRULE}
+ 
+ daemon_com.o: ${VOL}/daemon_com.c
+ 	${CCRULE}
+ 
+ clone.o: ${VOL}/clone.c
+ 	${CCRULE}
+ 
+ nuke.o: ${VOL}/nuke.c
+ 	${CCRULE}
+ 
+ devname.o: ${VOL}/devname.c
+ 	${CCRULE}
+ 
+ # only for darwin?
+ fstab.o: ${UTIL}/fstab.c
+ 	${CCRULE}
+ 
+ common.o: ${VOL}/common.c
+ 	${CCRULE}
+ 
+ listinodes.o: ${VOL}/listinodes.c
+ 	${CCRULE}
+ 
+ ihandle.o: ${VOL}/ihandle.c
+ 	${CCRULE}
+ 
+ namei_ops.o: ${VOL}/namei_ops.c
+ 	${CCRULE}
+ 
+ salvageserver: ${OBJECTS} ${LIBS}
+ 	${CC} ${LDFLAGS} -o salvageserver ${OBJECTS} ${LIBS} ${MT_LIBS} ${XLIBS}
+ 
+ fssync-debug: ${FSSDEBUG_OBJS} ${LIBS}
+ 	${CC} ${LDFLAGS} -o fssync-debug ${FSSDEBUG_OBJS} ${LIBS} ${MT_LIBS} ${XLIBS}
+ 
+ salvsync-debug: ${SSSDEBUG_OBJS} ${LIBS}
+ 	${CC} ${LDFLAGS} -o salvsync-debug ${SSSDEBUG_OBJS} ${LIBS} ${MT_LIBS} ${XLIBS}
+ 
+ ${DEST}/root.server/usr/afs/bin/salvageserver: salvageserver
+ 	${INSTALL} -ns $? $@
+ 
+ ${DEST}/root.server/usr/afs/bin/fssync-debug: fssync-debug
+ 	${INSTALL} -s $? $@
+ 
+ ${DEST}/root.server/usr/afs/bin/salvsync-debug: salvsync-debug
+ 	${INSTALL} -s $? $@
+ 
+ install: ${INSTALL_TARGS}
+ 
+ clean:
+ 	$(RM) -f *.o salvageserver core AFS_component_version_number.c
+ 
+ include ../config/Makefile.version
+ 
+ ${DESTDIR}${afssrvlibexecdir}/salvageserver: salvageserver
+ 	${INSTALL} -ns $? $@
+ 
+ ${DESTDIR}${afssrvsbindir}/fssync-debug: fssync-debug
+ 	${INSTALL} -s $? $@
+ 
+ ${DESTDIR}${afssrvsbindir}/salvsync-debug: salvsync-debug
+ 	${INSTALL} -s $? $@
+ 
+ dest: ${DEST_TARGS}
Index: openafs/src/tsalvaged/salvsync-debug.c
diff -c /dev/null openafs/src/tsalvaged/salvsync-debug.c:1.1
*** /dev/null	Thu Apr 27 12:42:31 2006
--- openafs/src/tsalvaged/salvsync-debug.c	Fri Mar 17 23:20:11 2006
***************
*** 0 ****
--- 1,475 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /* Main program file. Define globals. */
+ #define MAIN 1
+ 
+ /*
+  * salvsync debug tool
+  */
+ 
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/tsalvaged/salvsync-debug.c,v 1.1 2006/03/18 04:20:11 shadow Exp $");
+ 
+ #include &lt;stdlib.h&gt;
+ #include &lt;stdio.h&gt;
+ #include &lt;string.h&gt;
+ #include &lt;dirent.h&gt;
+ #include &lt;sys/stat.h&gt;
+ #include &lt;time.h&gt;
+ #include &lt;errno.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;io.h&gt;
+ #include &lt;WINNT/afsevent.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/file.h&gt;
+ #ifndef ITIMER_REAL
+ #include &lt;sys/time.h&gt;
+ #endif /* ITIMER_REAL */
+ #endif
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include &lt;afs/assert.h&gt;
+ 
+ 
+ #include &lt;fcntl.h&gt;
+ 
+ #ifndef AFS_NT40_ENV
+ #include &lt;afs/osi_inode.h&gt;
+ #endif
+ 
+ #include &lt;afs/cmd.h&gt;
+ #include &lt;afs/afsutil.h&gt;
+ #include &lt;afs/fileutil.h&gt;
+ 
+ #include "nfs.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ #include "daemon_com.h"
+ #include "salvsync.h"
+ #ifdef AFS_NT40_ENV
+ #include &lt;pthread.h&gt;
+ #endif
+ 
+ int VolumeChanged; /* hack to make dir package happy */
+ 
+ 
+ #ifndef AFS_DEMAND_ATTACH_FS
+ int
+ main(int argc, char ** argv)
+ {
+     fprintf(stderr, "*** salvsync-debug is only supported for OpenAFS builds with the demand-attach fileserver extension\n");
+     return -1;
+ }
+ #else /* AFS_DEMAND_ATTACH_FS */
+ 
+ struct salv_state {
+     afs_uint32 prio;
+     afs_uint32 volume;
+     char partName[16];
+ };
+ 
+ struct state {
+     afs_int32 reason;
+     struct salv_state * sop;
+ };
+ 
+ static int common_prolog(struct cmd_syndesc *, struct state *);
+ static int common_salv_prolog(struct cmd_syndesc *, struct state *);
+ 
+ static int do_salvop(struct state *, afs_int32 command, SYNC_response * res);
+ 
+ static char * response_code_to_string(afs_int32);
+ static char * command_code_to_string(afs_int32);
+ static char * reason_code_to_string(afs_int32);
+ static char * program_type_to_string(afs_int32);
+ static char * state_code_to_string(afs_int32);
+ 
+ 
+ static int OpStats(struct cmd_syndesc * as, char * rock);
+ static int OpSalvage(struct cmd_syndesc * as, char * rock);
+ static int OpCancel(struct cmd_syndesc * as, char * rock);
+ static int OpCancelAll(struct cmd_syndesc * as, char * rock);
+ static int OpRaisePrio(struct cmd_syndesc * as, char * rock);
+ static int OpQuery(struct cmd_syndesc * as, char * rock);
+ 
+ 
+ #ifndef AFS_NT40_ENV
+ #include "AFS_component_version_number.c"
+ #endif
+ #define MAX_ARGS 128
+ 
+ #define COMMON_PARMS_OFFSET    13
+ #define COMMON_PARMS(ts) \
+     cmd_Seek(ts, COMMON_PARMS_OFFSET); \
+     cmd_AddParm(ts, "-reason", CMD_SINGLE, CMD_OPTIONAL, "sync protocol reason code"); \
+     cmd_AddParm(ts, "-programtype", CMD_SINGLE, CMD_OPTIONAL, "program type code")
+ 
+ #define COMMON_SALV_PARMS_OFFSET    10
+ #define COMMON_SALV_PARMS(ts) \
+     cmd_Seek(ts, COMMON_SALV_PARMS_OFFSET); \
+     cmd_AddParm(ts, "-volumeid", CMD_SINGLE, 0, "volume id"); \
+     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); \
+     cmd_AddParm(ts, "-priority", CMD_SINGLE, CMD_OPTIONAL, "priority")
+ 
+ #define SALV_PARMS_DECL(ts) \
+     COMMON_SALV_PARMS(ts); \
+     COMMON_PARMS(ts)
+ 
+ #define COMMON_PARMS_DECL(ts) \
+     COMMON_PARMS(ts)
+ 
+ int
+ main(int argc, char **argv)
+ {
+     struct cmd_syndesc *ts;
+     int err = 0;
+     int i;
+     extern char cml_version_number[];
+ 
+     /* Initialize directory paths */
+     if (!(initAFSDirPath() &amp; AFSDIR_SERVER_PATHS_OK)) {
+ #ifdef AFS_NT40_ENV
+ 	ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
+ #endif
+ 	fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
+ 		argv[0]);
+ 	exit(2);
+     }
+ 
+ 
+     ts = cmd_CreateSyntax("stats", OpStats, 0, "get salvageserver statistics (SALVSYNC_NOP opcode)");
+     COMMON_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "nop");
+ 
+     ts = cmd_CreateSyntax("salvage", OpSalvage, 0, "schedule a salvage (SALVSYNC_SALVAGE opcode)");
+     SALV_PARMS_DECL(ts);
+ 
+     ts = cmd_CreateSyntax("cancel", OpCancel, 0, "cancel a salvage (SALVSYNC_CANCEL opcode)");
+     SALV_PARMS_DECL(ts);
+ 
+     ts = cmd_CreateSyntax("raiseprio", OpRaisePrio, 0, "raise a salvage priority (SALVSYNC_RAISEPRIO opcode)");
+     SALV_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "rp");
+ 
+     ts = cmd_CreateSyntax("query", OpQuery, 0, "query salvage status (SALVSYNC_QUERY opcode)");
+     SALV_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "qry");
+ 
+     ts = cmd_CreateSyntax("kill", OpCancelAll, 0, "cancel all scheduled salvages (SALVSYNC_CANCELALL opcode)");
+     COMMON_PARMS_DECL(ts);
+ 
+     err = cmd_Dispatch(argc, argv);
+     exit(err);
+ }
+ 
+ static int
+ common_prolog(struct cmd_syndesc * as, struct state * state)
+ {
+     register struct cmd_item *ti;
+ 
+ #ifdef AFS_NT40_ENV
+     if (afs_winsockInit() &lt; 0) {
+ 	Exit(1);
+     }
+ #endif
+ 
+     VInitVolumePackage(debugUtility, 1, 1,
+ 		       DONT_CONNECT_FS, 0);
+     DInit(1);
+ 
+     if ((ti = as-&gt;parms[COMMON_PARMS_OFFSET].items)) {	/* -reason */
+ 	state-&gt;reason = atoi(ti-&gt;data);
+     }
+     if ((ti = as-&gt;parms[COMMON_PARMS_OFFSET+1].items)) {	/* -programtype */
+ 	if (!strcmp(ti-&gt;data, "fileServer")) {
+ 	    programType = fileServer;
+ 	} else if (!strcmp(ti-&gt;data, "volumeUtility")) {
+ 	    programType = volumeUtility;
+ 	} else if (!strcmp(ti-&gt;data, "salvager")) {
+ 	    programType = salvager;
+ 	} else if (!strcmp(ti-&gt;data, "salvageServer")) {
+ 	    programType = salvageServer;
+ 	} else {
+ 	    programType = (ProgramType) atoi(ti-&gt;data);
+ 	}
+     }
+ 
+     VConnectSALV();
+ 
+     return 0;
+ }
+ 
+ static int
+ common_salv_prolog(struct cmd_syndesc * as, struct state * state)
+ {
+     register struct cmd_item *ti;
+     char pname[100], *temp;
+ 
+     state-&gt;sop = (struct salv_state *) calloc(1, sizeof(struct salv_state));
+     assert(state-&gt;sop != NULL);
+ 
+     if ((ti = as-&gt;parms[COMMON_SALV_PARMS_OFFSET].items)) {	/* -volumeid */
+ 	state-&gt;sop-&gt;volume = atoi(ti-&gt;data);
+     } else {
+ 	fprintf(stderr, "required argument -volumeid not given\n");
+     }
+ 
+     if ((ti = as-&gt;parms[COMMON_SALV_PARMS_OFFSET+1].items)) {	/* -partition */
+ 	strlcpy(state-&gt;sop-&gt;partName, ti-&gt;data, sizeof(state-&gt;sop-&gt;partName));
+     } else {
+ 	memset(state-&gt;sop-&gt;partName, 0, sizeof(state-&gt;sop-&gt;partName));
+     }
+ 
+     if ((ti = as-&gt;parms[COMMON_SALV_PARMS_OFFSET+2].items)) {	/* -prio */
+ 	state-&gt;sop-&gt;prio = atoi(ti-&gt;data);
+     } else {
+ 	state-&gt;sop-&gt;prio = 0;
+     }
+ 
+     return 0;
+ }
+ 
+ static int
+ do_salvop(struct state * state, afs_int32 command, SYNC_response * res)
+ {
+     afs_int32 code;
+     SALVSYNC_response_hdr hdr_l, *hdr;
+     SYNC_response res_l;
+ 
+     if (!res) {
+ 	res = &amp;res_l;
+ 	res-&gt;payload.len = sizeof(hdr_l);
+ 	res-&gt;payload.buf = hdr = &amp;hdr_l;
+     } else {
+ 	hdr = (SALVSYNC_response_hdr *) res-&gt;payload.buf;
+     }
+ 
+     fprintf(stderr, "calling SALVSYNC_SalvageVolume with command code %d (%s)\n", 
+ 	    command, command_code_to_string(command));
+ 
+     code = SALVSYNC_SalvageVolume(state-&gt;sop-&gt;volume,
+ 				  state-&gt;sop-&gt;partName,
+ 				  command,
+ 				  state-&gt;reason,
+ 				  state-&gt;sop-&gt;prio,
+ 				  res);
+ 
+     switch (code) {
+     case SYNC_OK:
+     case SYNC_DENIED:
+ 	break;
+     default:
+ 	fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
+     }
+ 
+     fprintf(stderr, "SALVSYNC_SalvageVolume returned %d (%s)\n", code, response_code_to_string(code));
+     fprintf(stderr, "protocol response code was %d (%s)\n", 
+ 	    res-&gt;hdr.response, response_code_to_string(res-&gt;hdr.response));
+     fprintf(stderr, "protocol reason code was %d (%s)\n", 
+ 	    res-&gt;hdr.reason, reason_code_to_string(res-&gt;hdr.reason));
+ 
+     printf("state = {\n");
+     if (res-&gt;hdr.flags &amp; SALVSYNC_FLAG_VOL_STATS_VALID) {
+ 	printf("\tstate = %d (%s)\n",
+ 	       hdr-&gt;state, state_code_to_string(hdr-&gt;state));
+ 	printf("\tprio = %d\n", hdr-&gt;prio);
+     }
+     printf("\tsq_len = %d\n", hdr-&gt;sq_len);
+     printf("\tpq_len = %d\n", hdr-&gt;pq_len);
+     printf("}\n");
+ 
+     VDisconnectSALV();
+ }
+ 
+ static char *
+ response_code_to_string(afs_int32 response)
+ {
+     switch (response) {
+     case SYNC_OK:
+ 	return "SYNC_OK";
+     case SYNC_DENIED:
+ 	return "SYNC_DENIED";
+     case SYNC_COM_ERROR:
+ 	return "SYNC_COM_ERROR";
+     case SYNC_BAD_COMMAND:
+ 	return "SYNC_BAD_COMMAND";
+     case SYNC_FAILED:
+ 	return "SYNC_FAILED";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static char *
+ command_code_to_string(afs_int32 command)
+ {
+     switch (command) {
+     case SYNC_COM_CHANNEL_CLOSE:
+ 	return "SYNC_COM_CHANNEL_CLOSE";
+     case SALVSYNC_NOP:
+ 	return "SALVSYNC_NOP";
+     case SALVSYNC_SALVAGE:
+ 	return "SALVSYNC_SALVAGE";
+     case SALVSYNC_CANCEL:
+ 	return "SALVSYNC_CANCEL";
+     case SALVSYNC_RAISEPRIO:
+ 	return "SALVSYNC_RAISEPRIO";
+     case SALVSYNC_QUERY:
+ 	return "SALVSYNC_QUERY";
+     case SALVSYNC_CANCELALL:
+ 	return "SALVSYNC_CANCELLALL";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static char *
+ reason_code_to_string(afs_int32 reason)
+ {
+     switch (reason) {
+     case SALVSYNC_WHATEVER:
+ 	return "SALVSYNC_WHATEVER";
+     case SALVSYNC_ERROR:
+ 	return "SALVSYNC_ERROR";
+     case SALVSYNC_OPERATOR:
+ 	return "SALVSYNC_OPERATOR";
+     case SALVSYNC_SHUTDOWN:
+ 	return "SALVSYNC_SHUTDOWN";
+     case SALVSYNC_NEEDED:
+ 	return "SALVSYNC_NEEDED";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static char *
+ program_type_to_string(afs_int32 type)
+ {
+     switch ((ProgramType)type) {
+     case fileServer:
+ 	return "fileServer";
+     case volumeUtility:
+ 	return "volumeUtility";
+     case salvager:
+ 	return "salvager";
+     case salvageServer:
+ 	return "salvageServer";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static char *
+ state_code_to_string(afs_int32 state)
+ {
+     switch (state) {
+     case SALVSYNC_STATE_UNKNOWN:
+ 	return "SALVSYNC_STATE_UNKNOWN";
+     case SALVSYNC_STATE_QUEUED:
+ 	return "SALVSYNC_STATE_QUEUED";
+     case SALVSYNC_STATE_SALVAGING:
+ 	return "SALVSYNC_STATE_SALVAGING";
+     case SALVSYNC_STATE_ERROR:
+ 	return "SALVSYNC_STATE_ERROR";
+     case SALVSYNC_STATE_DONE:
+ 	return "SALVSYNC_STATE_DONE";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static int
+ OpStats(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_salv_prolog(as, &amp;state);
+ 
+     do_salvop(&amp;state, SALVSYNC_NOP, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ OpSalvage(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_salv_prolog(as, &amp;state);
+ 
+     do_salvop(&amp;state, SALVSYNC_SALVAGE, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ OpCancel(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_salv_prolog(as, &amp;state);
+ 
+     do_salvop(&amp;state, SALVSYNC_CANCEL, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ OpCancelAll(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_salv_prolog(as, &amp;state);
+ 
+     do_salvop(&amp;state, SALVSYNC_CANCELALL, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ OpRaisePrio(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_salv_prolog(as, &amp;state);
+ 
+     do_salvop(&amp;state, SALVSYNC_RAISEPRIO, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ OpQuery(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_salv_prolog(as, &amp;state);
+ 
+     do_salvop(&amp;state, SALVSYNC_QUERY, NULL);
+ 
+     return 0;
+ }
+ 
+ #endif /* AFS_DEMAND_ATTACH_FS */
Index: openafs/src/tsm41/Makefile.in
diff -c openafs/src/tsm41/Makefile.in:1.7 openafs/src/tsm41/Makefile.in:1.8
*** openafs/src/tsm41/Makefile.in:1.7	Tue May 21 01:35:49 2002
--- openafs/src/tsm41/Makefile.in	Thu Mar  9 01:34:59 2006
***************
*** 9,15 ****
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  
! CFLAGS=${OPTIMIZE} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
  AFSLIBS =  ${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libprot.a \
  	   ${TOP_LIBDIR}/libubik.a ${TOP_LIBDIR}/libauth.a \
  	   ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libsys.a \
--- 9,15 ----
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  
! CFLAGS=${OPTIMIZE} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS}
  AFSLIBS =  ${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libprot.a \
  	   ${TOP_LIBDIR}/libubik.a ${TOP_LIBDIR}/libauth.a \
  	   ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libsys.a \
Index: openafs/src/tviced/.cvsignore
diff -c openafs/src/tviced/.cvsignore:1.1 openafs/src/tviced/.cvsignore:1.2
*** openafs/src/tviced/.cvsignore:1.1	Mon Sep 10 16:14:42 2001
--- openafs/src/tviced/.cvsignore	Mon Mar 27 12:27:38 2006
***************
*** 1,2 ****
--- 1,3 ----
  Makefile
  fileserver
+ state_analyzer
Index: openafs/src/tviced/Makefile.in
diff -c openafs/src/tviced/Makefile.in:1.11 openafs/src/tviced/Makefile.in:1.13
*** openafs/src/tviced/Makefile.in:1.11	Mon Aug  8 11:30:50 2005
--- openafs/src/tviced/Makefile.in	Fri Mar 17 14:54:42 2006
***************
*** 11,17 ****
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  CC=${MT_CC}
! CFLAGS=${COMMON_CFLAGS} -I.. -DNINTERFACE ${MT_CFLAGS} -DRXDEBUG
  
  CCRULE=${CC} ${CFLAGS} -c $?
  
--- 11,17 ----
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  CC=${MT_CC}
! CFLAGS=${COMMON_CFLAGS} -I.. -DNINTERFACE ${MT_CFLAGS} -DRXDEBUG -DFSSYNC_BUILD_SERVER -DSALVSYNC_BUILD_CLIENT
  
  CCRULE=${CC} ${CFLAGS} -c $?
  
***************
*** 24,30 ****
  VOL=../vol
  FSINT=../fsint
  
! VICEDOBJS=viced.o afsfileprocs.o host.o physio.o callback.o	
  
  VLSERVEROBJS=vldbint.cs.o vldbint.xdr.o
  
--- 24,30 ----
  VOL=../vol
  FSINT=../fsint
  
! VICEDOBJS=viced.o afsfileprocs.o host.o physio.o callback.o serialize_state.o	
  
  VLSERVEROBJS=vldbint.cs.o vldbint.xdr.o
  
***************
*** 36,53 ****
  
  DIROBJS=buffer.o dir.o salvage.o
  
! VOLOBJS= vnode.o volume.o vutil.o partition.o fssync.o purge.o \
  	 clone.o devname.o common.o ihandle.o listinodes.o namei_ops.o \
! 	 fstab.o
  
  FSINTOBJS= afsaux.o afscbint.cs.o afsint.ss.o afsint.xdr.o
  
  objects= ${VICEDOBJS} ${VLSERVEROBJS} ${LWPOBJS} ${LIBACLOBJS} \
  	 ${UTILOBJS} ${DIROBJS} ${VOLOBJS} ${FSINTOBJS}
  
  LIBS=${TOP_LIBDIR}/libafsauthent.a ${TOP_LIBDIR}/libafsrpc.a ${TOP_LIBDIR}/util.a
  
! all: fileserver
  
  viced.o: ${VICED}/viced.c
  	${CCRULE}
--- 36,55 ----
  
  DIROBJS=buffer.o dir.o salvage.o
  
! VOLOBJS= vnode.o volume.o vutil.o partition.o fssync-server.o \
  	 clone.o devname.o common.o ihandle.o listinodes.o namei_ops.o \
! 	 fstab.o salvsync-client.o daemon_com.o
  
  FSINTOBJS= afsaux.o afscbint.cs.o afsint.ss.o afsint.xdr.o
  
  objects= ${VICEDOBJS} ${VLSERVEROBJS} ${LWPOBJS} ${LIBACLOBJS} \
  	 ${UTILOBJS} ${DIROBJS} ${VOLOBJS} ${FSINTOBJS}
  
+ SDBGOBJS = state_analyzer.o uuid.o dirpath.o fileutil.o ${TOP_LIBDIR}/util.a
+ 
  LIBS=${TOP_LIBDIR}/libafsauthent.a ${TOP_LIBDIR}/libafsrpc.a ${TOP_LIBDIR}/util.a
  
! all: fileserver state_analyzer
  
  viced.o: ${VICED}/viced.c
  	${CCRULE}
***************
*** 64,69 ****
--- 66,74 ----
  callback.o: ${VICED}/callback.c
  	${CCRULE}
  
+ serialize_state.o: ./serialize_state.c
+ 	${CCRULE}
+ 
  assert.o: ${UTIL}/assert.c
  	${CCRULE}
  
***************
*** 130,139 ****
  partition.o: ${VOL}/partition.c
  	${CCRULE}
  
! fssync.o: ${VOL}/fssync.c
  	${CCRULE}
  
! purge.o: ${VOL}/purge.c
  	${CCRULE}
  
  clone.o: ${VOL}/clone.c
--- 135,150 ----
  partition.o: ${VOL}/partition.c
  	${CCRULE}
  
! fssync-server.o: ${VOL}/fssync-server.c
! 	${CCRULE}
! 
! fssync-client.o: ${VOL}/fssync-client.c
! 	${CCRULE}
! 
! salvsync-client.o: ${VOL}/salvsync-client.c
  	${CCRULE}
  
! daemon_com.o: ${VOL}/daemon_com.c
  	${CCRULE}
  
  clone.o: ${VOL}/clone.c
***************
*** 145,152 ****
  devname.o: ${VOL}/devname.c
  	${CCRULE}
  
! # only for darwin
! fstab.o: ${VOL}/fstab.c
  	${CCRULE}
  
  common.o: ${VOL}/common.c
--- 156,163 ----
  devname.o: ${VOL}/devname.c
  	${CCRULE}
  
! # only for darwin?
! fstab.o: ${UTIL}/fstab.c
  	${CCRULE}
  
  common.o: ${VOL}/common.c
***************
*** 179,199 ****
  afsint.xdr.o: ${FSINT}/afsint.xdr.c
  	${CCRULE}
  
  fileserver: ${objects} ${LIBS}
  	${CC} ${LDFLAGS} -o fileserver ${objects} ${LIBS} ${MT_LIBS} ${XLIBS}
  
  ${DEST}/root.server/usr/afs/bin/fileserver: fileserver
  	${INSTALL} -ns $? $@
  
! install: ${DESTDIR}${afssrvlibexecdir}/fileserver
  
  clean:
! 	$(RM) -f *.o fileserver core AFS_component_version_number.c
  
  include ../config/Makefile.version
  
  ${DESTDIR}${afssrvlibexecdir}/fileserver: fileserver
  	${INSTALL} -ns $? $@
  
! dest: ${DEST}/root.server/usr/afs/bin/fileserver
  
--- 190,222 ----
  afsint.xdr.o: ${FSINT}/afsint.xdr.c
  	${CCRULE}
  
+ state_analyzer.o: state_analyzer.c
+ 	${CCRULE}
+ 
  fileserver: ${objects} ${LIBS}
  	${CC} ${LDFLAGS} -o fileserver ${objects} ${LIBS} ${MT_LIBS} ${XLIBS}
  
+ state_analyzer: ${SDBGOBJS}
+ 	${CC} ${LDFLAGS} -o state_analyzer ${SDBGOBJS} ${MT_LIBS} ${XLIBS}
+ 
  ${DEST}/root.server/usr/afs/bin/fileserver: fileserver
  	${INSTALL} -ns $? $@
  
! ${DEST}/root.server/usr/afs/bin/state_analyzer: state_analyzer
! 	${INSTALL} $? $@
! 
! install: ${DESTDIR}${afssrvlibexecdir}/fileserver ${DESTDIR}${afssrvsbindir}/state_analyzer
  
  clean:
! 	$(RM) -f *.o fileserver state_analyzer core AFS_component_version_number.c
  
  include ../config/Makefile.version
  
  ${DESTDIR}${afssrvlibexecdir}/fileserver: fileserver
  	${INSTALL} -ns $? $@
  
! ${DESTDIR}${afssrvsbindir}/state_analyzer: state_analyzer
! 	${INSTALL} $? $@
! 
! dest: ${DEST}/root.server/usr/afs/bin/fileserver ${DEST}/root.server/usr/afs/bin/state_analyzer
  
Index: openafs/src/tviced/NTMakefile
diff -c openafs/src/tviced/NTMakefile:1.8 openafs/src/tviced/NTMakefile:1.10
*** openafs/src/tviced/NTMakefile:1.8	Sun Nov 20 20:57:30 2005
--- openafs/src/tviced/NTMakefile	Mon Mar 20 12:29:56 2006
***************
*** 5,11 ****
  # License.  For details, see the LICENSE file in the top-level source
  # directory or online at http://www.openafs.org/dl/license10.html
  
! AFSDEV_AUXCDEFINES = -DAFS_PTHREAD_ENV -DRXDEBUG
  
  RELDIR=tviced
  !INCLUDE ..\config\NTMakefile.$(SYS_NAME)
--- 5,11 ----
  # License.  For details, see the LICENSE file in the top-level source
  # directory or online at http://www.openafs.org/dl/license10.html
  
! AFSDEV_AUXCDEFINES = -DAFS_PTHREAD_ENV -DRXDEBUG -DFSSYNC_BUILD_SERVER
  
  RELDIR=tviced
  !INCLUDE ..\config\NTMakefile.$(SYS_NAME)
***************
*** 44,51 ****
  
  DIROBJS = $(OUT)\buffer.obj $(OUT)\dir.obj $(OUT)\salvage.obj
  
! VOLOBJS = $(OUT)\vnode.obj $(OUT)\volume.obj $(OUT)\vutil.obj $(OUT)\partition.obj $(OUT)\fssync.obj $(OUT)\purge.obj \
! 	  $(OUT)\clone.obj $(OUT)\common.obj $(OUT)\ihandle.obj $(OUT)\ntops.obj
  
  FSINTOBJS = $(OUT)\afsaux.obj $(OUT)\afscbint.cs.obj $(OUT)\afsint.ss.obj $(OUT)\afsint.xdr.obj
  
--- 44,52 ----
  
  DIROBJS = $(OUT)\buffer.obj $(OUT)\dir.obj $(OUT)\salvage.obj
  
! VOLOBJS = $(OUT)\vnode.obj $(OUT)\volume.obj $(OUT)\vutil.obj $(OUT)\partition.obj \
! 	  $(OUT)\clone.obj $(OUT)\common.obj $(OUT)\ihandle.obj $(OUT)\ntops.obj \
! 	  $(OUT)\fssync-server.obj $(OUT)\fssync-client.obj $(OUT)\daemon_com.obj
  
  FSINTOBJS = $(OUT)\afsaux.obj $(OUT)\afscbint.cs.obj $(OUT)\afsint.ss.obj $(OUT)\afsint.xdr.obj
  
Index: openafs/src/tviced/serialize_state.c
diff -c /dev/null openafs/src/tviced/serialize_state.c:1.1
*** /dev/null	Thu Apr 27 12:42:31 2006
--- openafs/src/tviced/serialize_state.c	Fri Mar 17 23:20:14 2006
***************
*** 0 ****
--- 1,1120 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  * demand attach fs
+  * fileserver state serialization
+  */
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/tviced/serialize_state.c,v 1.1 2006/03/18 04:20:14 shadow Exp $");
+ 
+ #include &lt;stdio.h&gt;
+ #include &lt;stdlib.h&gt;		/* for malloc() */
+ #include &lt;time.h&gt;		/* ANSI standard location for time stuff */
+ #ifdef AFS_NT40_ENV
+ #include &lt;fcntl.h&gt;
+ #include &lt;io.h&gt;
+ #else
+ #include &lt;sys/time.h&gt;
+ #include &lt;sys/file.h&gt;
+ #endif
+ #ifdef HAVE_STRING_H
+ #include &lt;string.h&gt;
+ #else
+ #ifdef HAVE_STRINGS_H
+ #include &lt;strings.h&gt;
+ #endif
+ #endif
+ #include &lt;afs/assert.h&gt;
+ #include &lt;sys/stat.h&gt;
+ 
+ #include &lt;afs/stds.h&gt;
+ 
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;lwp.h&gt;
+ #include &lt;lock.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include &lt;afs/rxgen_consts.h&gt;
+ #include &lt;afs/nfs.h&gt;
+ #include &lt;afs/errors.h&gt;
+ #include &lt;afs/ihandle.h&gt;
+ #include &lt;afs/vnode.h&gt;
+ #include &lt;afs/volume.h&gt;
+ #include &lt;afs/acl.h&gt;
+ #include &lt;afs/ptclient.h&gt;
+ #include &lt;afs/prs_fs.h&gt;
+ #include &lt;afs/auth.h&gt;
+ #include &lt;afs/afsutil.h&gt;
+ #include &lt;rx/rx.h&gt;
+ #include &lt;afs/cellconfig.h&gt;
+ #include &lt;stdlib.h&gt;
+ 
+ #include "../viced/viced_prototypes.h"
+ #include "../viced/viced.h"
+ #include "../viced/host.h"
+ #include "../viced/callback.h"
+ #include "serialize_state.h"
+ 
+ /*@+fcnmacros +macrofcndecl@*/
+ #ifdef O_LARGEFILE
+ #ifdef S_SPLINT_S
+ extern off64_t afs_lseek(int FD, off64_t O, int F);
+ #endif /*S_SPLINT_S */
+ #define afs_lseek(FD, O, F)	lseek64(FD, (off64_t)(O), F)
+ #define afs_stat		stat64
+ #define afs_fstat		fstat64
+ #define afs_open		open64
+ #define afs_fopen		fopen64
+ #define afs_ftruncate           ftruncate64
+ #define afs_mmap                mmap64
+ #ifdef AFS_AIX_ENV
+ extern void * mmap64();  /* ugly hack since aix build env appears to be somewhat broken */
+ #endif
+ #else /* !O_LARGEFILE */
+ #ifdef S_SPLINT_S
+ extern off_t afs_lseek(int FD, off_t O, int F);
+ #endif /*S_SPLINT_S */
+ #define afs_lseek(FD, O, F)	lseek(FD, (off_t)(O), F)
+ #define afs_stat		stat
+ #define afs_fstat		fstat
+ #define afs_open		open
+ #define afs_fopen		fopen
+ #define afs_ftruncate           ftruncate
+ #define afs_mmap                mmap
+ #endif /* !O_LARGEFILE */
+ /*@=fcnmacros =macrofcndecl@*/
+ 
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 
+ /*
+  * demand attach fs
+  * state dump routines
+  *
+  * in order to make state dump/restore as fast as possible,
+  * we use memory mapped files
+  *
+  * if this causes problems on certain platforms, the APIs
+  * have been written so that it will be very simple to go
+  * back to standard I/O for just those poorly written platforms
+  */
+ #define FS_STATE_USE_MMAP
+ 
+ 
+ #ifdef FS_STATE_USE_MMAP
+ #define FS_STATE_INIT_FILESIZE (8 * 1024 * 1024)  /* truncate to 8MB initially */
+ #include &lt;sys/mman.h&gt;
+ #endif
+ 
+ static int fs_stateCreateDump(struct fs_dump_state * state);
+ static int fs_stateLoadDump(struct fs_dump_state * state);
+ static int fs_stateInvalidateDump(struct fs_dump_state * state);
+ static int fs_stateCommitDump(struct fs_dump_state * state);
+ static int fs_stateCloseDump(struct fs_dump_state * state);
+ 
+ #ifdef FS_STATE_USE_MMAP
+ static int fs_stateSizeFile(struct fs_dump_state * state);
+ static int fs_stateResizeFile(struct fs_dump_state * state, size_t min_add);
+ static int fs_stateTruncateFile(struct fs_dump_state * state);
+ 
+ static int fs_stateMapFile(struct fs_dump_state * state);
+ static int fs_stateUnmapFile(struct fs_dump_state * state);
+ 
+ static int fs_stateIncCursor(struct fs_dump_state * state, size_t len);
+ static int fs_stateCheckIOSafety(struct fs_dump_state * state,
+ 				 size_t len);
+ #endif
+ 
+ static int fs_stateFillHeader(struct fs_state_header * hdr);
+ static int fs_stateCheckHeader(struct fs_state_header * hdr);
+ 
+ static int fs_stateAlloc(struct fs_dump_state * state);
+ static int fs_stateFree(struct fs_dump_state * state);
+ 
+ extern afsUUID FS_HostUUID;
+ extern char cml_version_number[];
+ 
+ /*
+  * demand attach fs
+  * save all fileserver state 
+  */
+ int
+ fs_stateSave(void)
+ {
+     int ret = 0, verified = 1;
+     struct fs_dump_state state;
+ 
+     /* save and restore need to be atomic wrt other host package operations */
+     H_LOCK; 
+ 
+     ViceLog(0, ("fs_stateSave: commencing fileserver state dump\n"));
+ 
+     if (fs_stateAlloc(&amp;state)) {
+ 	ViceLog(0, ("fs_stateSave: memory allocation failed; dump aborted\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     /* XXX
+      * on busy servers, these checks will inevitably fail since stuff drops H_LOCK
+      * all over the place (with structs left in inconsistent states) while RPCs to
+      * clients happen (grumble, grumble, the host package needs to be rewritten...)
+      *
+      * the current hack is to force the background threads that deal with host and
+      * callback state offline early in the shutdown process, do VShutdown, come
+      * back and wait for those threads to die, THEN do the state dump
+      *
+      * BUT, this still has one flaw -- what do we do about rx worker threads that
+      * are blocked in the host package making an RPC call to a cm???
+      *
+      * perhaps we need a refcounter that keeps track of threads blocked in rpc calls
+      * with H_LOCK dropped (and the host struct likely left in an inconsistent state)
+      *
+      * or better yet, we need to associate a state machine with each host object
+      * (kind of like demand attach Volume structures).
+      *
+      * sigh. I suspect we'll need to revisit this issue
+      */
+ 
+     if (fs_state.options.fs_state_verify_before_save) {
+ 	ViceLog(0, ("fs_stateSave: performing internal consistency checks before proceeding with state dump\n"));
+ 
+ 	if (h_stateVerify(&amp;state)) {
+ 	    ViceLog(0, ("fs_stateSave: error: host table consistency checks failed; state dump will not be marked clean\n"));
+ 	    verified = 0;
+ 	    ret = 1;
+ 	}
+ 
+ 	if (cb_stateVerify(&amp;state)) {
+ 	    ViceLog(0, ("fs_stateSave: error: callback table consistency checks failed; state dump will not be marked clean\n"));
+ 	    verified = 0;
+ 	    ret = 1;
+ 	}
+ 
+ 	/* if a consistency check asserted the bail flag, reset it */
+ 	state.bail = 0;
+ 
+ 	ViceLog(0, ("fs_stateSave: proceeding with dump\n"));
+     }
+ 
+     if (fs_stateCreateDump(&amp;state)) {
+ 	ViceLog(0, ("fs_stateSave: error: dump create failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (h_stateSave(&amp;state)) {
+ 	ViceLog(0, ("fs_stateSave: error: host state dump failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (cb_stateSave(&amp;state)) {
+ 	ViceLog(0, ("fs_stateSave: error: callback state dump failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (!verified) {
+ 	state.bail = 1;
+     }
+ 
+     if (fs_stateCommitDump(&amp;state)) {
+ 	ViceLog(0, ("fs_stateSave: error: dump commit failed\n"));
+ 	ret = 1; 
+ 	goto done;
+     }
+ 
+     if (verified) {
+ 	ViceLog(0, ("fs_stateSave: fileserver state dump completed successfully\n"));
+     } else {
+ 	ViceLog(0, ("fs_stateSave: fileserver state dump completed, but not marked clean.\n"));
+ 	ViceLog(0, ("fs_stateSave: please save a copy of '%s' for use by technical support\n",
+ 		    state.fn));
+     }
+ 
+  done:
+     if (state.fd &gt;= 0)
+ 	fs_stateCloseDump(&amp;state);
+     fs_stateFree(&amp;state);
+     H_UNLOCK;
+     return ret;
+ }
+ 
+ /*
+  * demand attach fs
+  * restore all fileserver state
+  *
+  * this function must appear as one atomic operation to the host and callback
+  * packages, hence H_LOCK is held for the entirety of the process.
+  */
+ int
+ fs_stateRestore(void)
+ {
+     int ret = 0;
+     struct fs_dump_state state;
+ 
+     /* save and restore need to be atomic wrt other host package operations */
+     H_LOCK;
+ 
+     ViceLog(0, ("fs_stateRestore: commencing fileserver state restore\n"));
+ 
+     if (fs_stateAlloc(&amp;state)) {
+ 	ViceLog(0, ("fs_stateRestore: memory allocation failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateLoadDump(&amp;state)) {
+ 	ViceLog(0, ("fs_stateRestore: failed to load dump file '%s'\n", state.fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateInvalidateDump(&amp;state)) {
+ 	ViceLog(0, ("fs_stateRestore: failed to invalidate dump file '%s'\n", state.fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+ 
+     if (state.flags.do_host_restore) {
+ 	if (h_stateRestore(&amp;state)) {
+ 	    ViceLog(0, ("fs_stateRestore: error: host state restore failed. exiting avoid further corruption\n"));
+ 	    exit(0);
+ 	}
+ 	ViceLog(0, ("fs_stateRestore: host table restored\n"));
+ 
+ 	if (cb_stateRestore(&amp;state)) {
+ 	    ViceLog(0, ("fs_stateRestore: error: callback state restore failed. exiting to avoid further corruption\n"));
+ 	    exit(0);
+ 	}
+ 	ViceLog(0, ("fs_stateRestore: FileEntry and CallBack tables restored\n"));
+ 
+ 	if (h_stateRestoreIndices(&amp;state)) {
+ 	    ViceLog(0, ("fs_stateRestore: error: host index remapping failed. exiting to avoid further corruption\n"));
+ 	    exit(0);
+ 	}
+ 	ViceLog(0, ("fs_stateRestore: host table indices remapped\n"));
+ 
+ 	if (cb_stateRestoreIndices(&amp;state)) {
+ 	    ViceLog(0, ("fs_stateRestore: error: callback index remapping failed. exiting to avoid further corruption\n"));
+ 	    exit(0);
+ 	}
+ 	ViceLog(0, ("fs_stateRestore: FileEntry and CallBack indices remapped\n"));
+     }
+ 
+     ViceLog(0, ("fs_stateRestore: restore phase complete\n"));
+ 
+     if (fs_state.options.fs_state_verify_after_restore) {
+ 	ViceLog(0, ("fs_stateRestore: beginning state verification phase\n"));
+ 
+ 	if (state.flags.do_host_restore) {
+ 	    if (h_stateVerify(&amp;state)) {
+ 		ViceLog(0, ("fs_stateRestore: error: host table consistency checks failed; exiting to avoid further corruption\n"));
+ 		exit(0);
+ 	    }
+ 
+ 	    if (cb_stateVerify(&amp;state)) {
+ 		ViceLog(0, ("fs_stateRestore: error: callback table consistency checks failed; exiting to avoid further corruption\n"));
+ 		exit(0);
+ 	    }
+ 	}
+ 
+ 	ViceLog(0, ("fs_stateRestore: fileserver state verification complete\n"));
+     }
+ 
+     ViceLog(0, ("fs_stateRestore: restore was successful\n"));
+ 
+  done:
+     if (state.fd &gt;= 0) {
+ 	fs_stateInvalidateDump(&amp;state);
+ 	fs_stateCloseDump(&amp;state);
+     }
+     fs_stateFree(&amp;state);
+     H_UNLOCK;
+     return ret;
+ }
+ 
+ static int
+ fs_stateCreateDump(struct fs_dump_state * state)
+ {
+     int fd, ret = 0;
+     char savedump[MAXPATHLEN];
+     struct afs_stat status;
+ 
+     afs_snprintf(savedump, sizeof(savedump), "%s.old", state-&gt;fn);
+ 
+     if (afs_stat(state-&gt;fn, &amp;status) == 0) {
+ 	renamefile(state-&gt;fn, savedump);
+     }
+ 
+     if (((fd = afs_open(state-&gt;fn, 
+ 			O_RDWR | O_CREAT | O_TRUNC, 
+ 			S_IRUSR | S_IWUSR)) == -1) ||
+ 	(afs_fstat(fd, &amp;status) == -1)) {
+ 	ViceLog(0, ("fs_stateCreateDump: failed to create state dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     state-&gt;fd = fd;
+     state-&gt;mode = FS_STATE_DUMP_MODE;
+     memset(state-&gt;hdr, 0, sizeof(struct fs_state_header));
+     fs_stateIncEOF(state, sizeof(struct fs_state_header));
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (fs_stateSizeFile(state)) {
+ 	ViceLog(0, ("fs_stateCreateDump: failed to resize state dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateMapFile(state)) {
+ 	ViceLog(0, ("fs_stateCreateDump: failed to memory map state dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ #endif
+ 
+     ret = fs_stateInvalidateDump(state);
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ fs_stateInvalidateDump(struct fs_dump_state * state)
+ {
+     afs_uint64 z;
+     int ret = 0;
+     struct fs_state_header hdr;
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (state-&gt;mmap.map == NULL) {
+ 	return 1;
+     }
+ #endif
+ 
+     memcpy(&amp;hdr, state-&gt;hdr, sizeof(hdr));
+     hdr.valid = 0;
+     ZeroInt64(z);
+ 
+     /* write a bogus header to flag dump in progress */
+     if (fs_stateWriteHeader(state, &amp;z, &amp;hdr, sizeof(hdr))) {
+ 	ViceLog(0, ("fs_stateInvalidateDump: failed to invalidate old dump file header '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+     if (fs_stateSync(state)) {
+ 	ViceLog(0, ("fs_stateInvalidateDump: failed to sync changes to disk\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ fs_stateCommitDump(struct fs_dump_state * state)
+ {
+     afs_uint64 z;
+     int ret = 0;
+ 
+     ZeroInt64(z);
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (fs_stateTruncateFile(state)) {
+ 	ViceLog(0, ("fs_stateCommitDump: failed to truncate dump file to proper size\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ #endif
+ 
+     /* ensure that all pending data I/Os for the state file have been committed 
+      * _before_ we make the metadata I/Os */
+     if (fs_stateSync(state)) {
+ 	ViceLog(0, ("fs_stateCommitDump: failed to sync changes to disk\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+ #ifdef FS_STATE_USE_MMAP
+     /* XXX madvise may not exist on all platforms, so
+      * we may need to add some ifdefs at some point... */
+     {
+ 	madvise((((char *)state-&gt;mmap.map) + sizeof(struct fs_state_header)), 
+ 		state-&gt;mmap.size - sizeof(struct fs_state_header), 
+ 		MADV_DONTNEED);
+     }
+ #endif
+ 
+     /* build the header, and write it to disk */
+     fs_stateFillHeader(state-&gt;hdr);
+     if (state-&gt;bail) {
+ 	state-&gt;hdr-&gt;valid = 0;
+     }
+     if (fs_stateWriteHeader(state, &amp;z, state-&gt;hdr, sizeof(struct fs_state_header))) {
+ 	ViceLog(0, ("fs_stateCommitDump: failed to write header to dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+     if (fs_stateSync(state)) {
+ 	ViceLog(0, ("fs_stateCommitDump: failed to sync new header to disk\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ fs_stateLoadDump(struct fs_dump_state * state)
+ {
+     afs_uint64 z;
+     int fd, ret = 0;
+     struct afs_stat status;
+     afs_int32 now = FT_ApproxTime();
+ 
+     ZeroInt64(z);
+ 
+     if ((fd = afs_open(state-&gt;fn, O_RDWR)) == -1 ||
+ 	(afs_fstat(fd, &amp;status) == -1)) {
+ 	ViceLog(0, ("fs_stateLoadDump: failed to load state dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+     state-&gt;fd = fd;
+     state-&gt;mode = FS_STATE_LOAD_MODE;
+     state-&gt;file_len = status.st_size;
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (fs_stateMapFile(state)) {
+ 	ViceLog(0, ("fs_stateLoadDump: failed to memory map state dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ #endif
+ 
+     if (fs_stateReadHeader(state, &amp;z, state-&gt;hdr, sizeof(struct fs_state_header))) {
+ 	ViceLog(0, ("fs_stateLoadDump: failed to read header from dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     /* check the validity of the header */
+     if (fs_stateCheckHeader(state-&gt;hdr)) {
+ 	ViceLog(1, ("fs_stateLoadDump: header failed validity checks; not restoring '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if ((state-&gt;hdr-&gt;timestamp + HOST_STATE_VALID_WINDOW) &gt;= now) {
+ 	state-&gt;flags.do_host_restore = 1;
+     } else {
+ 	ViceLog(0, ("fs_stateLoadDump: warning: dump is too old for host and callback restore; skipping those steps\n"));
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ fs_stateCloseDump(struct fs_dump_state * state)
+ {
+ #ifdef FS_STATE_USE_MMAP
+     fs_stateUnmapFile(state);
+ #endif
+     close(state-&gt;fd);
+     return 0;
+ }
+ 
+ int
+ fs_stateWrite(struct fs_dump_state * state,
+ 	      void * buf, size_t len)
+ {
+     int ret = 0;
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (fs_stateCheckIOSafety(state, len)) {
+ 	if (fs_stateResizeFile(state, len)) {
+ 	    ViceLog(0, ("fs_stateWrite: could not resize dump file '%s'\n",
+ 			state-&gt;fn));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     }
+ 	    
+     memcpy(state-&gt;mmap.cursor, buf, len);
+     fs_stateIncCursor(state, len);
+ #else
+     if (write(state-&gt;fd, buf, len) != len) {
+ 	ViceLog(0, ("fs_stateWrite: write failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ #endif
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ fs_stateRead(struct fs_dump_state * state,
+ 	     void * buf, size_t len)
+ {
+     int ret = 0;
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (fs_stateCheckIOSafety(state, len)) {
+ 	ViceLog(0, ("fs_stateRead: read beyond EOF for dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     memcpy(buf, state-&gt;mmap.cursor, len);
+     fs_stateIncCursor(state, len);
+ #else
+     if (read(state-&gt;fd, buf, len) != len) {
+ 	ViceLog(0, ("fs_stateRead: read failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ #endif
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ fs_stateWriteV(struct fs_dump_state * state,
+ 	       struct iovec * iov, int niov)
+ {
+     int i, ret = 0;
+     size_t len = 0;
+ 
+     for (i=0; i &lt; niov; i++) {
+ 	len += iov[i].iov_len;
+     }
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (fs_stateCheckIOSafety(state, len)) {
+ 	if (fs_stateResizeFile(state, len)) {
+ 	    ViceLog(0, ("fs_stateWrite: could not resize dump file '%s'\n",
+ 			state-&gt;fn));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     }
+ 
+     for (i=0; i &lt; niov; i++) {
+ 	memcpy(state-&gt;mmap.cursor, iov[i].iov_base, iov[i].iov_len);
+ 	fs_stateIncCursor(state, iov[i].iov_len);
+     }
+ #else
+     if (writev(state-&gt;fd, iov, niov) != len) {
+ 	ViceLog(0, ("fs_stateWriteV: write failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ #endif
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ fs_stateReadV(struct fs_dump_state * state,
+ 	      struct iovec * iov, int niov)
+ {
+     int i, ret = 0;
+     size_t len = 0;
+ 
+     for (i=0; i &lt; niov; i++) {
+ 	len += iov[i].iov_len;
+     }
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (fs_stateCheckIOSafety(state, len)) {
+ 	ViceLog(0, ("fs_stateRead: read beyond EOF for dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     for (i=0; i &lt; niov; i++) {
+ 	memcpy(iov[i].iov_base, state-&gt;mmap.cursor, iov[i].iov_len);
+ 	fs_stateIncCursor(state, iov[i].iov_len);
+     }
+ #else
+     if (readv(state-&gt;fd, iov, niov) != len) {
+ 	ViceLog(0, ("fs_stateReadV: read failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ #endif
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ fs_stateWriteHeader(struct fs_dump_state * state,
+ 		    afs_uint64 * offset,
+ 		    void * hdr, size_t len)
+ {
+     int ret = 0;
+ 
+     if (fs_stateSeek(state, offset)) {
+ 	ViceLog(0, ("fs_stateWriteHeader: could not seek to correct position in dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateWrite(state, hdr, len)) {
+ 	ViceLog(0, ("fs_stateWriteHeader: write failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ fs_stateReadHeader(struct fs_dump_state * state,
+ 		   afs_uint64 * offset,
+ 		   void * hdr, size_t len)
+ {
+     int ret = 0;
+ 
+     if (fs_stateSeek(state, offset)) {
+ 	ViceLog(0, ("fs_stateReadHeader: could not seek to correct position in dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateRead(state, hdr,len)) {
+ 	ViceLog(0, ("fs_stateReadHeader: read failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ #ifdef FS_STATE_USE_MMAP
+ static int
+ fs_stateSizeFile(struct fs_dump_state * state)
+ {
+     int ret = 0;
+     state-&gt;file_len = FS_STATE_INIT_FILESIZE;
+     if (afs_ftruncate(state-&gt;fd, state-&gt;file_len) != 0)
+ 	ret = 1;
+     return ret;
+ }
+ 
+ static int
+ fs_stateResizeFile(struct fs_dump_state * state, size_t min_add)
+ {
+     int ret = 0;
+     afs_foff_t inc;
+ 
+ #ifdef FS_STATE_USE_MMAP
+     fs_stateUnmapFile(state);
+ #endif
+ 
+     inc = ((min_add / FS_STATE_INIT_FILESIZE)+1) * FS_STATE_INIT_FILESIZE;
+     state-&gt;file_len += inc;
+ 
+     if (afs_ftruncate(state-&gt;fd, state-&gt;file_len) != 0) {
+ 	ViceLog(0, ("fs_stateResizeFile: truncate failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+ #ifdef FS_STATE_USE_MMAP
+     if (fs_stateMapFile(state)) {
+ 	ViceLog(0, ("fs_stateResizeFile: remapping memory mapped file failed\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ #endif
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ fs_stateTruncateFile(struct fs_dump_state * state)
+ {
+     int ret = 0;
+ 
+ #ifdef AFS_LARGEFILE_ENV
+     if (afs_ftruncate(state-&gt;fd, state-&gt;eof_offset) != 0) {
+ 	ret = 1;
+     }
+ #else
+     afs_uint32 hi, lo;
+     SplitInt64(state-&gt;eof_offset, hi, lo);
+     if (afs_ftruncate(state-&gt;fd, lo) != 0) {
+ 	ret = 1;
+     }
+ #endif
+ 
+     return ret;
+ }
+ #endif
+ 
+ #ifdef FS_STATE_USE_MMAP
+ static int
+ fs_stateMapFile(struct fs_dump_state * state)
+ {
+     int ret = 0, flags;
+ 
+     switch(state-&gt;mode) {
+     case FS_STATE_LOAD_MODE:
+ 	flags = PROT_READ | PROT_WRITE;   /* loading involves a header invalidation */
+ 	break;
+     case FS_STATE_DUMP_MODE:
+ 	flags = PROT_WRITE;
+ 	break;
+     default:
+ 	ViceLog(0, ("fs_stateMapFile: invalid dump state mode\n"));
+ 	return 1;
+     }
+ 
+     state-&gt;mmap.map = afs_mmap(NULL, 
+ 			       state-&gt;file_len, 
+ 			       flags, 
+ 			       MAP_SHARED,
+ 			       state-&gt;fd, 
+ 			       0);
+ 
+     if (state-&gt;mmap.map == MAP_FAILED) {
+ 	state-&gt;mmap.size = 0;
+ 	state-&gt;mmap.map = NULL;
+ 	ViceLog(0, ("fs_stateMapFile: failed to memory map file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     state-&gt;mmap.size = state-&gt;file_len;
+     state-&gt;mmap.cursor = state-&gt;mmap.map;
+     state-&gt;mmap.offset = 0;
+ 
+     /* for state loading, accesses will be sequential, so let's give
+      * the VM subsystem a heads up */
+     if (state-&gt;mode == FS_STATE_LOAD_MODE) {
+ 	/* XXX madvise may not exist on all platforms, so
+ 	 * we may need to add some ifdefs at some point... */
+ 	flags = MADV_SEQUENTIAL | MADV_WILLNEED;
+ #ifdef AFS_SUN510_ENV
+ 	flags |= MADV_ACCESS_LWP;   /* added in solaris 9 12/02 */
+ #endif
+ 	madvise(state-&gt;mmap.map, state-&gt;mmap.size, flags);
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ fs_stateUnmapFile(struct fs_dump_state * state)
+ {
+     int ret = 0;
+ 
+     if (munmap(state-&gt;mmap.map, state-&gt;mmap.size) == -1) {
+ 	ViceLog(0, ("fs_stateUnmapFile: failed to unmap dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+  done:
+     return ret;
+ }
+ #endif /* FS_STATE_USE_MMAP */
+ 
+ #ifdef FS_STATE_USE_MMAP
+ int
+ fs_stateSync(struct fs_dump_state * state)
+ {
+     int ret = 0;
+ 
+     msync(state-&gt;mmap.map, state-&gt;mmap.size, MS_SYNC);
+ 
+  done:
+     return ret;
+ }
+ #else /* !FS_STATE_USE_MMAP */
+ int
+ fs_stateSync(struct fs_dump_state * state)
+ {
+     int ret = 0;
+ 
+     if (fsync(state-&gt;fd) == -1)
+ 	ret = 1;
+ 
+  done:
+     return ret;
+ }
+ #endif /* !FS_STATE_USE_MMAP */
+ 
+ int
+ fs_stateIncEOF(struct fs_dump_state * state, afs_int32 len)
+ {
+     afs_uint64 temp;
+     FillInt64(temp, 0, len);
+     AddUInt64(state-&gt;eof_offset, temp, &amp;state-&gt;eof_offset);
+     return 0;
+ }
+ 
+ #ifdef FS_STATE_USE_MMAP
+ static int
+ fs_stateIncCursor(struct fs_dump_state * state, size_t len)
+ {
+     char * p;
+ 
+     state-&gt;mmap.offset += len;
+ 
+     p = (char *) state-&gt;mmap.cursor;
+     p += len;
+     state-&gt;mmap.cursor = (void *) p;
+ 
+     return 0;
+ }
+ 
+ static int
+ fs_stateCheckIOSafety(struct fs_dump_state * state, size_t len)
+ {
+     int ret = 0;
+ 
+     if ((state-&gt;mmap.offset + len) &gt; state-&gt;mmap.size) {
+ 	ret = 1;
+     }
+     return ret;
+ }
+ #endif /* FS_STATE_USE_MMAP */
+ 
+ #ifdef FS_STATE_USE_MMAP
+ int
+ fs_stateSeek(struct fs_dump_state * state, afs_uint64 * offset)
+ {
+     int ret = 0;
+     char * p;
+     afs_uint32 hi, lo;
+ 
+     SplitInt64(*offset, hi, lo);
+ 
+     /* update cursor */
+     p = (char *) state-&gt;mmap.map;
+ #ifdef AFS_64BIT_ENV
+     p += *offset;
+ #else
+     p += lo;
+ #endif
+     state-&gt;mmap.cursor = (void *) p;
+ 
+     /* update offset */
+ #ifdef AFS_LARGEFILE_ENV
+     state-&gt;mmap.offset = *offset;
+ #else
+     if (hi)
+ 	ret = 1;
+     state-&gt;mmap.offset = lo;
+ #endif
+ 
+     return ret;
+ }
+ #else /* !FS_STATE_USE_MMAP */
+ int
+ fs_stateSeek(struct fs_dump_state * state, afs_uint64 * offset)
+ {
+     int ret = 0;
+ #ifndef AFS_LARGEFILE_ENV
+     afs_uint32 high, low;
+     
+     SplitInt64(*offset, high, low);
+     if (high) {
+ 	ret = 1;
+ 	goto done;
+     }
+     
+     if (afs_lseek(state-&gt;fd, low, SEEK_SET) == -1)
+ 	ret = 1;
+ #else
+     if (afs_lseek(state-&gt;fd, *offset, SEEK_SET) == -1)
+ 	ret = 1;
+ #endif
+     return ret;
+ }
+ #endif /* !FS_STATE_USE_MMAP */
+ 
+ static int
+ fs_stateFillHeader(struct fs_state_header * hdr)
+ {
+     hdr-&gt;stamp.magic = FS_STATE_MAGIC;
+     hdr-&gt;stamp.version = FS_STATE_VERSION;
+ #ifdef SYS_NAME_ID
+     hdr-&gt;sys_name = SYS_NAME_ID;
+ #else
+     hdr-&gt;sys_name = 0xFFFFFFFF;
+ #endif
+     hdr-&gt;timestamp = FT_ApproxTime();
+     hdr-&gt;server_uuid = FS_HostUUID;
+     hdr-&gt;valid = 1;
+ #ifdef AFSBIG_ENDIAN
+     hdr-&gt;endianness = 1;
+ #else
+     hdr-&gt;endianness = 0;
+ #endif
+ #ifdef FS_STATS_DETAILED
+     hdr-&gt;stats_detailed = 1;
+ #else
+     hdr-&gt;stats_detailed = 0;
+ #endif
+     if (strlcpy(hdr-&gt;server_version_string, cml_version_number, sizeof(hdr-&gt;server_version_string))
+ 	&gt;= sizeof(hdr-&gt;server_version_string)) {
+ 	ViceLog(0, ("fs_stateFillHeader: WARNING -- cml_version_number field truncated\n"));
+     }
+     return 0;
+ }
+ 
+ static int
+ fs_stateCheckHeader(struct fs_state_header * hdr)
+ {
+     int ret = 0;
+ 
+     if (!hdr-&gt;valid) {
+ 	ViceLog(0, ("fs_stateCheckHeader: dump was previously flagged invalid\n"));
+ 	ret = 1;
+     }
+ #ifdef AFSBIG_ENDIAN
+     else if (!hdr-&gt;endianness) {
+ 	ViceLog(0, ("fs_stateCheckHeader: wrong endianness\n"));
+ 	ret = 1;
+     }
+ #else /* AFSLITTLE_ENDIAN */
+     else if (hdr-&gt;endianness) {
+ 	ViceLog(0, ("fs_stateCheckHeader: wrong endianness\n"));
+ 	ret = 1;
+     }
+ #endif /* AFSLITTLE_ENDIAN */
+ 
+     else if (hdr-&gt;stamp.magic != FS_STATE_MAGIC) {
+ 	ViceLog(0, ("fs_stateCheckHeader: invalid dump header\n"));
+ 	ret = 1;
+     }
+     else if (hdr-&gt;stamp.version != FS_STATE_VERSION) {
+ 	ViceLog(0, ("fs_stateCheckHeader: unknown dump format version number\n"));
+ 	ret = 1;
+     }
+ 
+ #ifdef FS_STATS_DETAILED
+     else if (!hdr-&gt;stats_detailed) {
+ 	ViceLog(0, ("fs_stateCheckHeader: wrong config flags\n"));
+ 	ret = 1;
+     }
+ #else /* FS_STATS_DETAILED */
+     else if (hdr-&gt;stats_detailed) {
+ 	ViceLog(0, ("fs_stateCheckHeader: wrong config flags\n"));
+ 	ret = 1;
+     }
+ #endif /* FS_STATS_DETAILED */
+ 
+     else if (!afs_uuid_equal(&amp;hdr-&gt;server_uuid, &amp;FS_HostUUID)) {
+ 	ViceLog(0, ("fs_stateCheckHeader: server UUID does not match this server's UUID\n"));
+ 	ret = 1;
+     }
+ 
+     /* the cml_version_string is included for informational purposes only.  If someone ever
+      * wants to limit state dump reloading based upon the contents of this string, just
+      * uncomment the following code.  uncommenting this code is _strongly discouraged_ because
+      * we already make use of the version stamps in the various dump headers to deal with
+      * data structure version incompatabilities.
+     else if (strncmp(hdr-&gt;server_version_string, cml_version_number, 
+ 		     sizeof(hdr-&gt;server_version_string)) != 0) {
+ 	ViceLog(0, ("fs_stateCheckHeader: dump from different server version\n"));
+ 	ret = 1;
+     }
+     */
+ 
+     else if (strncmp(hdr-&gt;server_version_string, cml_version_number, 
+ 		     sizeof(hdr-&gt;server_version_string)) != 0) {
+ 	ViceLog(0, ("fs_stateCheckHeader: dump from different server version ; attempting state reload anyway\n"));
+     }
+ 
+ 
+     return ret;
+ }
+ 
+ static int
+ fs_stateAlloc(struct fs_dump_state * state)
+ {
+     int ret = 0;
+     memset(state, 0, sizeof(struct fs_dump_state));
+     state-&gt;fd = -1;
+     state-&gt;fn = AFSDIR_SERVER_FSSTATE_FILEPATH;
+     state-&gt;hdr = (struct fs_state_header *)malloc(sizeof(struct fs_state_header));
+     state-&gt;h_hdr = (struct host_state_header *)malloc(sizeof(struct host_state_header));
+     state-&gt;cb_hdr = (struct callback_state_header *)malloc(sizeof(struct callback_state_header));
+     state-&gt;cb_timeout_hdr = (struct callback_state_timeout_header *)
+       malloc(sizeof(struct callback_state_timeout_header));
+     state-&gt;cb_fehash_hdr = (struct callback_state_fehash_header *)
+       malloc(sizeof(struct callback_state_fehash_header));
+     if ((state-&gt;hdr == NULL) || (state-&gt;h_hdr == NULL) || (state-&gt;cb_hdr == NULL) ||
+ 	(state-&gt;cb_timeout_hdr == NULL) || (state-&gt;cb_fehash_hdr == NULL))
+ 	ret = 1;
+     return ret;
+ }
+ 
+ static int
+ fs_stateFree(struct fs_dump_state * state)
+ {
+     if (state-&gt;hdr)
+ 	free(state-&gt;hdr);
+     if (state-&gt;h_hdr)
+ 	free(state-&gt;h_hdr);
+     if (state-&gt;cb_hdr)
+ 	free(state-&gt;cb_hdr);
+     if (state-&gt;cb_timeout_hdr)
+ 	free(state-&gt;cb_timeout_hdr);
+     if (state-&gt;cb_fehash_hdr)
+ 	free(state-&gt;cb_fehash_hdr);
+     if (state-&gt;h_map.entries)
+ 	free(state-&gt;h_map.entries);
+     if (state-&gt;fe_map.entries)
+ 	free(state-&gt;fe_map.entries);
+     if (state-&gt;cb_map.entries)
+ 	free(state-&gt;cb_map.entries);
+     return 0;
+ }
+ 
+ #endif /* AFS_DEMAND_ATTACH_FS */
Index: openafs/src/tviced/serialize_state.h
diff -c /dev/null openafs/src/tviced/serialize_state.h:1.1
*** /dev/null	Thu Apr 27 12:42:31 2006
--- openafs/src/tviced/serialize_state.h	Fri Mar 17 23:20:15 2006
***************
*** 0 ****
--- 1,311 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  * demand attach fs
+  * fileserver state serialization
+  */
+ 
+ #ifndef _AFS_TVICED_SERIALIZE_STATE_H
+ #define _AFS_TVICED_SERIALIZE_STATE_H
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 
+ #define FS_STATE_MAGIC 0x62FA841C
+ #define FS_STATE_VERSION 2
+ 
+ #define HOST_STATE_MAGIC 0x7B8C9DAE
+ #define HOST_STATE_VERSION 2
+ 
+ #define HOST_STATE_ENTRY_MAGIC 0xA8B9CADB
+ 
+ #define CALLBACK_STATE_MAGIC 0x89DE67BC
+ #define CALLBACK_STATE_VERSION 1
+ 
+ #define CALLBACK_STATE_TIMEOUT_MAGIC 0x99DD5511
+ #define CALLBACK_STATE_FEHASH_MAGIC 0x77BB33FF
+ #define CALLBACK_STATE_ENTRY_MAGIC 0x54637281
+ 
+ #define ACTIVE_VOLUME_STATE_MAGIC 0xAC7557CA
+ #define ACTIVE_VOLUME_STATE_VERSION 1
+ 
+ #define ACTIVE_VOLUME_STATE_AVEHASH_MAGIC 0xBADDF00D
+ 
+ #define HOST_STATE_VALID_WINDOW 1800 /* 30 minutes */
+ 
+ /*
+  * on-disk structures
+  */
+ struct disk_version_stamp {
+     afs_uint32 magic;
+     afs_uint32 version;
+ };
+ 
+ /* 1024 byte header structure */
+ struct fs_state_header {
+     struct disk_version_stamp stamp;  /* version stamp */
+     afs_uint32 timestamp;             /* timestamp of save */
+     afs_uint32 sys_name;              /* sys name id for this machine */
+     afsUUID server_uuid;              /* server's UUID */
+     byte valid;                       /* whether header contents are valid */
+     byte endianness;                  /* endianness sanity check (0 for LE, 1 for BE) */
+     byte stats_detailed;              /* fs stats detailed sanity check */
+     byte padding1[1];                 /* padding */
+     afs_uint32 reserved1[23];         /* for expansion */
+     afs_uint64 avol_offset;           /* offset of active volumes structure */
+     afs_uint64 h_offset;              /* offset of host_state_header structure */
+     afs_uint64 cb_offset;             /* offset of callback_state_header structure */
+     afs_uint64 vlru_offset;           /* offset of vlru state structure */
+     afs_uint32 reserved2[56];         /* for expansion */
+     char server_version_string[128];  /* version string from AFS_component_version_number.c */
+     afs_uint32 reserved3[128];        /* for expansion */
+ };
+ 
+ /*
+  * host package serialization
+  */
+ 
+ /* 256 byte header for the host state data */
+ struct host_state_header {
+     struct disk_version_stamp stamp;  /* host state version stamp */
+     afs_uint32 records;               /* number of stored host records */
+     afs_uint32 index_max;             /* max index value encountered */
+     afs_uint32 reserved[60];          /* for expansion */
+ };
+ 
+ /* 32 byte host entry header */
+ struct host_state_entry_header {
+     afs_uint32 magic;         /* stamp */
+     afs_uint32 len;           /* number of bytes in this record */
+     afs_uint32 interfaces;    /* number of interfaces included in record */
+     afs_uint32 hcps;          /* number of hcps entries in record */
+     afs_uint32 reserved[4];
+ };
+ 
+ /* 36 byte host entry structure */
+ struct hostDiskEntry {
+     afs_uint32 host;		/* IP address of host interface that is
+ 				 * currently being used, in network
+ 				 * byte order */
+     afs_uint16 port;	        /* port address of host */
+     afs_uint16 hostFlags;       /*  bit map */
+     byte Console;		/* XXXX This host is a console */
+     byte hcpsfailed;	        /* Retry the cps call next time */
+     byte hcps_valid;            /* prlist_val not null */
+ #if FS_STATS_DETAILED
+     byte InSameNetwork;	        /*Is host's addr in the same network as
+ 				 * the File Server's? */
+ #else
+     byte padding1[1];	        /* for padding */
+ #endif				/* FS_STATS_DETAILED */
+     afs_uint32 hcps_len;        /* length of hcps */
+     afs_uint32 LastCall;	/* time of last call from host */
+     afs_uint32 ActiveCall;	/* time of any call but gettime */
+     afs_uint32 cpsCall;		/* time of last cps call from this host */
+     afs_uint32 cblist;		/* Call back list for this host */
+     afs_uint32 index;           /* index for correlating w/ callback dumps */
+ };
+ 
+ /*
+  * callback package serialization
+  */
+ 
+ /* 512 byte header */
+ struct callback_state_header {
+     struct disk_version_stamp stamp;    /* callback state version stamp */
+     afs_uint32 nFEs;                    /* number of FileEntry records */
+     afs_uint32 nCBs;                    /* number of CallBack records */
+     afs_uint32 fe_max;                  /* max FileEntry index */
+     afs_uint32 cb_max;                  /* max CallBack index */
+     afs_int32 tfirst;                   /* first valid timeout */
+     afs_uint32 reserved[115];           /* for expansion */
+     afs_uint64 timeout_offset;          /* offset of timeout queue heads */
+     afs_uint64 fehash_offset;           /* offset of file entry hash buckets */
+     afs_uint64 fe_offset;               /* offset of first file entry */
+ };
+ 
+ /* 32 byte header */
+ struct callback_state_timeout_header {
+     afs_uint32 magic;         /* magic number for timeout header */
+     afs_uint32 len;           /* total length of header and timeout records */
+     afs_uint32 records;       /* number of timeout records */
+     afs_uint32 reserved[5];
+ };
+ 
+ /* 32 byte header */
+ struct callback_state_fehash_header {
+     afs_uint32 magic;         /* magic number for fehash header */
+     afs_uint32 len;           /* total length of header and fehash bucket heads */
+     afs_uint32 records;       /* number of hash buckets */
+     afs_uint32 reserved[5];
+ };
+ 
+ /* 32 byte header */
+ struct callback_state_entry_header {
+     afs_uint32 magic;         /* magic number for FE entry */
+     afs_uint32 len;           /* number of bytes in this record */
+     afs_uint32 nCBs;          /* number of callbacks for this FE */
+     afs_uint32 reserved[5];
+ };
+ 
+ struct FEDiskEntry {
+     struct FileEntry fe;
+     afs_uint32 index;
+ };
+ 
+ struct CBDiskEntry {
+     struct CallBack cb;
+     afs_uint32 index;
+ };
+ 
+ /*
+  * active volumes state serialization
+  *
+  * these structures are meant to support
+  * automated salvaging of active volumes
+  * in the event of a fileserver crash
+  */
+ 
+ /* 512 byte header */
+ struct active_volume_state_header {
+     struct disk_version_stamp stamp;    /* callback state version stamp */
+     afs_uint32 nAVEs;                   /* number of ActiveVolumeEntry records */
+     afs_uint32 init_timestamp;          /* timestamp of AVE initialization */
+     afs_uint32 update_timetamp;         /* timestamp of last AVE update */
+     afs_uint32 reserved[119];           /* for expansion */
+     afs_uint64 avehash_offset;          /* offset of active volume entry hash buckets */
+     afs_uint64 ave_offset;              /* offset of first active volume entry */
+ };
+ 
+ /* 32 byte header */
+ struct active_volume_state_avehash_header {
+     afs_uint32 magic;         /* magic number for avehash header */
+     afs_uint32 len;           /* total length of header and avehash bucket heads */
+     afs_uint32 records;       /* number of hash buckets */
+     afs_uint32 reserved[5];
+ };
+ 
+ typedef afs_uint32 active_volume_state_avehash_entry;
+ 
+ /* active volume entry */
+ struct AVDiskEntry {
+     afs_uint32 volume;
+     afs_uint32 partition;
+     afs_uint32 hash_next;
+ };
+ 
+ 
+ /*
+  * dump runtime state
+  */
+ struct idx_map_entry_t {
+     afs_uint32 old_idx;                    /* host hash id from last runtime */
+     afs_uint32 new_idx;                    /* host hash id for this runtime */
+ };
+ 
+ 
+ /* verification process sanity check constants
+  *
+  * make them fairly large so we don't get 
+  * false positives 
+  */
+ #define FS_STATE_H_MAX_UUID_HASH_CHAIN_LEN    100000     /* max elements in a host uuid-hash chain */
+ #define FS_STATE_H_MAX_ADDR_HASH_CHAIN_LEN    2000000    /* max elements in a host ipv4-hash chain */
+ #define FS_STATE_FE_MAX_HASH_CHAIN_LEN        100000     /* max elements in a FE fid-hash chain */
+ #define FS_STATE_FCB_MAX_LIST_LEN             100000     /* max elements in a per-FE CB list */
+ #define FS_STATE_HCB_MAX_LIST_LEN             100000     /* max elements in a per-host CB list */
+ #define FS_STATE_TCB_MAX_LIST_LEN             100000     /* max elements in a per-timeout CB list */
+ 
+ 
+ /*
+  * main state serialization state structure
+  */
+ 
+ struct fs_dump_state {
+     enum {
+ 	FS_STATE_DUMP_MODE,
+ 	FS_STATE_LOAD_MODE
+     } mode;
+     struct {
+ 	byte do_host_restore;              /* whether host restore should be done */
+ 	byte some_steps_skipped;           /* whether some steps were skipped */
+ 	byte warnings_generated;           /* whether any warnings were generated during restore */
+     } flags;
+     afs_fsize_t file_len;
+     int fd;                                /* fd of the current dump file */
+     int bail;                              /* non-zero if something went wrong */
+     char * fn;                             /* name of the current dump file */
+     struct {                               /* memory map of dump file */
+ 	void * map;
+ 	void * cursor;
+ 	afs_foff_t offset;
+ 	afs_fsize_t size;
+     } mmap;
+     struct fs_state_header * hdr;          /* main header */
+     struct host_state_header * h_hdr;      /* header for host state data */
+     struct callback_state_header * cb_hdr; /* header for callback state data */
+     struct callback_state_timeout_header * cb_timeout_hdr;
+     struct callback_state_fehash_header * cb_fehash_hdr;
+     afs_uint64 eof_offset;                 /* current end of file offset */
+     struct {
+ 	int len;                           /* number of host entries in map */
+ 	struct idx_map_entry_t * entries;
+     } h_map;
+     struct {
+ 	int len;
+ 	struct idx_map_entry_t * entries;
+     } fe_map;
+     struct {
+ 	int len;
+ 	struct idx_map_entry_t * entries;
+     } cb_map;
+ };
+ 
+ 
+ /* prototypes */
+ 
+ /* serialize_state.c */
+ extern int fs_stateWrite(struct fs_dump_state * state,
+ 			 void * buf, size_t len);
+ extern int fs_stateRead(struct fs_dump_state * state,
+ 			void * buf, size_t len);
+ extern int fs_stateWriteV(struct fs_dump_state * state,
+ 			  struct iovec * iov, int niov);
+ extern int fs_stateReadV(struct fs_dump_state * state,
+ 			 struct iovec * iov, int niov);
+ extern int fs_stateSync(struct fs_dump_state * state);
+ extern int fs_stateWriteHeader(struct fs_dump_state * state,
+ 			       afs_uint64 * offset,
+ 			       void * hdr, size_t len);
+ extern int fs_stateReadHeader(struct fs_dump_state * state,
+ 			      afs_uint64 * offset,
+ 			      void * hdr, size_t len);
+ extern int fs_stateIncEOF(struct fs_dump_state * state,
+ 			  afs_int32 len);
+ extern int fs_stateSeek(struct fs_dump_state * state,
+ 			afs_uint64 * offset);
+ 
+ /* host.c */
+ extern int h_stateSave(struct fs_dump_state * state);
+ extern int h_stateRestore(struct fs_dump_state * state);
+ extern int h_stateRestoreIndices(struct fs_dump_state * state);
+ extern int h_stateVerify(struct fs_dump_state * state);
+ extern int h_OldToNew(struct fs_dump_state * state, afs_uint32 old, afs_uint32 * new);
+ 
+ /* callback.c */
+ extern int cb_stateSave(struct fs_dump_state * state);
+ extern int cb_stateRestore(struct fs_dump_state * state);
+ extern int cb_stateRestoreIndices(struct fs_dump_state * state);
+ extern int cb_stateVerify(struct fs_dump_state * state);
+ extern int cb_stateVerifyHCBList(struct fs_dump_state * state, struct host * host);
+ extern int fe_OldToNew(struct fs_dump_state * state, afs_uint32 old, afs_uint32 * new);
+ extern int cb_OldToNew(struct fs_dump_state * state, afs_uint32 old, afs_uint32 * new);
+ 
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ #endif /* _AFS_TVICED_SERIALIZE_STATE_H */
Index: openafs/src/tviced/state_analyzer.c
diff -c /dev/null openafs/src/tviced/state_analyzer.c:1.1
*** /dev/null	Thu Apr 27 12:42:31 2006
--- openafs/src/tviced/state_analyzer.c	Thu Mar 23 10:09:13 2006
***************
*** 0 ****
--- 1,2004 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  * demand attach fs
+  * fileserver state serialization
+  *
+  * state analyzer
+  */
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/tviced/state_analyzer.c,v 1.1 2006/03/23 15:09:13 shadow Exp $");
+ 
+ #include &lt;stdio.h&gt;
+ #include &lt;errno.h&gt;
+ #include &lt;sys/file.h&gt;
+ #include &lt;netdb.h&gt;
+ #include &lt;netinet/in.h&gt;
+ #include &lt;time.h&gt;
+ 
+ #ifdef HAVE_STRING_H
+ #include &lt;string.h&gt;
+ #else
+ #ifdef HAVE_STRINGS_H
+ #include &lt;strings.h&gt;
+ #endif
+ #endif
+ 
+ #include &lt;afs/stds.h&gt;
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/assert.h&gt;
+ #include &lt;lwp.h&gt;
+ #include &lt;lock.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include &lt;afs/rxgen_consts.h&gt;
+ #include &lt;afs/nfs.h&gt;
+ #include &lt;afs/errors.h&gt;
+ #include &lt;afs/ihandle.h&gt;
+ #include &lt;afs/vnode.h&gt;
+ #include &lt;afs/volume.h&gt;
+ #ifdef AFS_ATHENA_STDENV
+ #include &lt;krb.h&gt;
+ #endif
+ #include &lt;afs/acl.h&gt;
+ #include &lt;afs/ptclient.h&gt;
+ #include &lt;afs/prs_fs.h&gt;
+ #include &lt;afs/auth.h&gt;
+ #include &lt;afs/afsutil.h&gt;
+ #include &lt;rx/rx.h&gt;
+ #include &lt;afs/cellconfig.h&gt;
+ #include &lt;stdlib.h&gt;
+ #include "../util/afsutil_prototypes.h"
+ #include "../viced/viced.h"
+ #include "../viced/host.h"
+ #include "../viced/callback.h"
+ #include "serialize_state.h"
+ #include &lt;fcntl.h&gt;
+ #include &lt;sys/types.h&gt;
+ #include &lt;sys/stat.h&gt;
+ #include &lt;sys/mman.h&gt;
+ #include &lt;unistd.h&gt;
+ 
+ /*@+fcnmacros +macrofcndecl@*/
+ #ifdef O_LARGEFILE
+ #ifdef S_SPLINT_S
+ extern off64_t afs_lseek(int FD, off64_t O, int F);
+ #endif /*S_SPLINT_S */
+ #define afs_lseek(FD, O, F)	lseek64(FD, (off64_t)(O), F)
+ #define afs_stat		stat64
+ #define afs_fstat		fstat64
+ #define afs_open		open64
+ #define afs_fopen		fopen64
+ #define afs_mmap                mmap64
+ #ifdef AFS_AIX_ENV
+ extern void * mmap64();  /* ugly hack since aix build env appears to be somewhat broken */
+ #endif
+ #else /* !O_LARGEFILE */
+ #ifdef S_SPLINT_S
+ extern off_t afs_lseek(int FD, off_t O, int F);
+ #endif /*S_SPLINT_S */
+ #define afs_lseek(FD, O, F)	lseek(FD, (off_t)(O), F)
+ #define afs_stat		stat
+ #define afs_fstat		fstat
+ #define afs_open		open
+ #define afs_fopen		fopen
+ #define afs_mmap                mmap
+ #endif /* !O_LARGEFILE */
+ /*@=fcnmacros =macrofcndecl@*/
+ 
+ 
+ #ifndef AFS_DEMAND_ATTACH_FS
+ int
+ main (int argc, char ** argv)
+ {
+     fprintf(stderr, "%s is only supported for demand attach fileservers\n",
+ 	    argv[0] ? argv[0] : "state analyzer");
+     return 1;
+ }
+ #else /* AFS_DEMAND_ATTACH_FS */
+ 
+ static void usage(char * prog);
+ static int openFile(char * path);
+ static void initState(void);
+ 
+ static void banner(void);
+ static void prompt(void);
+ 
+ static void print_help(void);
+ static void print_global_help(void);
+ static void print_h_help(void);
+ static void print_fe_help(void);
+ static void print_cb_help(void);
+ 
+ static void dump_hdr(void);
+ static void dump_h_hdr(void);
+ static void dump_cb_hdr(void);
+ 
+ static void dump_cb_timeout(void);
+ static void dump_cb_fehash(void);
+ 
+ static void dump_all_hes(void);
+ static void dump_all_fes(void);
+ static void dump_all_cbs(void);
+ 
+ static void dump_he(afs_uint32 idx);
+ static void dump_fe(afs_uint32 idx);
+ static void dump_cb(afs_uint32 idx);
+ static void dump_this_he(void);
+ static void dump_this_fe(void);
+ static void dump_this_cb(void);
+ static void dump_next_he(void);
+ static void dump_next_fe(void);
+ static void dump_next_cb(void);
+ static void dump_prev_he(void);
+ static void dump_prev_fe(void);
+ static void dump_prev_cb(void);
+ static void dump_first_he(void);
+ static void dump_first_fe(void);
+ static void dump_first_cb(void);
+ static void dump_last_he(void);
+ static void dump_last_fe(void);
+ static void dump_last_cb(void);
+ static void dump_he_hdr(void);
+ static void dump_he_entry(void);
+ static void dump_he_interfaces(void);
+ static void dump_he_hcps(void);
+ static void dump_fe_hdr(void);
+ static void dump_fe_entry(void);
+ static void dump_cb_entry(void);
+ 
+ static void hexdump_map(afs_uint32 offset, afs_uint32 len);
+ 
+ static int get_hdr(void);
+ static int get_h_hdr(void);
+ static int get_cb_hdr(void);
+ static int get_cb_timeout_hdr(void);
+ static int get_cb_timeout(void);
+ static int get_cb_fehash_hdr(void);
+ static int get_cb_fehash(void);
+ static int get_he(afs_uint32 idx);
+ static int get_he_hdr(void);
+ static int get_he_entry(void);
+ static int get_fe(afs_uint32 idx);
+ static int get_fe_hdr(void);
+ static int get_fe_entry(void);
+ static int get_cb(afs_uint32 idx);
+ static int get_cb_entry(void);
+ 
+ static int find_fe_by_index(afs_uint32 idx);
+ static int find_cb_by_index(afs_uint32 idx);
+ static int find_fe_by_fid(afs_uint32 vol, afs_uint32 vn, afs_uint32 uniq);
+ 
+ 
+ static int dump_fd = -1;
+ static void * map = NULL;
+ static size_t map_len;
+ 
+ static struct {
+     struct fs_state_header hdr;
+     struct host_state_header h_hdr;
+     struct callback_state_header cb_hdr;
+     struct callback_state_timeout_header timeout_hdr;
+     struct callback_state_fehash_header fehash_hdr;
+     afs_uint32 * timeout;
+     afs_uint32 * fehash;
+ 
+     /* pointers into the memory map */
+     void * hdr_p;
+     void * h_hdr_p;
+     void * cb_hdr_p;
+     void * timeout_hdr_p;
+     void * timeout_p;
+     void * fehash_hdr_p;
+     void * fehash_p;
+ 
+     byte hdr_valid;
+     byte h_hdr_valid;
+     byte cb_hdr_valid;
+     byte timeout_hdr_valid;
+     byte fehash_hdr_valid;
+ } hdrs;
+ 
+ static struct {
+     void * fh;
+     void * cursor;
+     void * ifp;
+     void * hcps;
+     struct host_state_entry_header hdr;
+     struct hostDiskEntry he;
+     afs_uint32 idx;
+     byte hdr_valid;
+     byte he_valid;
+ } he_cursor;
+ 
+ static struct {
+     void ** cursor;
+ } he_cache;
+ 
+ static struct {
+     void * ffe;
+     void * cursor;
+     void * fcb;
+     struct callback_state_entry_header hdr;
+     struct FEDiskEntry fe;
+     afs_uint32 idx;
+     byte hdr_valid;
+     byte fe_valid;
+ } fe_cursor;
+ 
+ static struct {
+     void ** cursor;
+ } fe_cache;
+ 
+ static struct {
+     void * cursor;
+     struct CBDiskEntry cb;
+     afs_uint32 idx;
+     byte cb_valid;
+ } cb_cursor;
+ 
+ static struct {
+     void ** cursor;
+ } cb_cache;
+ 
+ static void
+ usage(char * prog)
+ {
+     fprintf(stderr, "usage: %s [&lt;state dump file&gt;]\n");
+ }
+ 
+ int
+ main(int argc, char ** argv)
+ {
+     banner();
+ 
+     if (argc &gt; 2 || (argc == 2 &amp;&amp; !strcmp(argv[1], "-h"))) {
+ 	usage(argv[0]);
+ 	return 1;
+     }
+ 
+     initState();
+ 
+     if (argc &gt; 1) {
+ 	if (openFile(argv[1]))
+ 	    return 1;
+     } else {
+ 	if (openFile(AFSDIR_SERVER_FSSTATE_FILEPATH))
+ 	    return 1;
+     }
+ 
+     prompt();
+     return 0;
+ }
+ 
+ 
+ static int
+ openFile(char * path)
+ {
+     int ret = 0;
+     struct afs_stat status;
+     
+     dump_fd = afs_open(path, O_RDWR);
+     if (dump_fd == -1) {
+ 	fprintf(stderr, "dump file '%s' failed to open\n", path);
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     printf("opened dump file '%s'\n", path);
+ 
+     if (afs_fstat(dump_fd, &amp;status) == -1) {
+ 	fprintf(stderr, "failed to stat file\n");
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     map_len = status.st_size;
+ 
+     map = afs_mmap(NULL, map_len, PROT_READ, MAP_SHARED, dump_fd, 0);
+     if (map == MAP_FAILED) {
+ 	fprintf(stderr, "failed to mmap file\n");
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     printf("mapped %d bytes at 0x%x\n", map_len, map);
+ 
+  done:
+     if (ret) {
+ 	if (map) {
+ 	    munmap(map, map_len);
+ 	    map = NULL;
+ 	}
+ 	if (dump_fd != -1) {
+ 	    close(dump_fd);
+ 	    dump_fd = -1;
+ 	}
+     }
+     return ret;
+ }
+ 
+ static void
+ initState(void)
+ {
+     hdrs.hdr_valid = hdrs.h_hdr_valid = hdrs.cb_hdr_valid = 0;
+     he_cursor.cursor = fe_cursor.cursor = cb_cursor.cursor = NULL;
+     he_cursor.fh = fe_cursor.ffe = fe_cursor.fcb = NULL;
+     he_cache.cursor = fe_cache.cursor = NULL;
+ }
+ 
+ static void
+ banner(void)
+ {
+     fprintf(stderr, "demand attach fs\n");
+     fprintf(stderr, "fileserver state analyzer\n");
+     fprintf(stderr, "version 0.1\n");
+ }
+ 
+ #define PROGNAME "fs state analyzer"
+ 
+ static void
+ prompt(void)
+ {
+     char input[256];
+     char prev_input[256];
+     char * tok = NULL;
+     afs_uint32 x, y, z;
+     enum {
+ 	PR_GLOBAL_MODE,
+ 	PR_H_MODE,
+ 	PR_FE_MODE,
+ 	PR_CB_MODE
+     } mode = PR_GLOBAL_MODE, next_mode;
+ 
+     next_mode = mode;
+     input[0] = prev_input[0] = '\0';
+ 
+     while (1) {
+ 	if (!tok) {
+ 	    switch(mode) {
+ 	    case PR_GLOBAL_MODE:
+ 		printf(PROGNAME "&gt; ");
+ 		break;
+ 	    case PR_H_MODE:
+ 		printf(PROGNAME ": h(%d)&gt; ", he_cursor.idx);
+ 		break;
+ 	    case PR_FE_MODE:
+ 		printf(PROGNAME ": fe(%d)&gt; ", fe_cursor.idx);
+ 		break;
+ 	    case PR_CB_MODE:
+ 		printf(PROGNAME ": fe(%d):cb(%d)&gt; ", fe_cursor.idx, cb_cursor.idx);
+ 		break;
+ 	    default:
+ 		fprintf(stderr, "prompt state broken; aborting\n");
+ 		return;
+ 	    }
+ 	    gets(input);
+ 
+ 	    if (!strcmp(input, "")) {
+ 		/* repeat last command */
+ 		if (!strcmp(prev_input, "")) {
+ 		    continue;
+ 		}
+ 		strlcpy(input, prev_input, sizeof(input));
+ 	    } else {
+ 		/* save command for repetition */
+ 		strlcpy(prev_input, input, sizeof(prev_input));
+ 	    }
+ 
+ 	    tok = strtok(input, " \t");
+ 	}
+ 	while (tok &amp;&amp; !strcmp(tok, ";")) {
+ 	    tok = strtok(NULL, "; \t");
+ 	}
+ 
+ 	if (!tok) {
+ 	    continue;
+ 	}
+ 
+ 	if (!strcasecmp(tok, "exit")) {
+ 	    return;
+ 	} else if (!strcasecmp(tok, "quit")) {
+ 	    switch(mode) {
+ 	    case PR_CB_MODE:
+ 		next_mode = PR_FE_MODE;
+ 		break;
+ 	    case PR_FE_MODE:
+ 	    case PR_H_MODE:
+ 		next_mode = PR_GLOBAL_MODE;
+ 		break;
+ 	    default:
+ 		return;
+ 	    }
+ 	} else if (!strcasecmp(tok, "h")) {
+ 	    tok = strtok(NULL, " \t");
+ 	    mode = PR_H_MODE;
+ 	    if (!tok) {
+ 		next_mode = mode;
+ 	    }
+ 	    continue;
+ 	} else if (!strcasecmp(tok, "fe")) {
+ 	    tok = strtok(NULL, " \t");
+ 	    mode = PR_FE_MODE;
+ 	    if (!tok) {
+ 		next_mode = mode;
+ 	    }
+ 	    continue;
+ 	} else if (!strcasecmp(tok, "fs")) {
+ 	    tok = strtok(NULL, " \t");
+ 	    mode = PR_GLOBAL_MODE;
+ 	    if (!tok) {
+ 		next_mode = mode;
+ 	    }
+ 	    continue;
+ 	} else if (!strcasecmp(tok, "cb")) {
+ 	    tok = strtok(NULL, " \t");
+ 	    mode = PR_CB_MODE;
+ 	    if (!tok) {
+ 		next_mode = mode;
+ 	    }
+ 	    continue;
+ 	} else if (!strcasecmp(tok, "help")) {
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		print_h_help();
+ 		break;
+ 	    case PR_FE_MODE:
+ 		print_fe_help();
+ 		break;
+ 	    case PR_CB_MODE:
+ 		print_cb_help();
+ 		break;
+ 	    default:
+ 		print_global_help();
+ 	    }
+ 	    print_help();
+ 	} else if (!strcasecmp(tok, "hexdump")) {
+ 	    tok = strtok(NULL, " \t");
+ 	    if (!tok) {
+ 		hexdump_map(0, map_len);
+ 		continue;
+ 	    }
+ 	    if (sscanf(tok, "%u", &amp;x) != 1) {
+ 		fprintf(stderr, "hexdump parse error 1\n");
+ 		tok = NULL;
+ 		continue;
+ 	    }
+ 	    tok = strtok(NULL, " \t");
+ 	    if (!tok) {
+ 		hexdump_map(x, map_len - x);
+ 		continue;
+ 	    }
+ 	    if (sscanf(tok, "%u", &amp;y) != 1) {
+ 		fprintf(stderr, "hexdump parse error 2\n");
+ 		continue;
+ 	    }
+ 	    hexdump_map(x,y);
+ 	} else if (!strcasecmp(tok, "hdr")) {
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		dump_h_hdr();
+ 		break;
+ 	    case PR_FE_MODE:
+ 		dump_cb_hdr();
+ 		break;
+ 	    case PR_CB_MODE:
+ 		dump_this_fe();
+ 		break;
+ 	    default:
+ 		dump_hdr();
+ 	    }
+ 	} else if (!strcasecmp(tok, "this")) {
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		dump_this_he();
+ 		break;
+ 	    case PR_FE_MODE:
+ 		dump_this_fe();
+ 		break;
+ 	    case PR_CB_MODE:
+ 		dump_this_cb();
+ 		break;
+ 	    default:
+ 		fprintf(stderr, "command not valid for this mode\n");
+ 	    }
+ 	} else if (!strcasecmp(tok, "next")) {
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		dump_next_he();
+ 		break;
+ 	    case PR_FE_MODE:
+ 		dump_next_fe();
+ 		break;
+ 	    case PR_CB_MODE:
+ 		dump_next_cb();
+ 		break;
+ 	    default:
+ 		fprintf(stderr, "command not valid for this mode\n");
+ 	    }
+ 	} else if (!strcasecmp(tok, "prev")) {
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		dump_prev_he();
+ 		break;
+ 	    case PR_FE_MODE:
+ 		dump_prev_fe();
+ 		break;
+ 	    case PR_CB_MODE:
+ 		dump_prev_cb();
+ 		break;
+ 	    default:
+ 		fprintf(stderr, "command not valid for this mode\n");
+ 	    }
+ 	} else if (!strcasecmp(tok, "first")) {
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		dump_first_he();
+ 		break;
+ 	    case PR_FE_MODE:
+ 		dump_first_fe();
+ 		break;
+ 	    case PR_CB_MODE:
+ 		dump_first_cb();
+ 		break;
+ 	    default:
+ 		fprintf(stderr, "command not valid for this mode\n");
+ 	    }
+ 	} else if (!strcasecmp(tok, "last")) {
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		dump_last_he();
+ 		break;
+ 	    case PR_FE_MODE:
+ 		dump_last_fe();
+ 		break;
+ 	    case PR_CB_MODE:
+ 		dump_last_cb();
+ 		break;
+ 	    default:
+ 		fprintf(stderr, "command not valid for this mode\n");
+ 	    }
+ 	} else if (!strcasecmp(tok, "dump")) {
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		dump_all_hes();
+ 		break;
+ 	    case PR_FE_MODE:
+ 		dump_all_fes();
+ 		break;
+ 	    case PR_CB_MODE:
+ 		dump_all_cbs();
+ 		break;
+ 	    default:
+ 		fprintf(stderr, "command not valid for this mode\n");
+ 	    }
+ 	} else if (!strcasecmp(tok, "find")) {
+ 	    tok = strtok(NULL, " \t");
+ 	    if (!tok || strcasecmp(tok, "by")) {
+ 		tok = NULL;
+ 		fprintf(stderr, "find syntax error 1 (%s)\n", 
+ 			(tok) ? tok : "nil");
+ 		continue;
+ 	    }
+ 	    tok = strtok(NULL, " \t");
+ 	    if (!tok) {
+ 		fprintf(stderr, "find syntax error 2\n");
+ 		continue;
+ 	    }
+ 	    switch(mode) {
+ 	    case PR_H_MODE:
+ 		fprintf(stderr, "not implemented yet\n");
+ 		break;
+ 	    case PR_FE_MODE:
+ 		if (!strcasecmp(tok, "index")) {
+ 		    tok = strtok(NULL, " \t");
+ 		    if (!tok || sscanf(tok, "%u", &amp;x) != 1) {
+ 			tok = NULL;
+ 			fprintf(stderr, "find syntax error 3\n");
+ 			continue;
+ 		    }
+ 		    if (find_fe_by_index(x)) {
+ 			fprintf(stderr, "find returned no results\n");
+ 		    }
+ 		} else if (!strcasecmp(tok, "fid")) {
+ 		    tok = strtok(NULL, "(), \t");
+ 		    if (!tok || sscanf(tok, "%u", &amp;x) != 1) {
+ 			tok = NULL;
+ 			fprintf(stderr, "find syntax error 4\n");
+ 			continue;
+ 		    }
+ 		    tok = strtok(NULL, "(), \t");
+ 		    if (!tok || sscanf(tok, "%u", &amp;y) != 1) {
+ 			tok = NULL;
+ 			fprintf(stderr, "find syntax error 5\n");
+ 			continue;
+ 		    }
+ 		    tok = strtok(NULL, "(), \t");
+ 		    if (!tok || sscanf(tok, "%u", &amp;z) != 1) {
+ 			tok = NULL;
+ 			fprintf(stderr, "find syntax error 6\n");
+ 			continue;
+ 		    }
+ 		    if (find_fe_by_fid(x,y,z)) {
+ 			fprintf(stderr, "find returned no results\n");
+ 		    }
+ 		} else {
+ 		    fprintf(stderr, "unsupported filter type\n");
+ 		}
+ 		break;
+ 	    case PR_CB_MODE:
+ 		if (!strcasecmp(tok, "index")) {
+ 		    tok = strtok(NULL, " \t");
+ 		    if (!tok || sscanf(tok, "%u", &amp;x) != 1) {
+ 			tok = NULL;
+ 			fprintf(stderr, "find syntax error 3\n");
+ 			continue;
+ 		    }
+ 		    if (find_cb_by_index(x)) {
+ 			fprintf(stderr, "find returned no results\n");
+ 		    }
+ 		} else {
+ 		    fprintf(stderr, "unsupported filter type\n");
+ 		}
+ 		break;
+ 	    default:
+ 		fprintf(stderr, "find not supported for this menu\n");
+ 	    }
+ 	} else if (!strcspn(tok, "0123456789")) {
+ 	    if (sscanf(tok, "%u", &amp;x) == 1) {
+ 		switch(mode) {
+ 		case PR_H_MODE:
+ 		    dump_he(x);
+ 		    break;
+ 		case PR_FE_MODE:
+ 		    dump_fe(x);
+ 		    break;
+ 		case PR_CB_MODE:
+ 		    dump_cb(x);
+ 		    break;
+ 		default:
+ 		    fprintf(stderr, "command not available from this menu\n");
+ 		}
+ 	    } else {
+ 		fprintf(stderr, "input parse error ('%s')\n", tok);
+ 	    }
+ 	} else if (mode == PR_FE_MODE) {
+ 	    if (!strcmp(tok, "timeout")) {
+ 		dump_cb_timeout();
+ 	    } else if (!strcmp(tok, "hash")) {
+ 		dump_cb_fehash();
+ 	    }
+ 	} else {
+ 	    fprintf(stderr, "unknown command\n");
+ 	}
+ 	tok = strtok(NULL, " \t");
+ 	mode = next_mode;
+     }
+ }
+ 
+ static void
+ print_help(void)
+ {
+     printf("\th &lt;...&gt;  -- host menu commands\n");
+     printf("\tfe &lt;...&gt; -- FileEntry menu commands\n");
+     printf("\tcb &lt;...&gt; -- CallBack menu commands\n");
+     printf("\thexdump [&lt;offset&gt; [&lt;len&gt;]]\n\t\t -- hex dump the raw data\n");
+     printf("\tquit     -- quit this menu\n");
+     printf("\texit     -- exit the debugger\n");
+     printf("\thelp     -- this help message\n");
+ }
+ 
+ static void
+ print_global_help(void)
+ {
+     printf("\thdr      -- display the fs_state_header struct\n");
+ }
+ 
+ static void
+ print_h_help(void)
+ {
+     printf("\thdr      -- display the host_state_header struct\n");
+     printf("\tfirst    -- display the first host\n");
+     printf("\tprev     -- display the previous host\n");
+     printf("\tthis     -- display this host\n");
+     printf("\tnext     -- display the next host\n");
+     printf("\tlast     -- display the last host\n");
+     printf("\tdump     -- display all hosts\n");
+ }
+ 
+ static void
+ print_fe_help(void)
+ {
+     printf("\thdr      -- display the callback_state_header struct\n");
+     printf("\tfirst    -- display the first FE\n");
+     printf("\tprev     -- display the previous FE\n");
+     printf("\tthis     -- display this FE\n");
+     printf("\tnext     -- display the next FE\n");
+     printf("\tlast     -- display the last FE\n");
+     printf("\tdump     -- display all FEs\n");
+     printf("\ttimeout  -- display the timeout queue heads\n");
+     printf("\thash   -- display the file entry hash buckets\n");
+     printf("\tfind by index &lt;id&gt;\n\t\t -- find an fe by its array index\n");
+     printf("\tfind by fid &lt;(vol,vnode,unique)&gt;\n\t\t -- find an fe by its AFSFid\n");
+ }
+ 
+ static void
+ print_cb_help(void)
+ {
+     printf("\thdr      -- display the callback_state_entry_header struct\n");
+     printf("\tfirst    -- display the first CB\n");
+     printf("\tprev     -- display the previous CB\n");
+     printf("\tthis     -- display this CB\n");
+     printf("\tnext     -- display the next CB\n");
+     printf("\tlast     -- display the last CB\n");
+     printf("\tdump     -- display all CBs\n");
+ }
+ 
+ #define DPFTB0 "\t"
+ #define DPFTB1 "\t\t"
+ #define DPFTB2 "\t\t\t"
+ 
+ #define DPFOFF(addr) \
+     do { \
+         char * _p = (char *)addr; \
+         char * _m = (char *)map; \
+         printf("loading structure from address 0x%x (offset %u)\n", \
+                addr, _p-_m); \
+     } while (0)
+ 
+ /* structs */
+ #define DPFSO(T, name) printf(T "%s = {\n", name)
+ #define DPFSO0(name) DPFSO(DPFTB0, name)
+ #define DPFSO1(name) DPFSO(DPFTB1, name)
+ #define DPFSC(T) printf(T "}\n")
+ #define DPFSC0 DPFSC(DPFTB0)
+ #define DPFSC1 DPFSC(DPFTB1)
+ 
+ /* arrays */
+ #define DPFAO(T1, T2, name) printf(T1 "%s =\n" T2 "{ ", name)
+ #define DPFAO0(name) DPFAO(DPFTB0, DPFTB1, name)
+ #define DPFAO1(name) DPFAO(DPFTB1, DPFTB2, name)
+ #define DPFAC0 printf(" }\n")
+ #define DPFAC1 DPFAC0
+ #define DPFA1 printf(DPFTB1 "  ")
+ #define DPFA2 printf(DPFTB2 "  ")
+ #define DPFAN printf("\n")
+ #define DPFALE(type, var) printf("%" type, var)
+ #define DPFAE(type, var) printf("%" type ",\t", var)
+ 
+ /* normal vars */
+ #define DPFV(T, name, type, var) printf(T "%s = %" type "\n", name, var)
+ #define DPFV1(name, type, var) DPFV(DPFTB1, name, type, var)
+ #define DPFV2(name, type, var) DPFV(DPFTB2, name, type, var)
+ 
+ /* hex */
+ #define DPFX(T, name, var) printf(T "%s = 0x%x\n", name, var)
+ #define DPFX1(name, var) DPFX(DPFTB1, name, var)
+ #define DPFX2(name, var) DPFX(DPFTB2, name, var)
+ 
+ /* strings */
+ #define DPFS(T, name, var) printf(T "%s = \"%s\"\n", name, var)
+ #define DPFS1(name, var) DPFS(DPFTB1, name, var)
+ #define DPFS2(name, var) DPFS(DPFTB2, name, var)
+ 
+ /* time */
+ #define DPFT(T, name, var) \
+     do { \
+         char * last; \
+         printf(T "%s = \"%s\"\n", name, strtok_r(ctime(&amp;(var)), "\r\n", &amp;last)); \
+     } while(0)
+ #define DPFT1(name, var) DPFT(DPFTB1, name, var)
+ #define DPFT2(name, var) DPFT(DPFTB2, name, var)
+ 
+ static void
+ dump_hdr(void)
+ {
+     char uuid_str[40];
+     afs_uint32 hi, lo;
+ 
+     if (get_hdr())
+ 	return;
+ 
+     DPFOFF(map);
+     DPFSO0("fs_state_header");
+     DPFSO1("stamp");
+     DPFX2("magic", hdrs.hdr.stamp.magic);
+     DPFV2("version", "u", hdrs.hdr.stamp.version);
+     DPFSC1;
+     DPFT1("timestamp", hdrs.hdr.timestamp);
+     DPFV1("sys_name", "u", hdrs.hdr.sys_name);
+ 
+     afsUUID_to_string(&amp;hdrs.hdr.server_uuid, uuid_str, sizeof(uuid_str));
+     DPFS1("server_uuid", uuid_str);
+     DPFV1("valid", "d", hdrs.hdr.valid);
+     DPFV1("endianness", "d", hdrs.hdr.endianness);
+     DPFV1("stats_detailed", "d", hdrs.hdr.stats_detailed);
+ 
+     SplitInt64(hdrs.hdr.h_offset, hi, lo);
+     DPFSO1("h_offset");
+     DPFV2("hi", "u", hi);
+     DPFV2("lo", "u", lo);
+     DPFSC1;
+ 
+     SplitInt64(hdrs.hdr.cb_offset, hi, lo);
+     DPFSO1("cb_offset");
+     DPFV2("hi", "u", hi);
+     DPFV2("lo", "u", lo);
+     DPFSC1;
+ 
+     DPFS1("server_version_string", hdrs.hdr.server_version_string);
+     DPFSC0;
+ 
+     if (hdrs.hdr.stamp.magic != FS_STATE_MAGIC) {
+ 	fprintf(stderr, "* magic check failed\n");
+     }
+     if (hdrs.hdr.stamp.version != FS_STATE_VERSION) {
+ 	fprintf(stderr, "* version check failed\n");
+     }
+ }
+ 
+ static void
+ dump_h_hdr(void)
+ {
+     if (get_h_hdr())
+ 	return;
+ 
+     DPFOFF(hdrs.h_hdr_p);
+     DPFSO0("host_state_header");
+     DPFSO1("stamp");
+     DPFX2("magic", hdrs.h_hdr.stamp.magic);
+     DPFV2("version", "u", hdrs.h_hdr.stamp.version);
+     DPFSC1;
+     DPFV1("records", "u", hdrs.h_hdr.records);
+     DPFV1("index_max", "u", hdrs.h_hdr.index_max);
+     DPFSC0;
+ 
+     if (hdrs.h_hdr.stamp.magic != HOST_STATE_MAGIC) {
+ 	fprintf(stderr, "* magic check failed\n");
+     }
+     if (hdrs.h_hdr.stamp.version != HOST_STATE_VERSION) {
+ 	fprintf(stderr, "* version check failed\n");
+     }
+ }
+ 
+ static void
+ dump_cb_hdr(void)
+ {
+     afs_uint32 hi, lo;
+ 
+     if (get_cb_hdr())
+ 	return;
+ 
+     DPFOFF(hdrs.cb_hdr_p);
+     DPFSO0("callback_state_header");
+     DPFSO1("stamp");
+     DPFX2("magic", hdrs.cb_hdr.stamp.magic);
+     DPFV2("version", "u", hdrs.cb_hdr.stamp.version);
+     DPFSC1;
+     DPFV1("nFEs", "u", hdrs.cb_hdr.nFEs);
+     DPFV1("nCBs", "u", hdrs.cb_hdr.nCBs);
+     DPFV1("fe_max", "u", hdrs.cb_hdr.fe_max);
+     DPFV1("cb_max", "u", hdrs.cb_hdr.cb_max);
+     DPFV1("tfirst", "d", hdrs.cb_hdr.tfirst);
+ 
+     SplitInt64(hdrs.cb_hdr.timeout_offset, hi, lo);
+     DPFSO1("timeout_offset");
+     DPFV2("hi", "u", hi);
+     DPFV2("lo", "u", lo);
+     DPFSC1;
+ 
+     SplitInt64(hdrs.cb_hdr.fehash_offset, hi, lo);
+     DPFSO1("fehash_offset");
+     DPFV2("hi", "u", hi);
+     DPFV2("lo", "u", lo);
+     DPFSC1;
+ 
+     SplitInt64(hdrs.cb_hdr.fe_offset, hi, lo);
+     DPFSO1("fe_offset");
+     DPFV2("hi", "u", hi);
+     DPFV2("lo", "u", lo);
+     DPFSC1;
+ 
+     DPFSC0;
+ 
+     if (hdrs.cb_hdr.stamp.magic != CALLBACK_STATE_MAGIC) {
+ 	fprintf(stderr, "* magic check failed\n");
+     }
+     if (hdrs.cb_hdr.stamp.version != CALLBACK_STATE_VERSION) {
+ 	fprintf(stderr, "* version check failed\n");
+     }
+ }
+ 
+ static void
+ dump_cb_timeout(void)
+ {
+     int i;
+ 
+     if (get_cb_hdr())
+ 	return;
+ 
+     if (get_cb_timeout_hdr())
+ 	return;
+ 
+     if (get_cb_timeout())
+ 	return;
+ 
+     DPFOFF(hdrs.timeout_hdr_p);
+     DPFSO0("callback_state_timeout_header");
+     DPFX1("magic", hdrs.timeout_hdr.magic);
+     DPFV1("len", "u", hdrs.timeout_hdr.len);
+     DPFV1("records", "u", hdrs.timeout_hdr.records);
+     DPFSC0;
+ 
+     if (hdrs.timeout_hdr.magic != CALLBACK_STATE_TIMEOUT_MAGIC) {
+ 	fprintf(stderr, "* magic check failed\n");
+     }
+ 
+     DPFOFF(hdrs.timeout_p);
+     DPFAO0("timeout");
+     for (i = 0; i &lt; 127; i++) {
+ 	DPFAE("u", hdrs.timeout[i]);
+ 	if ((i % 8) == 7) {
+ 	    DPFAN;
+ 	    DPFA1;
+ 	}
+     }
+     DPFALE("u", hdrs.timeout[127]);
+     DPFAC0;
+ }
+ 
+ static void
+ dump_cb_fehash(void)
+ {
+     int i;
+ 
+     if (get_cb_hdr())
+ 	return;
+ 
+     if (get_cb_fehash_hdr())
+ 	return;
+ 
+     if (get_cb_fehash())
+ 	return;
+ 
+     DPFOFF(hdrs.fehash_hdr_p);
+     DPFSO0("callback_state_fehash_header");
+     DPFX1("magic", hdrs.fehash_hdr.magic);
+     DPFV1("len", "u", hdrs.fehash_hdr.len);
+     DPFV1("records", "u", hdrs.fehash_hdr.records);
+     DPFSC0;
+ 
+     if (hdrs.fehash_hdr.magic != CALLBACK_STATE_FEHASH_MAGIC) {
+ 	fprintf(stderr, "* magic check failed\n");
+     }
+ 
+     DPFOFF(hdrs.fehash_p);
+     DPFAO0("fehash");
+     for (i = 0; i &lt; hdrs.fehash_hdr.records - 1; i++) {
+ 	DPFAE("u", hdrs.fehash[i]);
+ 	if ((i % 8) == 7) {
+ 	    DPFAN;
+ 	    DPFA1;
+ 	}
+     }
+     DPFALE("u", hdrs.fehash[hdrs.fehash_hdr.records-1]);
+     DPFAC0;
+ }
+ 
+ static void
+ dump_all_hes(void)
+ {
+     int i;
+ 
+     if (get_h_hdr()) {
+ 	fprintf(stderr, "error getting host_state_header\n");
+ 	return;
+     }
+ 
+     for (i = 0; i &lt; hdrs.h_hdr.records; i++) {
+ 	dump_he(i);
+     }
+ }
+ 
+ static void
+ dump_all_fes(void)
+ {
+     int i;
+ 
+     if (get_cb_hdr()) {
+ 	fprintf(stderr, "error getting callback_state_header\n");
+ 	return;
+     }
+ 
+     for (i = 0; i &lt; hdrs.cb_hdr.nFEs; i++) {
+ 	dump_fe(i);
+     }
+ }
+ 
+ static void
+ dump_all_cbs(void)
+ {
+     int i;
+ 
+     if (get_fe_hdr()) {
+ 	fprintf(stderr, "error getting callback_state_entry_header\n");
+ 	return;
+     }
+ 
+     for (i = 0; i &lt; fe_cursor.hdr.nCBs; i++) {
+ 	dump_cb(i);
+     }
+ }
+ 
+ static void
+ dump_he(afs_uint32 idx)
+ {
+     if (get_he(idx)) {
+ 	fprintf(stderr, "error getting he %d\n", idx);
+ 	return;
+     }
+ 
+     DPFOFF(he_cursor.cursor);
+     dump_he_hdr();
+     dump_he_entry();
+     dump_he_interfaces();
+     dump_he_hcps();
+ }
+ 
+ static void
+ dump_fe(afs_uint32 idx)
+ {
+     if (get_fe(idx)) {
+ 	fprintf(stderr, "error getting fe %d\n", idx);
+ 	return;
+     }
+ 
+     DPFOFF(fe_cursor.cursor);
+     dump_fe_hdr();
+     dump_fe_entry();
+ }
+ 
+ static void
+ dump_cb(afs_uint32 idx)
+ {
+     if (get_cb(idx)) {
+ 	fprintf(stderr, "error getting cb %d\n", idx);
+ 	return;
+     }
+ 
+     DPFOFF(cb_cursor.cursor);
+     dump_cb_entry();
+ }
+ 
+ static void
+ dump_this_he(void)
+ {
+     dump_he(he_cursor.idx);
+ }
+ 
+ static void
+ dump_this_fe(void)
+ {
+     dump_fe(fe_cursor.idx);
+ }
+ 
+ static void
+ dump_this_cb(void)
+ {
+     dump_cb(cb_cursor.idx);
+ }
+ 
+ static void
+ dump_next_he(void)
+ {
+     if (get_h_hdr()) {
+ 	fprintf(stderr, "error getting host_state_header\n");
+ 	return;
+     }
+ 
+     if ((he_cursor.idx + 1) &gt;= hdrs.h_hdr.records) {
+ 	fprintf(stderr, "no more HEs\n");
+ 	return;
+     }
+     
+     dump_he(he_cursor.idx+1);
+ }
+ 
+ static void
+ dump_next_fe(void)
+ {
+     if (get_cb_hdr()) {
+ 	fprintf(stderr, "error getting callback_state_header\n");
+ 	return;
+     }
+ 
+     if ((fe_cursor.idx + 1) &gt;= hdrs.cb_hdr.nFEs) {
+ 	fprintf(stderr, "no more FEs\n");
+ 	return;
+     }
+     
+     dump_fe(fe_cursor.idx+1);
+ }
+ 
+ static void
+ dump_next_cb(void)
+ {
+     if (get_fe_hdr()) {
+ 	fprintf(stderr, "error getting callback_state_entry_header\n");
+ 	return;
+     }
+ 
+     if ((cb_cursor.idx + 1) &gt;= fe_cursor.hdr.nCBs) {
+ 	fprintf(stderr, "no more CBs\n");
+ 	return;
+     }
+     
+     dump_cb(cb_cursor.idx+1);
+ }
+ 
+ static void
+ dump_prev_he(void)
+ {
+     if (!he_cursor.idx) {
+ 	fprintf(stderr, "no more HEs\n");
+ 	return;
+     }
+     
+     dump_he(he_cursor.idx-1);
+ }
+ 
+ static void
+ dump_prev_fe(void)
+ {
+     if (!fe_cursor.idx) {
+ 	fprintf(stderr, "no more FEs\n");
+ 	return;
+     }
+     
+     dump_fe(fe_cursor.idx-1);
+ }
+ 
+ static void
+ dump_prev_cb(void)
+ {
+     if (!cb_cursor.idx) {
+ 	fprintf(stderr, "no more CBs\n");
+ 	return;
+     }
+     
+     dump_cb(cb_cursor.idx-1);
+ }
+ 
+ static void
+ dump_first_fe(void)
+ {
+     if (get_cb_hdr()) {
+ 	fprintf(stderr, "error getting callback_state_header\n");
+ 	return;
+     }
+ 
+     if (!hdrs.cb_hdr.nFEs) {
+ 	fprintf(stderr, "no FEs present\n");
+ 	return;
+     }
+     
+     dump_fe(0);
+ }
+ 
+ static void
+ dump_first_he(void)
+ {
+     if (get_h_hdr()) {
+ 	fprintf(stderr, "error getting host_state_header\n");
+ 	return;
+     }
+ 
+     if (!hdrs.h_hdr.records) {
+ 	fprintf(stderr, "no HEs present\n");
+ 	return;
+     }
+     
+     dump_he(0);
+ }
+ 
+ static void
+ dump_first_cb(void)
+ {
+     if (get_fe_hdr()) {
+ 	fprintf(stderr, "error getting callback_state_entry_header\n");
+ 	return;
+     }
+ 
+     if (!fe_cursor.hdr.nCBs) {
+ 	fprintf(stderr, "no CBs present\n");
+ 	return;
+     }
+     
+     dump_cb(0);
+ }
+ 
+ static void
+ dump_last_he(void)
+ {
+     if (get_h_hdr()) {
+ 	fprintf(stderr, "error getting host_state_header\n");
+ 	return;
+     }
+ 
+     if (!hdrs.h_hdr.records) {
+ 	fprintf(stderr, "no HEs present\n");
+ 	return;
+     }
+     
+     dump_he(hdrs.h_hdr.records-1);
+ }
+ 
+ static void
+ dump_last_fe(void)
+ {
+     if (get_cb_hdr()) {
+ 	fprintf(stderr, "error getting callback_state_header\n");
+ 	return;
+     }
+ 
+     if (!hdrs.cb_hdr.nFEs) {
+ 	fprintf(stderr, "no FEs present\n");
+ 	return;
+     }
+     
+     dump_fe(hdrs.cb_hdr.nFEs-1);
+ }
+ 
+ static void
+ dump_last_cb(void)
+ {
+     if (get_fe_hdr()) {
+ 	fprintf(stderr, "error getting callback_state_entry_header\n");
+ 	return;
+     }
+ 
+     if (!fe_cursor.hdr.nCBs) {
+ 	fprintf(stderr, "no CBs present\n");
+ 	return;
+     }
+ 
+     dump_cb(fe_cursor.hdr.nCBs-1);
+ }
+ 
+ static void
+ dump_he_hdr(void)
+ {
+     DPFSO0("host_state_entry_header");
+     DPFX1("magic", he_cursor.hdr.magic);
+     DPFV1("len", "u", he_cursor.hdr.len);
+     DPFV1("interfaces", "u", he_cursor.hdr.interfaces);
+     DPFV1("hcps", "u", he_cursor.hdr.hcps);
+     DPFSC0;
+ 
+     if (he_cursor.hdr.magic != HOST_STATE_ENTRY_MAGIC) {
+ 	fprintf(stderr, "* magic check failed\n");
+     }
+ }
+ 
+ static void
+ dump_he_entry(void)
+ {
+     DPFSO0("hostDiskEntry");
+     DPFS1("host", afs_inet_ntoa(he_cursor.he.host));
+     DPFV1("port", "u", he_cursor.he.port);
+     DPFX1("hostFlags", he_cursor.he.hostFlags);
+     DPFV1("Console", "u", he_cursor.he.Console);
+     DPFV1("hcpsfailed", "u", he_cursor.he.hcpsfailed);
+     DPFV1("hcps_valid", "u", he_cursor.he.hcps_valid);
+     if (hdrs.hdr.stats_detailed) {
+ #ifdef FS_STATS_DETAILED
+ 	DPFV1("InSameNetwork", "u", he_cursor.he.InSameNetwork);
+ #else
+ 	DPFV1("InSameNetwork", "u", he_cursor.he.padding1[0]);
+ #endif
+     }
+     DPFV1("hcps_len", "u", he_cursor.he.hcps_len);
+     DPFT1("LastCall", he_cursor.he.LastCall);
+     DPFT1("ActiveCall", he_cursor.he.ActiveCall);
+     DPFT1("cpsCall", he_cursor.he.cpsCall);
+     DPFV1("cblist", "u", he_cursor.he.cblist);
+     DPFV1("index", "u", he_cursor.he.index);
+     DPFSC0;
+ }
+ 
+ static void
+ dump_he_interfaces(void)
+ {
+     char temp_str[40];
+     struct Interface * ifp;
+     int len, i;
+ 
+     if (!he_cursor.hdr.interfaces)
+ 	return;
+ 
+     len = sizeof(struct Interface) + ((he_cursor.hdr.interfaces-1)*sizeof(struct AddrPort));
+     ifp = (struct Interface *) malloc(len);
+     assert(ifp != NULL);
+ 
+     memcpy(ifp, he_cursor.ifp, len);
+ 
+     DPFSO0("Interface");
+     DPFV1("numberOfInterfaces", "u", ifp-&gt;numberOfInterfaces);
+ 
+     afsUUID_to_string(&amp;ifp-&gt;uuid, temp_str, sizeof(temp_str));
+     DPFS1("uuid", temp_str);
+     for (i = 0; i &lt; he_cursor.hdr.interfaces; i++) {
+ 	snprintf(temp_str, sizeof(temp_str), "interface[%d]", i);
+ 	DPFSO1(temp_str);
+ 	DPFS2("addr", afs_inet_ntoa(ifp-&gt;interface[i].addr));
+ 	DPFV2("port", "u", ifp-&gt;interface[i].port);
+ 	DPFSC1;
+     }
+ 
+     DPFSC0;
+ 
+     if (he_cursor.hdr.interfaces != ifp-&gt;numberOfInterfaces) {
+ 	fprintf(stderr, "* interface count mismatch between header and Interface struct\n");
+     }
+     free(ifp);
+ }
+ 
+ static void
+ dump_he_hcps(void)
+ {
+     char temp_str[40];
+     afs_int32 * hcps;
+     int len, i;
+ 
+     if (!he_cursor.hdr.hcps)
+ 	return;
+ 
+     len = (he_cursor.hdr.hcps)*sizeof(afs_uint32);
+     hcps = (afs_int32 *) malloc(len);
+     assert(hcps != NULL);
+     memcpy(hcps, he_cursor.hcps, len);
+ 
+     DPFSO0("hcps");
+     DPFAO1("prlist_val");
+     for (i = 0; i &lt; he_cursor.hdr.hcps - 1; i++) {
+ 	DPFAE("d", hcps[i]);
+ 	if ((i % 8) == 7) {
+ 	    DPFAN;
+ 	    DPFA2;
+ 	}
+     }
+     DPFALE("d", hcps[he_cursor.hdr.hcps-1]);
+     DPFAC1;
+     DPFSC0;
+     free(hcps);
+ }
+ 
+ static void
+ dump_fe_hdr(void)
+ {
+     DPFSO0("callback_state_entry_header");
+     DPFX1("magic", fe_cursor.hdr.magic);
+     DPFV1("len", "u", fe_cursor.hdr.len);
+     DPFV1("nCBs", "u", fe_cursor.hdr.nCBs);
+     DPFSC0;
+ 
+     if (fe_cursor.hdr.magic != CALLBACK_STATE_ENTRY_MAGIC) {
+ 	fprintf(stderr, "* magic check failed\n");
+     }
+ }
+ 
+ static void
+ dump_fe_entry(void)
+ {
+     DPFSO0("FEDiskEntry");
+     DPFSO1("fe");
+     DPFV2("vnode", "u", fe_cursor.fe.fe.vnode);
+     DPFV2("unique", "u", fe_cursor.fe.fe.unique);
+     DPFV2("volid", "u", fe_cursor.fe.fe.volid);
+     DPFV2("fnext", "u", fe_cursor.fe.fe.fnext);
+     DPFV2("ncbs", "u", fe_cursor.fe.fe.ncbs);
+     DPFV2("firstcb", "u", fe_cursor.fe.fe.firstcb);
+     DPFV2("status", "u", fe_cursor.fe.fe.status);
+     DPFSC1;
+     DPFV1("index", "u", fe_cursor.fe.index);
+     DPFSC0;
+ }
+ 
+ static void
+ dump_cb_entry(void)
+ {
+     DPFSO0("CBDiskEntry");
+     DPFSO1("cb");
+     DPFV2("cnext", "u", cb_cursor.cb.cb.cnext);
+     DPFV2("fhead", "u", cb_cursor.cb.cb.fhead);
+     DPFV2("thead", "u", (afs_uint32)cb_cursor.cb.cb.thead);
+     DPFV2("status", "u", (afs_uint32)cb_cursor.cb.cb.status);
+     DPFV2("hhead", "u", cb_cursor.cb.cb.hhead);
+     DPFV2("tprev", "u", cb_cursor.cb.cb.tprev);
+     DPFV2("tnext", "u", cb_cursor.cb.cb.tnext);
+     DPFV2("hprev", "u", cb_cursor.cb.cb.hprev);
+     DPFV2("hnext", "u", cb_cursor.cb.cb.hnext);
+     DPFSC1;
+     DPFV1("index", "u", cb_cursor.cb.index);
+     DPFSC0;
+ }
+ 
+ #define DPFHMS printf("  ")
+ #define DPFHS printf("    ")
+ #define DPFHN(offset) printf("\n%u\t", offset)
+ #define DPFHD(x) printf("%02X  ", x)
+ #define DPFHE printf("\n")
+ 
+ static void
+ hexdump_map(afs_uint32 offset, afs_uint32 len)
+ {
+     int i;
+     unsigned char * p = (unsigned char *)map;
+     afs_uint32 c32;
+ 
+     if (!len)
+ 	return;
+ 
+     if ((offset + len) &gt; map_len) {
+ 	fprintf(stderr, "offset + length exceeds memory map size (%u &gt; %u)\n",
+ 		offset+len, map_len);
+ 	return;
+     }
+ 
+     p += offset;
+     DPFOFF(p);
+     DPFHN(offset);
+ 
+     for (i = offset % 16; i &gt; 0; i--) {
+ 	DPFHS;
+     }
+ 
+     for (i=0; i &lt; len; i++, p++, offset++) {
+ 	if (!(offset % 16)) {
+ 	    DPFHN(offset);
+ 	} else if (!(offset % 8)) {
+ 	    DPFHMS;
+ 	}
+ 	DPFHD(*p);
+     }
+     DPFHE;
+ }
+ 
+ static int
+ get_hdr(void)
+ {
+     if (!hdrs.hdr_valid) {
+ 	if (map_len &lt; sizeof(struct fs_state_header)) {
+ 	    fprintf(stderr, "corrupt state dump: fs_state_header larger than memory map\n");
+ 	    return 1;
+ 	}
+ 	memcpy(&amp;hdrs.hdr, map, sizeof(hdrs.hdr));
+ 	hdrs.hdr_p = map;
+ 	hdrs.hdr_valid = 1;
+     }
+     return 0;
+ }
+ 
+ static int
+ get_h_hdr(void)
+ {
+     char * buf;
+     afs_uint32 hi, lo;
+ 
+     if (hdrs.h_hdr_valid)
+ 	return 0;
+ 
+     if (get_hdr())
+ 	return 1;
+ 
+     SplitInt64(hdrs.hdr.h_offset, hi, lo);
+ 
+     if (hi) {
+ 	fprintf(stderr, "hi offset bits set in h_offset; can't get host_state_header\n");
+ 	return 1;
+     }
+     if ((lo &gt;= map_len) || 
+ 	((lo + sizeof(struct host_state_header)) &gt; map_len) ||
+ 	(lo + sizeof(struct host_state_header) &lt; lo)) {
+ 	fprintf(stderr, "h_offset puts host_state_header beyond end of memory map\n");
+ 	return 1;
+     }
+ 
+     buf = (char *) map;
+     buf += lo;
+     memcpy(&amp;hdrs.h_hdr, buf, sizeof(struct host_state_header));
+     hdrs.h_hdr_p = buf;
+     buf += sizeof(struct host_state_header);
+     he_cursor.fh = (void *)buf;
+     return 0;
+ }
+ 
+ static int
+ get_cb_hdr(void)
+ {
+     char * buf;
+     afs_uint32 hi, lo;
+ 
+     if (hdrs.cb_hdr_valid)
+ 	return 0;
+ 
+     if (get_hdr())
+ 	return 1;
+ 
+     SplitInt64(hdrs.hdr.cb_offset, hi, lo);
+ 
+     if (hi) {
+ 	fprintf(stderr, "hi offset bits set in cb_offset; can't get callback_state_header\n");
+ 	return 1;
+     }
+     if ((lo &gt;= map_len) || 
+ 	((lo + sizeof(struct callback_state_header)) &gt; map_len) ||
+ 	(lo + sizeof(struct callback_state_header) &lt; lo)) {
+ 	fprintf(stderr, "cb_offset puts callback_state_header beyond end of memory map\n");
+ 	return 1;
+     }
+ 
+     buf = (char *) map;
+     buf += lo;
+     memcpy(&amp;hdrs.cb_hdr, buf, sizeof(struct callback_state_header));
+     hdrs.cb_hdr_p = buf;
+     hdrs.cb_hdr_valid = 1;
+ 
+     SplitInt64(hdrs.cb_hdr.fe_offset, hi, lo);
+ 
+     if (hi) {
+ 	fprintf(stderr, "hi offset bits set in fe_offset; can't get callback_state_entry_header\n");
+ 	return 1;
+     }
+     hi = lo + (hdrs.cb_hdr.nFEs * (sizeof(struct callback_state_entry_header) +
+ 				  sizeof(struct FEDiskEntry)) +
+ 	       hdrs.cb_hdr.nCBs * sizeof(struct CBDiskEntry));
+     if ((hi &gt; map_len) ||
+ 	(lo &gt; hi)) {
+ 	fprintf(stderr, "fe_offset puts callback_state_entry_header beyond end of memory map\n");
+ 	return 1;
+     }
+ 
+     buf = (char *) map;
+     buf += lo;
+     fe_cursor.ffe = (void *)buf;
+ 
+     return 0;
+ }
+ 
+ static int
+ get_cb_timeout_hdr(void)
+ {
+     char * buf;
+     afs_uint32 hi, lo;
+ 
+     if (hdrs.timeout_hdr_valid)
+ 	return 0;
+ 
+     if (get_cb_hdr())
+ 	return 1;
+ 
+     SplitInt64(hdrs.cb_hdr.timeout_offset, hi, lo);
+ 
+     if (hi) {
+ 	fprintf(stderr, "hi offset bits set in timeout_offset; can't get callback_state_timeout_header\n");
+ 	return 1;
+     }
+     if ((lo &gt;= map_len) || 
+ 	((lo + sizeof(struct callback_state_timeout_header)) &gt; map_len) ||
+ 	(lo + sizeof(struct callback_state_timeout_header) &lt; lo)) {
+ 	fprintf(stderr, "timeout_offset puts callback_state_timeout_header beyond end of memory map\n");
+ 	return 1;
+     }
+ 
+     buf = (char *) map;
+     buf += lo;
+     memcpy(&amp;hdrs.timeout_hdr, buf, sizeof(struct callback_state_timeout_header));
+     hdrs.timeout_hdr_p = buf;
+     hdrs.timeout_hdr_valid = 1;
+     buf += sizeof(struct callback_state_timeout_header);
+     hdrs.timeout_p = buf;
+ 
+     return 0;
+ }
+ 
+ static int
+ get_cb_timeout(void)
+ {
+     char * buf;
+ 
+     if (hdrs.timeout)
+ 	return 0;
+ 
+     if (get_cb_timeout_hdr())
+ 	return 1;
+ 
+     hdrs.timeout = (afs_uint32 *) calloc(hdrs.timeout_hdr.records, sizeof(afs_uint32));
+     assert(hdrs.timeout != NULL);
+     memcpy(hdrs.timeout, hdrs.timeout_p, hdrs.timeout_hdr.records * sizeof(afs_uint32));
+     return 0;
+ }
+ 
+ static int
+ get_cb_fehash_hdr(void)
+ {
+     char * buf;
+     afs_uint32 hi, lo;
+ 
+     if (hdrs.fehash_hdr_valid)
+ 	return 0;
+ 
+     if (get_cb_hdr())
+ 	return 1;
+ 
+     SplitInt64(hdrs.cb_hdr.fehash_offset, hi, lo);
+ 
+     if (hi) {
+ 	fprintf(stderr, "hi offset bits set in fehash_offset; can't get callback_state_fehash_header\n");
+ 	return 1;
+     }
+     if ((lo &gt;= map_len) || 
+ 	((lo + sizeof(struct callback_state_fehash_header)) &gt; map_len) ||
+ 	(lo + sizeof(struct callback_state_fehash_header) &lt; lo)) {
+ 	fprintf(stderr, "timeout_offset puts callback_state_fehash_header beyond end of memory map\n");
+ 	return 1;
+     }
+ 
+     buf = (char *) map;
+     buf += lo;
+     memcpy(&amp;hdrs.fehash_hdr, buf, sizeof(struct callback_state_fehash_header));
+     hdrs.fehash_hdr_p = buf;
+     hdrs.fehash_hdr_valid = 1;
+     buf += sizeof(struct callback_state_fehash_header);
+     hdrs.fehash_p = buf;
+ 
+     return 0;
+ }
+ 
+ static int
+ get_cb_fehash(void)
+ {
+     char * buf;
+ 
+     if (hdrs.fehash)
+ 	return 0;
+ 
+     if (get_cb_fehash_hdr())
+ 	return 1;
+ 
+     hdrs.fehash = (afs_uint32 *) calloc(hdrs.fehash_hdr.records, sizeof(afs_uint32));
+     assert(hdrs.fehash != NULL);
+     memcpy(hdrs.fehash, hdrs.fehash_p, hdrs.fehash_hdr.records * sizeof(afs_uint32));
+     return 0;
+ }
+ 
+ static int
+ get_he(afs_uint32 idx)
+ {
+     int i;
+     char * p;
+ 
+     if (get_h_hdr())
+ 	return 1;
+ 
+     if (idx &gt;= hdrs.h_hdr.records)
+ 	return 1;
+ 
+     if (he_cursor.idx == idx &amp;&amp; he_cursor.hdr_valid &amp;&amp; he_cursor.he_valid)
+ 	return 0;
+ 
+     he_cursor.hdr_valid = he_cursor.he_valid = 0;
+ 
+     if (he_cache.cursor == NULL) {
+ 	he_cache.cursor = (void **) calloc(hdrs.h_hdr.records, sizeof(void *));
+ 	assert(he_cache.cursor != NULL);
+     }
+ 
+     if (idx &amp;&amp; he_cache.cursor[idx-1] == NULL) {
+ 	for (i = 0; i &lt; idx; i++) {
+ 	    if (he_cache.cursor[i] == NULL) {
+ 		get_he(i);
+ 	    }
+ 	}
+     }
+ 
+     if (!idx) {
+ 	he_cursor.cursor = he_cursor.fh;
+     } else if (he_cursor.cursor == he_cache.cursor[idx-1]) {
+ 	p = (char *)he_cursor.cursor;
+ 	p += he_cursor.hdr.len;
+ 	he_cursor.cursor = (void *)p;
+     } else {
+ 	he_cursor.cursor = he_cache.cursor[idx-1];
+ 	if (get_he_hdr())
+ 	    return 1;
+ 	p = (char *)he_cursor.cursor;
+ 	p += he_cursor.hdr.len;
+ 	he_cursor.cursor = (void *)p;
+     }
+ 
+     he_cursor.idx = idx;
+     he_cache.cursor[idx] = he_cursor.cursor;
+ 
+     if (get_he_hdr())
+ 	return 1;
+     if (get_he_entry())
+ 	return 1;
+ 
+     return 0;
+ }
+ 
+ static int
+ get_he_hdr(void)
+ {
+     memcpy(&amp;he_cursor.hdr, he_cursor.cursor, sizeof(struct host_state_entry_header));
+     he_cursor.hdr_valid = 1;
+     return 0;
+ }
+ 
+ static int
+ get_he_entry(void)
+ {
+     char * p;
+ 
+     if (!he_cursor.hdr_valid) {
+ 	if (get_he_hdr()) {
+ 	    return 1;
+ 	}
+     }
+ 
+     p = (char *) he_cursor.cursor;
+     p += sizeof(struct host_state_entry_header);
+ 
+     memcpy(&amp;he_cursor.he, p, sizeof(struct hostDiskEntry));
+ 
+     he_cursor.he_valid = 1;
+     p += sizeof(struct hostDiskEntry);
+     he_cursor.ifp = (void *)p;
+     if (he_cursor.hdr.interfaces) {
+ 	p += sizeof(struct Interface) + ((he_cursor.hdr.interfaces-1)*sizeof(struct AddrPort));
+ 	he_cursor.hcps = (void *)p;
+     } else {
+ 	he_cursor.hcps = he_cursor.ifp;
+     }
+     return 0;
+ }
+ 
+ static int
+ get_fe(afs_uint32 idx)
+ {
+     int i;
+     char * p;
+ 
+     cb_cursor.cb_valid = 0;
+ 
+     if (get_cb_hdr())
+ 	return 1;
+ 
+     if (idx &gt;= hdrs.cb_hdr.nFEs)
+ 	return 1;
+ 
+     if (fe_cursor.idx == idx &amp;&amp; fe_cursor.hdr_valid &amp;&amp; fe_cursor.fe_valid)
+ 	return 0;
+ 
+     fe_cursor.hdr_valid = fe_cursor.fe_valid = 0;
+ 
+     if (fe_cache.cursor == NULL) {
+ 	fe_cache.cursor = (void **) calloc(hdrs.cb_hdr.nFEs, sizeof(void *));
+ 	assert(fe_cache.cursor != NULL);
+     }
+ 
+     if (idx &amp;&amp; fe_cache.cursor[idx-1] == NULL) {
+ 	for (i = 0; i &lt; idx; i++) {
+ 	    if (fe_cache.cursor[i] == NULL) {
+ 		get_fe(i);
+ 	    }
+ 	}
+     }
+ 
+     if (!idx) {
+ 	fe_cursor.cursor = fe_cursor.ffe;
+     } else if (fe_cursor.cursor == fe_cache.cursor[idx-1]) {
+ 	p = (char *)fe_cursor.cursor;
+ 	p += fe_cursor.hdr.len;
+ 	fe_cursor.cursor = (void *)p;
+     } else {
+ 	fe_cursor.cursor = fe_cache.cursor[idx-1];
+ 	if (get_fe_hdr())
+ 	    return 1;
+ 	p = (char *)fe_cursor.cursor;
+ 	p += fe_cursor.hdr.len;
+ 	fe_cursor.cursor = (void *)p;
+     }
+ 
+     fe_cursor.idx = idx;
+     fe_cache.cursor[idx] = fe_cursor.cursor;
+ 
+     if (get_fe_hdr())
+ 	return 1;
+     if (get_fe_entry())
+ 	return 1;
+ 
+     return 0;
+ }
+ 
+ static int
+ get_fe_hdr(void)
+ {
+     memcpy(&amp;fe_cursor.hdr, fe_cursor.cursor, sizeof(struct callback_state_entry_header));
+     fe_cursor.hdr_valid = 1;
+     return 0;
+ }
+ 
+ static int
+ get_fe_entry(void)
+ {
+     char * p;
+ 
+     if (!fe_cursor.hdr_valid) {
+ 	if (get_fe_hdr()) {
+ 	    return 1;
+ 	}
+     }
+ 
+     p = (char *) fe_cursor.cursor;
+     p += sizeof(struct callback_state_entry_header);
+ 
+     memcpy(&amp;fe_cursor.fe, p, sizeof(struct FEDiskEntry));
+ 
+     fe_cursor.fe_valid = 1;
+     p += sizeof(struct FEDiskEntry);
+     fe_cursor.fcb = (void *)p;
+     return 0;
+ }
+ 
+ static int
+ get_cb(afs_uint32 idx)
+ {
+     int i;
+     char * p;
+ 
+     if (get_fe(fe_cursor.idx))
+ 	return 1;
+ 
+     if (idx &gt;= fe_cursor.hdr.nCBs)
+ 	return 1;
+ 
+     if (idx == cb_cursor.idx &amp;&amp; cb_cursor.cb_valid)
+ 	return 0;
+ 
+     cb_cursor.cb_valid = 0;
+ 
+     p = (char *)fe_cursor.fcb;
+     p += idx * sizeof(struct CBDiskEntry);
+     cb_cursor.cursor = (void *)p;
+ 
+     cb_cursor.idx = idx;
+ 
+     if (get_cb_entry())
+ 	return 1;
+ 
+     return 0;
+ }
+ 
+ static int
+ get_cb_entry(void)
+ {
+     memcpy(&amp;cb_cursor.cb, cb_cursor.cursor, sizeof(struct CBDiskEntry));
+     cb_cursor.cb_valid = 1;
+     return 0;
+ }
+ 
+ static int
+ find_he_by_index(afs_uint32 idx)
+ {
+     int i;
+ 
+     if (get_h_hdr()) {
+ 	return 1;
+     }
+ 
+     for (i = 0; i &lt; hdrs.h_hdr.records; i++) {
+ 	if (get_he(i)) {
+ 	    fprintf(stderr, "error getting he %d\n", i);
+ 	    return 1;
+ 	}
+ 	if (he_cursor.he.index == idx)
+ 	    break;
+     }
+ 
+     if (i &lt; hdrs.h_hdr.records) {
+ 	dump_this_he();
+ 	return 0;
+     }
+     return 1;
+ }
+ 
+ static int
+ find_fe_by_index(afs_uint32 idx)
+ {
+     int i;
+ 
+     if (get_cb_hdr()) {
+ 	return 1;
+     }
+ 
+     for (i = 0; i &lt; hdrs.cb_hdr.nFEs; i++) {
+ 	if (get_fe(i)) {
+ 	    fprintf(stderr, "error getting fe %d\n", i);
+ 	    return 1;
+ 	}
+ 	if (fe_cursor.fe.index == idx)
+ 	    break;
+     }
+ 
+     if (i &lt; hdrs.cb_hdr.nFEs) {
+ 	dump_this_fe();
+ 	return 0;
+     }
+     return 1;
+ }
+ 
+ static int
+ find_fe_by_fid(afs_uint32 volid, afs_uint32 vnode, afs_uint32 unique)
+ {
+     int i;
+ 
+     if (get_cb_hdr()) {
+ 	return 1;
+     }
+ 
+     for (i = 0; i &lt; hdrs.cb_hdr.nFEs; i++) {
+ 	if (get_fe(i)) {
+ 	    fprintf(stderr, "error getting fe %d\n", i);
+ 	    return 1;
+ 	}
+ 	if ((fe_cursor.fe.fe.unique == unique) &amp;&amp;
+ 	    (fe_cursor.fe.fe.volid == volid) &amp;&amp;
+ 	    (fe_cursor.fe.fe.vnode == vnode))
+ 	    break;
+     }
+ 
+     if (i &lt; hdrs.cb_hdr.nFEs) {
+ 	dump_this_fe();
+ 	return 0;
+     }
+     return 1;
+ }
+ 
+ static int
+ find_cb_by_index(afs_uint32 idx)
+ {
+     int i;
+ 
+     if (get_fe_hdr()) {
+ 	return 1;
+     }
+ 
+     for (i = 0; i &lt; fe_cursor.hdr.nCBs; i++) {
+ 	if (get_cb(i)) {
+ 	    fprintf(stderr, "error getting cb %d\n", i);
+ 	    return 1;
+ 	}
+ 	if (cb_cursor.cb.index == idx)
+ 	    break;
+     }
+ 
+     if (i &lt; fe_cursor.hdr.nCBs) {
+ 	dump_this_cb();
+ 	return 0;
+     }
+     return 1;
+ }
+ 
+ #endif /* AFS_DEMAND_ATTACH_FS */
Index: openafs/src/tvolser/Makefile.in
diff -c openafs/src/tvolser/Makefile.in:1.3 openafs/src/tvolser/Makefile.in:1.4
*** openafs/src/tvolser/Makefile.in:1.3	Mon Aug  8 11:30:50 2005
--- openafs/src/tvolser/Makefile.in	Fri Mar 17 14:54:44 2006
***************
*** 10,16 ****
  HELPER_SPLINT=@HELPER_SPLINT@
  
  CC=${MT_CC}
! CFLAGS=${COMMON_CFLAGS} -I.. -DNINTERFACE ${MT_CFLAGS} -DRXDEBUG
  
  CCRULE=${CC} ${CFLAGS} -c $?
  
--- 10,16 ----
  HELPER_SPLINT=@HELPER_SPLINT@
  
  CC=${MT_CC}
! CFLAGS=${COMMON_CFLAGS} -I.. -DNINTERFACE ${MT_CFLAGS} -DRXDEBUG -DFSSYNC_BUILD_CLIENT
  
  CCRULE=${CC} ${CFLAGS} -c $?
  
***************
*** 36,43 ****
  
  DIROBJS=buffer.o dir.o salvage.o
  
! VOLOBJS= vnode.o volume.o vutil.o partition.o fssync.o purge.o \
! 	 clone.o devname.o common.o ihandle.o listinodes.o namei_ops.o nuke.o
  
  FSINTOBJS=# afsaux.o afscbint.cs.o afsint.ss.o afsint.xdr.o
  
--- 36,44 ----
  
  DIROBJS=buffer.o dir.o salvage.o
  
! VOLOBJS= vnode.o volume.o vutil.o partition.o fssync-client.o purge.o \
! 	 clone.o devname.o common.o ihandle.o listinodes.o \
! 	 namei_ops.o nuke.o salvsync-client.o daemon_com.o
  
  FSINTOBJS=# afsaux.o afscbint.cs.o afsint.ss.o afsint.xdr.o
  
***************
*** 138,144 ****
  nuke.o: ${VOL}/nuke.c
  	${COMPILE}
  
! fssync.o: ${VOL}/fssync.c
  	${COMPILE}
  
  purge.o: ${VOL}/purge.c
--- 139,151 ----
  nuke.o: ${VOL}/nuke.c
  	${COMPILE}
  
! fssync-client.o: ${VOL}/fssync-client.c
! 	${COMPILE}
! 
! salvsync-client.o: ${VOL}/salvsync-client.c
! 	${COMPILE}
! 
! daemon_com.o: ${VOL}/daemon_com.c
  	${COMPILE}
  
  purge.o: ${VOL}/purge.c
Index: openafs/src/tvolser/NTMakefile
diff -c /dev/null openafs/src/tvolser/NTMakefile:1.1
*** /dev/null	Thu Apr 27 12:42:31 2006
--- openafs/src/tvolser/NTMakefile	Mon Mar 20 11:01:22 2006
***************
*** 0 ****
--- 1,126 ----
+ # Copyright 2000, International Business Machines Corporation and others.
+ # All Rights Reserved.
+ # 
+ # This software has been released under the terms of the IBM Public
+ # License.  For details, see the LICENSE file in the top-level source
+ # directory or online at http://www.openafs.org/dl/license10.html
+ 
+ AFSDEV_AUXCDEFINES = -DAFS_PTHREAD_ENV -DRXDEBUG -DFSSYNC_BUILD_CLIENT
+ 
+ RELDIR=tvolser
+ !INCLUDE ..\config\NTMakefile.$(SYS_NAME)
+ !INCLUDE ..\config\NTMakefile.version
+ SRC_DIR = ..\volser
+ 
+ VICED = ..\viced
+ VLSERVER = ..\vlserver
+ LWP = ..\lwp
+ LIBACL = ..\libacl
+ UTIL = ..\util
+ DIR = ..\dir
+ VOLSER = ..\volser
+ VOL = ..\vol
+ FSINT = ..\fsint
+ RX = ..\rx
+ 
+ ############################################################################
+ # Definitions for installing header files
+ 
+ INCFILEDIR = $(DESTDIR)\include\afs  # header file install directory
+ 
+ INCFILES = \
+ 	$(INCFILEDIR)\volser_prototypes.h \
+ 	$(INCFILEDIR)\volser.h \
+ 	$(INCFILEDIR)\volint.h
+ 
+ 
+ LOCAL_INCFILES = \
+ 	volser.h \
+ 	volint.h
+ 
+ ############################################################################
+ # Build volserver
+ 
+ VOLSERVER_EXEFILE = $(DESTDIR)\root.server\usr\afs\bin\volserver.exe
+ 
+ VOLSEROBJS=$(OUT)\volmain.obj $(OUT)\volprocs.obj $(OUT)\physio.obj $(OUT)\voltrans.obj $(OUT)\volerr.obj $(OUT)\volint.cs.obj $(OUT)\dumpstuff.obj  $(OUT)\volint.ss.obj $(OUT)\volint.xdr.obj $(OUT)\vscommon.obj
+ 
+ LWPOBJS=$(OUT)\lock.obj $(OUT)\threadname.obj
+ 
+ LIBACLOBJS=$(OUT)\aclprocs.obj $(OUT)\netprocs.obj
+ 
+ UTILOBJS=$(OUT)\assert.obj $(OUT)\uuid.obj $(OUT)\serverLog.obj $(OUT)\fileutil.obj $(OUT)\netutils.obj $(OUT)\dirpath.obj $(OUT)\volparse.obj $(OUT)\flipbase64.obj $(OUT)\softsig.obj
+ 
+ DIROBJS=$(OUT)\buffer.obj $(OUT)\dir.obj $(OUT)\salvage.obj
+ 
+ VOLOBJS= $(OUT)\vnode.obj $(OUT)\volume.obj $(OUT)\vutil.obj $(OUT)\partition.obj $(OUT)\fssync-client.obj $(OUT)\purge.obj $(OUT)\clone.obj $(OUT)\devname.obj $(OUT)\common.obj $(OUT)\ihandle.obj $(OUT)\listinodes.obj $(OUT)\namei_ops.obj $(OUT)\nuke.obj $(OUT)\salvsync-client.obj $(OUT)\daemon_com.obj
+ 
+ 
+ VOLSERVER_EXEOBJS = $(VOLSEROBJS) $(VLSERVEROBJS) $(LWPOBJS) $(LIBACLOBJS) $(UTILOBJS) $(DIROBJS) $(VOLOBJS) $(FSINTOBJS)
+ 
+ VOLSERVER_EXELIBS = \
+ 	$(DESTDIR)\lib\afsauthent.lib \
+ 	$(DESTDIR)\lib\afsrpc.lib \
+ 	$(DESTDIR)\lib\afs\afscmd.lib \
+ 	$(DESTDIR)\lib\afs\afsaudit.lib \
+ 	$(DESTDIR)\lib/afs/afscom_err.lib \
+ 	$(DESTDIR)\lib\afs\afsreg.lib \
+ 	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
+ 	$(DESTDIR)\lib\afs\afseventlog.lib \
+ 	$(DESTDIR)\lib\afs\afsutil.lib \
+ 	$(DESTDIR)\lib\afspthread.lib
+ 
+ $(VOLSERVER_EXEFILE): $(VOLSERVER_EXEOBJS) $(VOLSERVER_EXELIBS) 
+ 	$(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib
+         $(_VC_MANIFEST_EMBED_EXE)
+ 	$(EXEPREP) 
+ 
+ $(VOLSEROBJS): $(VOLSER)\$$(@B).c
+         $(C2OBJ) -I$(VOLSER) -I$(UTIL) $**
+ 
+ $(VICEDOBJS): $(VICED)\$$(@B).c
+ 	$(C2OBJ) -I$(VICED) -I$(UTIL) $**
+ 
+ $(UTILOBJS): $(UTIL)\$$(@B).c
+ 	$(C2OBJ) -I$(UTIL) $**
+ 
+ $(LWPOBJS): $(LWP)\$$(@B).C
+ 	$(C2OBJ) -I$(LWP) $**
+ 
+ $(LIBACLOBJS): $(LIBACL)\$$(@B).C
+ 	$(C2OBJ) -I$(LIBACL) $**
+ 
+ $(UTILOBJS): $(UTILACL)\$$(@B).C
+ 	$(C2OBJ) -I$(UTILACL) $**
+ 
+ $(VLSERVEROBJS): $(VLSERVER)\$$(@B).C
+ 	$(C2OBJ) -I$(VLSERVER) $**
+ 
+ $(DIROBJS): $(DIR)\$$(@B).C
+ 	$(C2OBJ) -I$(DIR) $**
+ 
+ $(VOLOBJS): $(VOL)\$$(@B).C
+ 	$(C2OBJ) -I$(VOL) $**
+ 
+ $(FSINTOBJS): $(FSINT)\$$(@B).C
+ 	$(C2OBJ) -I$(FSINT) $**
+ 
+ ############################################################################
+ # Generate versioninfo resources
+ $(OUT)\volserver.res: AFS_component_version_number.h
+ 
+ ############################################################################
+ # Install target; primary makefile target
+ 
+ install: $(LOCAL_INCFILES) $(LIBFILE) $(VOLSERVER_EXEFILE) $(CL_VOS_EXEFILE) \
+ 		$(INCFILES)
+ 
+ 
+ ############################################################################
+ # Local clean target; augments predefined clean target
+ 
+ clean::
+ 	$(DEL) volerr.c volser.h $(INCFILES)
+ 	$(DEL) volint.cs.c volint.h volint.ss.c volint.xdr.c volser.h
+ 
+ mkdir:
Index: openafs/src/ubik/phys.c
diff -c openafs/src/ubik/phys.c:1.8 openafs/src/ubik/phys.c:1.9
*** openafs/src/ubik/phys.c:1.8	Tue Jul 15 19:17:05 2003
--- openafs/src/ubik/phys.c	Thu Mar  9 01:35:00 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ubik/phys.c,v 1.8 2003/07/15 23:17:05 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #ifdef AFS_NT40_ENV
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/ubik/phys.c,v 1.9 2006/03/09 06:35:00 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #ifdef AFS_NT40_ENV
***************
*** 276,282 ****
      thdr.version.epoch = htonl(aversion-&gt;epoch);
      thdr.version.counter = htonl(aversion-&gt;counter);
      thdr.magic = htonl(UBIK_MAGIC);
!     thdr.size = htonl(HDRSIZE);
      code = write(fd, &amp;thdr, sizeof(thdr));
      fsync(fd);			/* preserve over crash */
      uphys_close(fd);
--- 276,282 ----
      thdr.version.epoch = htonl(aversion-&gt;epoch);
      thdr.version.counter = htonl(aversion-&gt;counter);
      thdr.magic = htonl(UBIK_MAGIC);
!     thdr.size = htons(HDRSIZE);
      code = write(fd, &amp;thdr, sizeof(thdr));
      fsync(fd);			/* preserve over crash */
      uphys_close(fd);
Index: openafs/src/usd/Makefile.in
diff -c openafs/src/usd/Makefile.in:1.6 openafs/src/usd/Makefile.in:1.7
*** openafs/src/usd/Makefile.in:1.6	Thu Nov  1 00:01:09 2001
--- openafs/src/usd/Makefile.in	Thu Mar  9 01:35:01 2006
***************
*** 10,16 ****
  
  
  
! CFLAGS=-I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
  
  all: ${TOP_LIBDIR}/libusd.a ${TOP_INCDIR}/afs/usd.h
  
--- 10,16 ----
  
  
  
! CFLAGS=-I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS}
  
  all: ${TOP_LIBDIR}/libusd.a ${TOP_INCDIR}/afs/usd.h
  
Index: openafs/src/usd/test/Makefile.in
diff -c openafs/src/usd/test/Makefile.in:1.5 openafs/src/usd/test/Makefile.in:1.6
*** openafs/src/usd/test/Makefile.in:1.5	Tue Oct 15 23:59:17 2002
--- openafs/src/usd/test/Makefile.in	Thu Mar  9 01:35:02 2006
***************
*** 10,16 ****
  
  
  INCDIRS= -I${DESTDIR}/include  -I..
! CFLAGS = $(DBUG) -I${SRCDIR}/include ${INCDIRS} ${XCFLAGS}
  LIBUSD=DEST/lib/afs/libusd.a
  
  #####################################################################
--- 10,16 ----
  
  
  INCDIRS= -I${DESTDIR}/include  -I..
! CFLAGS = $(DBUG) -I${SRCDIR}/include ${INCDIRS} ${XCFLAGS} ${ARCHFLAGS}
  LIBUSD=DEST/lib/afs/libusd.a
  
  #####################################################################
Index: openafs/src/uss/Makefile.in
diff -c openafs/src/uss/Makefile.in:1.7 openafs/src/uss/Makefile.in:1.8
*** openafs/src/uss/Makefile.in:1.7	Thu Jun 19 12:55:10 2003
--- openafs/src/uss/Makefile.in	Thu Mar  9 01:35:03 2006
***************
*** 13,19 ****
  all: uss
  
  CFLAGS=-I. -I${srcdir} ${DBUG} -I${TOP_OBJDIR}/src/config \
! 	-I${TOP_INCDIR} -I. ${XCFLAGS}
  
  #
  # Build targets
--- 13,19 ----
  all: uss
  
  CFLAGS=-I. -I${srcdir} ${DBUG} -I${TOP_OBJDIR}/src/config \
! 	-I${TOP_INCDIR} -I. ${XCFLAGS} ${ARCHFLAGS}
  
  #
  # Build targets
Index: openafs/src/util/Makefile.am
diff -c openafs/src/util/Makefile.am:1.1 openafs/src/util/Makefile.am:1.2
*** openafs/src/util/Makefile.am:1.1	Tue Jun  5 16:17:53 2001
--- openafs/src/util/Makefile.am	Thu Mar  9 01:35:05 2006
***************
*** 1,4 ****
! # $Id: Makefile.am,v 1.1 2001/06/05 20:17:53 shadow Exp $
  
  include $(top_srcdir)/Makefile.am.common
  
--- 1,4 ----
! # $Id: Makefile.am,v 1.2 2006/03/09 06:35:05 shadow Exp $
  
  include $(top_srcdir)/Makefile.am.common
  
***************
*** 27,31 ****
  	flipbase64.c	\
  	afs_atomlist.c	\
  	afs_lhash.c	\
! 	snprintf.c
  
--- 27,32 ----
  	flipbase64.c	\
  	afs_atomlist.c	\
  	afs_lhash.c	\
! 	snprintf.c	\
! 	fstab.c
  
Index: openafs/src/util/Makefile.in
diff -c openafs/src/util/Makefile.in:1.30 openafs/src/util/Makefile.in:1.32
*** openafs/src/util/Makefile.in:1.30	Sat Jun 18 20:14:18 2005
--- openafs/src/util/Makefile.in	Fri Mar 17 14:54:46 2006
***************
*** 12,19 ****
  
  objects = assert.o base64.o casestrcpy.o ktime.o volparse.o hostparse.o \
  	 hputil.o kreltime.o isathing.o get_krbrlm.o uuid.o serverLog.o \
! 	 dirpath.o fileutil.o netutils.o flipbase64.o \
! 	 afs_atomlist.o afs_lhash.o snprintf.o strlcat.o strlcpy.o \
  	 daemon.o rxkstats.o ${REGEX_OBJ}
  
  includes = \
--- 12,19 ----
  
  objects = assert.o base64.o casestrcpy.o ktime.o volparse.o hostparse.o \
  	 hputil.o kreltime.o isathing.o get_krbrlm.o uuid.o serverLog.o \
! 	 dirpath.o fileutil.o netutils.o flipbase64.o fstab.o \
! 	 afs_atomlist.o afs_lhash.o snprintf.o strlcat.o strlcpy.o strnlen.o \
  	 daemon.o rxkstats.o ${REGEX_OBJ}
  
  includes = \
***************
*** 80,85 ****
--- 80,88 ----
  snprintf.o: ${srcdir}/snprintf.c ${includes}
  	${CCOBJ} ${CFLAGS} -c ${srcdir}/snprintf.c
  
+ fstab.o: ${srcdir}/fstab.c ${includes}
+ 	${CCOBJ} ${CFLAGS} -c ${srcdir}/fstab.c
+ 
  base64.o: ${srcdir}/base64.c ${includes}
  	${CCOBJ} ${CFLAGS} -c ${srcdir}/base64.c
  
***************
*** 131,136 ****
--- 134,142 ----
  strlcpy.o: ${srcdir}/strlcpy.c ${includes}
  	${CCOBJ} ${CFLAGS} -c ${srcdir}/strlcpy.c
  
+ strnlen.o: ${srcdir}/strnlen.c ${includes}
+ 	${CCOBJ} ${CFLAGS} -c ${srcdir}/strnlen.c
+ 
  daemon.o: ${srcdir}/daemon.c ${includes}
  	${CCOBJ} ${CFLAGS} -c ${srcdir}/daemon.c
  
***************
*** 389,392 ****
  	    assert.c base64.c casestrcpy.c ktime.c volparse.c hostparse.c \
  	    hputil.c kreltime.c isathing.c get_krbrlm.c uuid.c serverLog.c \
  	    dirpath.c fileutil.c netutils.c flipbase64.c \
! 	    afs_atomlist.c afs_lhash.c snprintf.c
--- 395,398 ----
  	    assert.c base64.c casestrcpy.c ktime.c volparse.c hostparse.c \
  	    hputil.c kreltime.c isathing.c get_krbrlm.c uuid.c serverLog.c \
  	    dirpath.c fileutil.c netutils.c flipbase64.c \
! 	    afs_atomlist.c afs_lhash.c snprintf.c fstab.c
Index: openafs/src/util/NTMakefile
diff -c openafs/src/util/NTMakefile:1.11 openafs/src/util/NTMakefile:1.14
*** openafs/src/util/NTMakefile:1.11	Sat Oct  9 20:25:21 2004
--- openafs/src/util/NTMakefile	Sun Apr  2 19:44:56 2006
***************
*** 48,59 ****
  	$(OUT)\regex.obj \
  	$(OUT)\readdir_nt.obj \
  	$(OUT)\serverLog.obj \
!     $(OUT)\snprintf.obj \
  	$(OUT)\uuid.obj \
  	$(OUT)\volparse.obj \
  	$(OUT)\winsock_nt.obj \
  	$(OUT)\errmap_nt.obj \
  	$(OUT)\dirpath.obj \
  	$(OUT)\fileutil.obj \
  	$(OUT)\secutil_nt.obj
  
--- 48,62 ----
  	$(OUT)\regex.obj \
  	$(OUT)\readdir_nt.obj \
  	$(OUT)\serverLog.obj \
!     	$(OUT)\snprintf.obj \
!     	$(OUT)\strlcat.obj \
  	$(OUT)\uuid.obj \
  	$(OUT)\volparse.obj \
  	$(OUT)\winsock_nt.obj \
  	$(OUT)\errmap_nt.obj \
  	$(OUT)\dirpath.obj \
+ 	$(OUT)\strnlen.obj \
+ 	$(OUT)\strlcpy.obj \
  	$(OUT)\fileutil.obj \
  	$(OUT)\secutil_nt.obj
  
Index: openafs/src/util/afsutil.h
diff -c openafs/src/util/afsutil.h:1.19 openafs/src/util/afsutil.h:1.21
*** openafs/src/util/afsutil.h:1.19	Sat Jul  2 12:59:50 2005
--- openafs/src/util/afsutil.h	Wed Mar 15 14:32:49 2006
***************
*** 22,29 ****
--- 22,37 ----
  
  /* logging defines
   */
+ #ifndef AFS_NT40_ENV
+ #include &lt;sys/types.h&gt;
+ #include &lt;sys/socket.h&gt;
+ #include &lt;netinet/in.h&gt;
+ #include &lt;arpa/inet.h&gt; /* for inet_ntoa() */
+ #endif
+ 
  #include &lt;stdio.h&gt;
  #include &lt;stdarg.h&gt;
+ 
  extern int LogLevel;
  extern int mrafsStyleLogs;
  #ifndef AFS_NT40_ENV
Index: openafs/src/util/afsutil_prototypes.h
diff -c openafs/src/util/afsutil_prototypes.h:1.14 openafs/src/util/afsutil_prototypes.h:1.16
*** openafs/src/util/afsutil_prototypes.h:1.14	Wed Dec  7 20:13:41 2005
--- openafs/src/util/afsutil_prototypes.h	Fri Mar 17 14:54:46 2006
***************
*** 75,81 ****
  /* get_krbrlm.c */
  extern int afs_krb_get_lrealm(char *r, int n);
  extern int afs_krb_exclusion(char *name);
! extern int afs_is_foreign_ticket_name(char *tcell, char *tname, char *tinst, char *localrealm);
  /* hostparse.c */
  extern struct hostent *hostutil_GetHostByName(register char *ahost);
  extern char *hostutil_GetNameByINet(afs_uint32 addr);
--- 75,81 ----
  /* get_krbrlm.c */
  extern int afs_krb_get_lrealm(char *r, int n);
  extern int afs_krb_exclusion(char *name);
! extern int afs_is_foreign_ticket_name(char *tname, char *tinst, char * tcell, char *localrealm);
  /* hostparse.c */
  extern struct hostent *hostutil_GetHostByName(register char *ahost);
  extern char *hostutil_GetNameByINet(afs_uint32 addr);
***************
*** 173,178 ****
--- 173,181 ----
  extern size_t strlcat(char *dst, const char *src, size_t siz);
  #endif
  
+ /* strn */
+ extern size_t afs_strnlen(char * buf, size_t len);
+ 
  
  /* sys.c */
  
***************
*** 184,189 ****
--- 187,196 ----
  extern void afs_ntohuuid(afsUUID * uuidp);
  extern afs_int32 afs_uuid_create(afsUUID * uuid);
  extern u_short afs_uuid_hash(afsUUID * uuid);
+ #if !defined(KERNEL) &amp;&amp; !defined(UKERNEL)
+ extern int afsUUID_from_string(const char *str, afsUUID * uuid);
+ extern int afsUUID_to_string(const afsUUID * uuid, char *str, size_t strsz);
+ #endif
  
  /* volparse.c */
  extern afs_int32 volutil_GetPartitionID(char *aname);
Index: openafs/src/util/dirpath.c
diff -c openafs/src/util/dirpath.c:1.18 openafs/src/util/dirpath.c:1.19
*** openafs/src/util/dirpath.c:1.18	Wed Dec  7 20:13:41 2005
--- openafs/src/util/dirpath.c	Fri Mar 17 14:54:46 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/dirpath.c,v 1.18 2005/12/08 01:13:41 jaltman Exp $");
  
  #include &lt;stddef.h&gt;
  #include &lt;stdlib.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/dirpath.c,v 1.19 2006/03/17 19:54:46 shadow Exp $");
  
  #include &lt;stddef.h&gt;
  #include &lt;stdlib.h&gt;
***************
*** 292,301 ****
--- 292,308 ----
      pathp = dirPathArray[AFSDIR_SERVER_SLVGLOG_FILEPATH_ID];
      AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SLVGLOG_FILE);
  
+     pathp = dirPathArray[AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID];
+     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SALSRVLOG_FILE);
+ 
      pathp = dirPathArray[AFSDIR_SERVER_SALVAGER_FILEPATH_ID];
      AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
  			   AFSDIR_SALVAGER_FILE);
  
+     pathp = dirPathArray[AFSDIR_SERVER_SALSRV_FILEPATH_ID];
+     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
+ 			   AFSDIR_SALSRV_FILE);
+ 
      pathp = dirPathArray[AFSDIR_SERVER_SLVGLOCK_FILEPATH_ID];
      AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SLVGLOCK_FILE);
  
***************
*** 368,373 ****
--- 375,383 ----
      pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID];
      AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KRB_EXCL_FILE);
  
+     pathp = dirPathArray[AFSDIR_SERVER_FSSTATE_FILEPATH_ID];
+     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_FSSTATE_FILE);
+ 
      /* client file paths */
  #ifdef AFS_NT40_ENV
      strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID],
Index: openafs/src/util/dirpath.hin
diff -c openafs/src/util/dirpath.hin:1.5 openafs/src/util/dirpath.hin:1.6
*** openafs/src/util/dirpath.hin:1.5	Sat Dec 10 13:47:40 2005
--- openafs/src/util/dirpath.hin	Fri Mar 17 14:54:46 2006
***************
*** 135,141 ****
--- 135,143 ----
  #define AFSDIR_VLOG_FILE        "VLLog"
  #define AFSDIR_CORE_FILE        "core"
  #define AFSDIR_SLVGLOG_FILE     "SalvageLog"
+ #define AFSDIR_SALSRVLOG_FILE   "SalsrvLog"
  #define AFSDIR_SALVAGER_FILE    "salvager"
+ #define AFSDIR_SALSRV_FILE      "salvageserver"
  #define AFSDIR_SLVGLOCK_FILE    "salvage.lock"
  #define AFSDIR_BOZCONF_FILE     "BosConfig"
  #define AFSDIR_BOZCONFNEW_FILE  "BosConfig.new"
***************
*** 155,160 ****
--- 157,164 ----
  #define AFSDIR_FILELOG_FILE     "FileLog"
  #define AFSDIR_MIGRATE_LOGNAME  "wtlog."
  
+ #define AFSDIR_FSSTATE_FILE     "fsstate.dat"
+ 
  #define AFSDIR_CELLSERVDB_FILE_NTCLIENT  "afsdcell.ini"
  
  #define AFSDIR_NETINFO_FILE     "NetInfo"
***************
*** 194,202 ****
--- 198,212 ----
  #define AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH \
  AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/" AFSDIR_SALVAGER_FILE
  
+ #define AFSDIR_CANONICAL_SERVER_SALSRV_FILEPATH \
+ AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/" AFSDIR_SALSRV_FILE
+ 
  #define AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH \
  AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH "/" AFSDIR_SLVGLOG_FILE
  
+ #define AFSDIR_CANONICAL_SERVER_SALSRVLOG_FILEPATH \
+ AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH "/" AFSDIR_SALSRVLOG_FILE
+ 
  
  /* ---------------------  Local path macros ---------------------- */
  
***************
*** 264,269 ****
--- 274,282 ----
        AFSDIR_SERVER_BIN_FILE_DIRPATH_ID,
        AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID,
        AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID,
+       AFSDIR_SERVER_SALSRV_FILEPATH_ID,
+       AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID,
+       AFSDIR_SERVER_FSSTATE_FILEPATH_ID,
        AFSDIR_PATHSTRING_MAX } afsdir_id_t;
  
  /* getDirPath() returns a pointer to a string from an internal array of path strings 
***************
*** 310,316 ****
--- 323,331 ----
  #define AFSDIR_SERVER_VLOG_FILEPATH getDirPath(AFSDIR_SERVER_VLOG_FILEPATH_ID)
  #define AFSDIR_SERVER_CORELOG_FILEPATH getDirPath(AFSDIR_SERVER_CORELOG_FILEPATH_ID)
  #define AFSDIR_SERVER_SLVGLOG_FILEPATH getDirPath(AFSDIR_SERVER_SLVGLOG_FILEPATH_ID)
+ #define AFSDIR_SERVER_SALSRVLOG_FILEPATH getDirPath(AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID)
  #define AFSDIR_SERVER_SALVAGER_FILEPATH getDirPath(AFSDIR_SERVER_SALVAGER_FILEPATH_ID)
+ #define AFSDIR_SERVER_SALSRV_FILEPATH getDirPath(AFSDIR_SERVER_SALSRV_FILEPATH_ID)
  #define AFSDIR_SERVER_BOZCONF_FILEPATH getDirPath(AFSDIR_SERVER_BOZCONF_FILEPATH_ID)
  #define AFSDIR_SERVER_BOZCONFNEW_FILEPATH getDirPath(AFSDIR_SERVER_BOZCONFNEW_FILEPATH_ID)
  #define AFSDIR_SERVER_BOZINIT_FILEPATH getDirPath(AFSDIR_SERVER_BOZINIT_FILEPATH_ID)
***************
*** 332,337 ****
--- 347,353 ----
  #define AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH getDirPath(AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID)
  #define AFSDIR_SERVER_MIGRATELOG_FILEPATH getDirPath(AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID)
  #define AFSDIR_SERVER_KRB_EXCL_FILEPATH getDirPath(AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID)
+ #define AFSDIR_SERVER_FSSTATE_FILEPATH getDirPath(AFSDIR_SERVER_FSSTATE_FILEPATH_ID)
  
  /* client file paths */
  #define AFSDIR_CLIENT_THISCELL_FILEPATH getDirPath(AFSDIR_CLIENT_THISCELL_FILEPATH_ID)
Index: openafs/src/util/dirpath_nt.h
diff -c openafs/src/util/dirpath_nt.h:1.7 openafs/src/util/dirpath_nt.h:1.8
*** openafs/src/util/dirpath_nt.h:1.7	Wed Dec  7 20:13:41 2005
--- openafs/src/util/dirpath_nt.h	Fri Mar 17 14:54:46 2006
***************
*** 126,132 ****
--- 126,134 ----
  #define AFSDIR_VLOG_FILE        "VLLog"
  #define AFSDIR_CORE_FILE        "core"
  #define AFSDIR_SLVGLOG_FILE     "SalvageLog"
+ #define AFSDIR_SALSRVLOG_FILE   "SalsrvLog"
  #define AFSDIR_SALVAGER_FILE    "salvager"
+ #define AFSDIR_SALSRV_FILE      "salvageserver"
  #define AFSDIR_SLVGLOCK_FILE    "salvage.lock"
  #define AFSDIR_BOZCONF_FILE     "BosConfig"
  #define AFSDIR_BOZCONFNEW_FILE  "BosConfig.new"
***************
*** 146,151 ****
--- 148,155 ----
  #define AFSDIR_FILELOG_FILE     "FileLog"
  #define AFSDIR_MIGRATE_LOGNAME  "wtlog."
  
+ #define AFSDIR_FSSTATE_FILE     "fsstate.dat"
+ 
  #ifdef COMMENT
  #define AFSDIR_CELLSERVDB_FILE_NTCLIENT  "afsdcell.ini"
  #else
***************
*** 189,197 ****
--- 193,207 ----
  #define AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH \
  AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/" AFSDIR_SALVAGER_FILE
  
+ #define AFSDIR_CANONICAL_SERVER_SALSRV_FILEPATH \
+ AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/" AFSDIR_SALSRV_FILE
+ 
  #define AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH \
  AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH "/" AFSDIR_SLVGLOG_FILE
  
+ #define AFSDIR_CANONICAL_SERVER_SALSRVLOG_FILEPATH \
+ AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH "/" AFSDIR_SALSRVLOG_FILE
+ 
  
  /* ---------------------  Local path macros ---------------------- */
  
***************
*** 259,264 ****
--- 269,277 ----
      AFSDIR_SERVER_BIN_FILE_DIRPATH_ID,
      AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID,
      AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID,
+     AFSDIR_SERVER_SALSRV_FILEPATH_ID,
+     AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID,
+     AFSDIR_SERVER_FSSTATE_FILEPATH_ID,
      AFSDIR_PATHSTRING_MAX
  } afsdir_id_t;
  
***************
*** 306,312 ****
--- 319,327 ----
  #define AFSDIR_SERVER_VLOG_FILEPATH getDirPath(AFSDIR_SERVER_VLOG_FILEPATH_ID)
  #define AFSDIR_SERVER_CORELOG_FILEPATH getDirPath(AFSDIR_SERVER_CORELOG_FILEPATH_ID)
  #define AFSDIR_SERVER_SLVGLOG_FILEPATH getDirPath(AFSDIR_SERVER_SLVGLOG_FILEPATH_ID)
+ #define AFSDIR_SERVER_SALSRVLOG_FILEPATH getDirPath(AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID)
  #define AFSDIR_SERVER_SALVAGER_FILEPATH getDirPath(AFSDIR_SERVER_SALVAGER_FILEPATH_ID)
+ #define AFSDIR_SERVER_SALSRV_FILEPATH getDirPath(AFSDIR_SERVER_SALSRV_FILEPATH_ID)
  #define AFSDIR_SERVER_BOZCONF_FILEPATH getDirPath(AFSDIR_SERVER_BOZCONF_FILEPATH_ID)
  #define AFSDIR_SERVER_BOZCONFNEW_FILEPATH getDirPath(AFSDIR_SERVER_BOZCONFNEW_FILEPATH_ID)
  #define AFSDIR_SERVER_BOZINIT_FILEPATH getDirPath(AFSDIR_SERVER_BOZINIT_FILEPATH_ID)
***************
*** 328,333 ****
--- 343,349 ----
  #define AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH getDirPath(AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID)
  #define AFSDIR_SERVER_MIGRATELOG_FILEPATH getDirPath(AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID)
  #define AFSDIR_SERVER_KRB_EXCL_FILEPATH getDirPath(AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID)
+ #define AFSDIR_SERVER_FSSTATE_FILEPATH getDirPath(AFSDIR_SERVER_FSSTATE_FILEPATH_ID)
  
  /* client file paths */
  #define AFSDIR_CLIENT_THISCELL_FILEPATH getDirPath(AFSDIR_CLIENT_THISCELL_FILEPATH_ID)
Index: openafs/src/util/errors.h
diff -c openafs/src/util/errors.h:1.4 openafs/src/util/errors.h:1.5
*** openafs/src/util/errors.h:1.4	Tue Jul 15 19:17:16 2003
--- openafs/src/util/errors.h	Fri Mar 17 14:54:46 2006
***************
*** 50,55 ****
--- 50,56 ----
  				 * to THIS server to find out where */
  #define VIO		112	/* Vnode temporarily unaccessible, but not known 
  				 * to be permanently bad. */
+ #define VSALVAGING      113     /* Volume is being salvaged (demand attach fs) */
  #define VRESTRICTED     120	/* Volume is restricted from using one or more
  				 * of the given residencies; do a
  				 * vos examine to find out the current
Index: openafs/src/util/fstab.c
diff -c /dev/null openafs/src/util/fstab.c:1.1
*** /dev/null	Thu Apr 27 12:42:31 2006
--- openafs/src/util/fstab.c	Thu Mar  9 01:38:36 2006
***************
*** 0 ****
--- 1,181 ----
+ /*
+  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+  *
+  * @APPLE_LICENSE_HEADER_START@
+  * 
+  * This file contains Original Code and/or Modifications of Original Code
+  * as defined in and that are subject to the Apple Public Source License
+  * Version 2.0 (the 'License'). You may not use this file except in
+  * compliance with the License. Please obtain a copy of the License at
+  * http://www.opensource.apple.com/apsl/ and read it before using this
+  * file.
+  * 
+  * The Original Code and all software distributed under the License are
+  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+  * Please see the License for the specific language governing rights and
+  * limitations under the License.
+  * 
+  * @APPLE_LICENSE_HEADER_END@
+  */
+ /*
+  * Copyright (c) 1980, 1988, 1993
+  *	The Regents of the University of California.  All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *	This product includes software developed by the University of
+  *	California, Berkeley and its contributors.
+  * 4. Neither the name of the University nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #include &lt;afs/param.h&gt;
+ 
+ #if defined(AFS_DARWIN_ENV)
+ /*-----------------------------------------------------------------------
+  * This version of fstab.c is intended to be used on Darwin systems to
+  * replace getfsent() and family.  It has been modified so that rather
+  * than read /etc/fstab, it calls getfsstat() to get the real list of
+  * mounted volumes.
+  *-----------------------------------------------------------------------*/
+ 
+ #include &lt;errno.h&gt;
+ #include &lt;fstab.h&gt;
+ #include &lt;stdio.h&gt;
+ #include &lt;string.h&gt;
+ #include &lt;stdlib.h&gt;
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/ucred.h&gt;
+ #include &lt;sys/mount.h&gt;
+ 
+ #define	STDERR_FILENO	2
+ 
+ static struct fstab _fs_fstab;
+ static struct statfs *_fs_buf;
+ static struct statfs *_fs_ptr;
+ static int _fs_count;
+ 
+ static error __P((int));
+ static fstabscan __P((void));
+ 
+ static
+ fstabscan()
+ {
+     if (_fs_count &lt;= 0)
+ 	return (0);
+     _fs_fstab.fs_spec = _fs_ptr-&gt;f_mntfromname;
+     _fs_fstab.fs_file = _fs_ptr-&gt;f_mntonname;
+     _fs_fstab.fs_vfstype = _fs_ptr-&gt;f_fstypename;
+     _fs_fstab.fs_mntops = _fs_ptr-&gt;f_fstypename;	// no mount options given
+     _fs_fstab.fs_type = (_fs_ptr-&gt;f_flags &amp; MNT_RDONLY) ? FSTAB_RO : FSTAB_RW;
+     _fs_fstab.fs_freq = 0;
+     _fs_fstab.fs_passno = 0;
+ 
+     _fs_ptr++;
+     _fs_count--;
+     return (1);
+ }
+ 
+ struct fstab *
+ getfsent()
+ {
+     if (!_fs_buf &amp;&amp; !setfsent() || !fstabscan())
+ 	return ((struct fstab *)NULL);
+     return (&amp;_fs_fstab);
+ }
+ 
+ struct fstab *
+ getfsspec(name)
+      register const char *name;
+ {
+     if (setfsent())
+ 	while (fstabscan())
+ 	    if (!strcmp(_fs_fstab.fs_spec, name))
+ 		return (&amp;_fs_fstab);
+     return ((struct fstab *)NULL);
+ }
+ 
+ struct fstab *
+ getfsfile(name)
+      register const char *name;
+ {
+     if (setfsent())
+ 	while (fstabscan())
+ 	    if (!strcmp(_fs_fstab.fs_file, name))
+ 		return (&amp;_fs_fstab);
+     return ((struct fstab *)NULL);
+ }
+ 
+ setfsent()
+ {
+     long bufsize;
+ 
+     if (_fs_buf) {
+ 	free(_fs_buf);
+ 	_fs_buf = NULL;
+     }
+     if ((_fs_count = getfsstat(NULL, 0, MNT_WAIT)) &lt; 0) {
+ 	error(errno);
+ 	return (0);
+     }
+     bufsize = (long)_fs_count *sizeof(struct statfs);
+     if ((_fs_buf = malloc(bufsize)) == NULL) {
+ 	error(errno);
+ 	return (0);
+     }
+     if (getfsstat(_fs_buf, bufsize, MNT_WAIT) &lt; 0) {
+ 	error(errno);
+ 	return (0);
+     }
+     _fs_ptr = _fs_buf;
+     return (1);
+ }
+ 
+ void
+ endfsent()
+ {
+     if (_fs_buf) {
+ 	free(_fs_buf);
+ 	_fs_buf = NULL;
+     }
+     _fs_count = 0;
+ }
+ 
+ static
+ error(err)
+      int err;
+ {
+     char *p;
+ 
+     (void)write(STDERR_FILENO, "fstab: ", 7);
+     (void)write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1);
+     (void)write(STDERR_FILENO, ": ", 1);
+     p = strerror(err);
+     (void)write(STDERR_FILENO, p, strlen(p));
+     (void)write(STDERR_FILENO, "\n", 1);
+ }
+ #endif /* defined(AFS_DARWIN_ENV) */
Index: openafs/src/util/get_krbrlm.c
diff -c openafs/src/util/get_krbrlm.c:1.8 openafs/src/util/get_krbrlm.c:1.9
*** openafs/src/util/get_krbrlm.c:1.8	Thu Dec 15 00:51:24 2005
--- openafs/src/util/get_krbrlm.c	Mon Mar 13 10:09:47 2006
***************
*** 7,13 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/get_krbrlm.c,v 1.8 2005/12/15 05:51:24 jaltman Exp $");
  
  #include &lt;stdio.h&gt;
  #include "afsutil.h"
--- 7,13 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/get_krbrlm.c,v 1.9 2006/03/13 15:09:47 jaltman Exp $");
  
  #include &lt;stdio.h&gt;
  #include "afsutil.h"
***************
*** 114,120 ****
  }
  
  int 
! afs_is_foreign_ticket_name(char *tcell, char *tname, char *tinst, char *localrealm)
  {
      int foreign = 0;
  
--- 114,120 ----
  }
  
  int 
! afs_is_foreign_ticket_name(char *tname, char *tinst, char * tcell, char *localrealm)
  {
      int foreign = 0;
  
***************
*** 134,140 ****
  		    break;
  	    }
  
! 	    if (i=0 &amp;&amp; localrealm) {
  		strncpy(local_realms[0], localrealm, AFS_REALM_SZ);
  		num_lrealms = 1;
  	    } else {
--- 134,140 ----
  		    break;
  	    }
  
! 	    if (i==0 &amp;&amp; localrealm) {
  		strncpy(local_realms[0], localrealm, AFS_REALM_SZ);
  		num_lrealms = 1;
  	    } else {
***************
*** 154,160 ****
  	/* If yes, then make sure that the name is not present in 
  	 * an exclusion list */
  	if (lrealm_match) {
! 	    if (tinst[0])
  		snprintf(uname,sizeof(uname),"%s.%s@%s",tname,tinst,tcell);
  	    else
  		snprintf(uname,sizeof(uname),"%s@%s",tname,tcell);
--- 154,160 ----
  	/* If yes, then make sure that the name is not present in 
  	 * an exclusion list */
  	if (lrealm_match) {
! 	    if (tinst &amp;&amp; tinst[0])
  		snprintf(uname,sizeof(uname),"%s.%s@%s",tname,tinst,tcell);
  	    else
  		snprintf(uname,sizeof(uname),"%s@%s",tname,tcell);
Index: openafs/src/util/kreltime.c
diff -c openafs/src/util/kreltime.c:1.8 openafs/src/util/kreltime.c:1.9
*** openafs/src/util/kreltime.c:1.8	Tue Jul 15 19:17:16 2003
--- openafs/src/util/kreltime.c	Mon Mar 20 08:25:50 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/kreltime.c,v 1.8 2003/07/15 23:17:16 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/kreltime.c,v 1.9 2006/03/20 13:25:50 jaltman Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
***************
*** 115,122 ****
  ktimeDate_FromInt32(afs_int32 timeSecs, struct ktime_date *ktimePtr)
  {
      struct tm *timePtr;
  
!     timePtr = localtime((time_t *) &amp; timeSecs);
  
      /* copy the relevant fields */
      ktimePtr-&gt;sec = timePtr-&gt;tm_sec;
--- 115,123 ----
  ktimeDate_FromInt32(afs_int32 timeSecs, struct ktime_date *ktimePtr)
  {
      struct tm *timePtr;
+     time_t     tt = timeSecs;
  
!     timePtr = localtime(&amp;tt);
  
      /* copy the relevant fields */
      ktimePtr-&gt;sec = timePtr-&gt;tm_sec;
Index: openafs/src/util/ktime.c
diff -c openafs/src/util/ktime.c:1.11 openafs/src/util/ktime.c:1.12
*** openafs/src/util/ktime.c:1.11	Wed Sep  8 17:35:53 2004
--- openafs/src/util/ktime.c	Mon Apr  3 12:22:30 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/ktime.c,v 1.11 2004/09/08 21:35:53 jaltman Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;stdio.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/util/ktime.c,v 1.12 2006/04/03 16:22:30 rees Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;stdio.h&gt;
***************
*** 517,522 ****
--- 517,523 ----
      if (akdate-&gt;mask)
  	return 0;
  
+     /* Old ambiguous mm/dd/yy hh:mm:ss format */
  
      code =
  	sscanf(adate, "%d / %d / %d %d : %d : %d%1s", &amp;month, &amp;day2, &amp;year,
***************
*** 528,540 ****
  		   &amp;hour, &amp;min, &amp;c[0]);
  	if (code != 5) {
  	    hour = min = 0;
! 	    code = sscanf(adate, "%d / %d / %d%1s", &amp;month, &amp;day2, &amp;year, &amp;c[0]);
  	    if (code != 3) {
! 		return -1;
  	    }
  	}
      }
  
      if ((year &lt; 0) || (month &lt; 1) || (month &gt; 12) || (day2 &lt; 1) || (day2 &gt; 31) ||	/* more or less */
  	(hour &lt; 0) || (hour &gt; 23) || (min &lt; 0) || (min &gt; 59) || (sec &lt; 0)
  	|| (sec &gt; 59))
--- 529,556 ----
  		   &amp;hour, &amp;min, &amp;c[0]);
  	if (code != 5) {
  	    hour = min = 0;
! 	    code =
! 		sscanf(adate, "%d / %d / %d%1s", &amp;month, &amp;day2, &amp;year, &amp;c[0]);
  	    if (code != 3) {
! 		code = -1;
  	    }
  	}
      }
  
+     /* New ISO 8601 (subset) format */
+ 
+     if (code &lt; 0) {
+ 	hour = min = sec = 0;
+ 	code =
+ 	    sscanf(adate, "%d-%d-%d %d:%d:%d%1s", &amp;year, &amp;month, &amp;day2,
+ 		   &amp;hour, &amp;min, &amp;sec, c);
+ 	if (code != 3 &amp;&amp; code != 5 &amp;&amp; code != 6)
+ 	    code = -1;
+     }
+ 
+     if (code &lt; 0)
+ 	return code;
+ 
      if ((year &lt; 0) || (month &lt; 1) || (month &gt; 12) || (day2 &lt; 1) || (day2 &gt; 31) ||	/* more or less */
  	(hour &lt; 0) || (hour &gt; 23) || (min &lt; 0) || (min &gt; 59) || (sec &lt; 0)
  	|| (sec &gt; 59))
***************
*** 575,597 ****
  ktime_DateToInt32(char *adate, afs_int32 * aint32)
  {
      struct ktime_date tdate;
!     register afs_int32 code;
  
!     /* parse the date into a ktime_date structure */
!     code = ktime_ParseDate(adate, &amp;tdate);
!     if (code)
! 	return code;		/* failed to parse */
  
!     code = ktime_InterpretDate(&amp;tdate);	/* interpret as seconds since 1970 */
!     *aint32 = code;		/* return it */
!     return 0;			/* and declare no errors */
  }
  
  /* get useful error message to print about date input format */
  char *
  ktime_GetDateUsage(void)
  {
!     return "date format is 'mm/dd/yy [hh:mm]', using a 24 hour clock";
  }
  
  
--- 591,618 ----
  ktime_DateToInt32(char *adate, afs_int32 * aint32)
  {
      struct ktime_date tdate;
!     afs_int32 code;
!     unsigned long l;
!     char c[2];
  
!     if (sscanf(adate, "%lu%1s", &amp;l, c) == 1 &amp;&amp; l &gt; 200000000)
! 	*aint32 = l;
!     else {
! 	/* parse the date into a ktime_date structure */
! 	code = ktime_ParseDate(adate, &amp;tdate);
! 	if (code)
! 	    return code;		/* failed to parse */
! 	*aint32 = ktime_InterpretDate(&amp;tdate);	/* interpret as seconds since 1970 */
!     }
  
!     return 0;
  }
  
  /* get useful error message to print about date input format */
  char *
  ktime_GetDateUsage(void)
  {
!     return "date format is '(yyyy-mm-dd | mm/dd/yy) [hh:mm]', using a 24 hour clock";
  }
  
  
Index: openafs/src/util/softsig.c
diff -c openafs/src/util/softsig.c:1.9 openafs/src/util/softsig.c:1.10
*** openafs/src/util/softsig.c:1.9	Thu Jun  2 00:40:53 2005
--- openafs/src/util/softsig.c	Thu Feb 23 07:32:25 2006
***************
*** 36,42 ****
  static struct {
      void (*handler) (int);
      int pending;
! #if !defined(AFS_DARWIN60_ENV) || !defined(AFS_NBSD_ENV)
      int fatal;
  #endif /* !defined(AFS_DARWIN60_ENV) || !defined(AFS_NBSD_ENV) */
      int inited;
--- 36,42 ----
  static struct {
      void (*handler) (int);
      int pending;
! #if !defined(AFS_DARWIN60_ENV) || defined(AFS_NBSD30_ENV) || !defined(AFS_NBSD_ENV)
      int fatal;
  #endif /* !defined(AFS_DARWIN60_ENV) || !defined(AFS_NBSD_ENV) */
      int inited;
***************
*** 53,59 ****
      pthread_sigmask(SIG_BLOCK, &amp;ss, &amp;os);
      pthread_sigmask(SIG_SETMASK, &amp;os, NULL);
      sigaddset(&amp;ss, SIGUSR1);
! #if defined(AFS_DARWIN60_ENV) || defined(AFS_NBSD_ENV)
      pthread_sigmask (SIG_BLOCK, &amp;ss, NULL);
      sigdelset (&amp;os, SIGUSR1);
  #else /* !defined(AFS_DARWIN60_ENV) &amp;&amp; !defined(AFS_NBSD_ENV) */
--- 53,59 ----
      pthread_sigmask(SIG_BLOCK, &amp;ss, &amp;os);
      pthread_sigmask(SIG_SETMASK, &amp;os, NULL);
      sigaddset(&amp;ss, SIGUSR1);
! #if defined(AFS_DARWIN60_ENV) || (defined(AFS_NBSD_ENV) &amp;&amp; !defined(AFS_NBSD30_ENV))
      pthread_sigmask (SIG_BLOCK, &amp;ss, NULL);
      sigdelset (&amp;os, SIGUSR1);
  #else /* !defined(AFS_DARWIN60_ENV) &amp;&amp; !defined(AFS_NBSD_ENV) */
***************
*** 74,80 ****
  	for (i = 0; i &lt; NSIG; i++) {
  	    if (softsig_sigs[i].handler &amp;&amp; !softsig_sigs[i].inited) {
  		sigaddset(&amp;ss, i);
! #if defined(AFS_DARWIN60_ENV) || defined(AFS_NBSD_ENV)
  		pthread_sigmask (SIG_BLOCK, &amp;ss, NULL);
  		sigdelset (&amp;os, i);
  #endif /* defined(AFS_DARWIN60_ENV) || defined(AFS_NBSD_ENV) */
--- 74,80 ----
  	for (i = 0; i &lt; NSIG; i++) {
  	    if (softsig_sigs[i].handler &amp;&amp; !softsig_sigs[i].inited) {
  		sigaddset(&amp;ss, i);
! #if defined(AFS_DARWIN60_ENV) || (defined(AFS_NBSD_ENV) &amp;&amp; !defined(AFS_NBSD30_ENV))
  		pthread_sigmask (SIG_BLOCK, &amp;ss, NULL);
  		sigdelset (&amp;os, i);
  #endif /* defined(AFS_DARWIN60_ENV) || defined(AFS_NBSD_ENV) */
***************
*** 87,93 ****
  	    }
  	}
  	if (i == NSIG) {
! #if defined(AFS_DARWIN60_ENV) || defined(AFS_NBSD_ENV)
  	    sigsuspend (&amp;os);
  #else /* !defined(AFS_DARWIN60_ENV) &amp;&amp; !defined(AFS_NBSD_ENV) */
  	    sigwait(&amp;ss, &amp;sigw);
--- 87,93 ----
  	    }
  	}
  	if (i == NSIG) {
! #if defined(AFS_DARWIN60_ENV) || (defined(AFS_NBSD_ENV) &amp;&amp; !defined(AFS_NBSD30_ENV))
  	    sigsuspend (&amp;os);
  #else /* !defined(AFS_DARWIN60_ENV) &amp;&amp; !defined(AFS_NBSD_ENV) */
  	    sigwait(&amp;ss, &amp;sigw);
Index: openafs/src/util/strnlen.c
diff -c /dev/null openafs/src/util/strnlen.c:1.1
*** /dev/null	Thu Apr 27 12:42:31 2006
--- openafs/src/util/strnlen.c	Fri Mar 17 23:20:16 2006
***************
*** 0 ****
--- 1,35 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /* strnlen.c - fixed length string length */
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/util/strnlen.c,v 1.1 2006/03/18 04:20:16 shadow Exp $");
+ 
+ #include &lt;sys/types.h&gt;
+ #include &lt;stdarg.h&gt;
+ #include &lt;ctype.h&gt;
+ 
+ 
+ size_t
+ afs_strnlen(char * buf, size_t len)
+ {
+     size_t i;
+ 
+     for (i = 0; i &lt; len; i++) {
+ 	if (buf[i] == '\0')
+ 	    break;
+     }
+ 
+     return i;
+ }
+ 
Index: openafs/src/util/test/Makefile.in
diff -c openafs/src/util/test/Makefile.in:1.4 openafs/src/util/test/Makefile.in:1.5
*** openafs/src/util/test/Makefile.in:1.4	Tue Jul  1 15:24:05 2003
--- openafs/src/util/test/Makefile.in	Thu Mar  9 01:35:06 2006
***************
*** 9,15 ****
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  
! CFLAGS = -I. -I.. -I${SRCDIR}/include ${XCFLAGS} ${DBG}
  
  tests: test_ktime ktest dirpath_test
  
--- 9,15 ----
  include @TOP_OBJDIR@/src/config/Makefile.config
  
  
! CFLAGS = -I. -I.. -I${SRCDIR}/include ${XCFLAGS} ${ARCHFLAGS} ${DBG}
  
  tests: test_ktime ktest dirpath_test
  
Index: openafs/src/venus/Makefile.in
diff -c openafs/src/venus/Makefile.in:1.33 openafs/src/venus/Makefile.in:1.34
*** openafs/src/venus/Makefile.in:1.33	Fri Oct  7 16:11:09 2005
--- openafs/src/venus/Makefile.in	Thu Mar  9 01:35:08 2006
***************
*** 166,172 ****
  					-o kdump.$$IP kdump.$$IP.o \
  					${TOP_LIBDIR}/libcmd64.a -lelf \
  				;; \
! 			*) 	${CC} ${XCFLAGS} \
  					$$CPU_KDEFS \
  					-o kdump.$$IP kdump.$$IP.o \
  					${TOP_LIBDIR}/libcmd.a -lelf \
--- 166,172 ----
  					-o kdump.$$IP kdump.$$IP.o \
  					${TOP_LIBDIR}/libcmd64.a -lelf \
  				;; \
! 			*) 	${CC} ${XCFLAGS} ${ARCHFLAGS} \
  					$$CPU_KDEFS \
  					-o kdump.$$IP kdump.$$IP.o \
  					${TOP_LIBDIR}/libcmd.a -lelf \
***************
*** 220,226 ****
  						${KERN_DBG} ${KERN_OPTMZ} -I${TOP_INCDIR} \
  						-I${TOP_OBJDIR}/src/config \
  						$$CPU_KDEFS \
! 						${XCFLAGS} -DAFS_32BIT_KERNEL_ENV \
  						-c ${srcdir}/kdump.c -o kdump.$$IP.o \
  					;; \
  				esac || exit $$?; \
--- 220,226 ----
  						${KERN_DBG} ${KERN_OPTMZ} -I${TOP_INCDIR} \
  						-I${TOP_OBJDIR}/src/config \
  						$$CPU_KDEFS \
! 						${XCFLAGS} ${ARCHFLAGS} -DAFS_32BIT_KERNEL_ENV \
  						-c ${srcdir}/kdump.c -o kdump.$$IP.o \
  					;; \
  				esac || exit $$?; \
***************
*** 230,236 ****
  			touch kdump.o ;; \
  		*) \
  			${CC} ${KERN_DBG} ${KERN_OPTMZ} -I${TOP_SRCDIR} -I${TOP_INCDIR}/afs \
! 			-I${TOP_OBJDIR}/src/config -I${TOP_OBJDIR}/src -I${TOP_INCDIR} ${XCFLAGS} \
  			-o kdump.o -c ${srcdir}/kdump.c ;; \
  	esac ;
  
--- 230,236 ----
  			touch kdump.o ;; \
  		*) \
  			${CC} ${KERN_DBG} ${KERN_OPTMZ} -I${TOP_SRCDIR} -I${TOP_INCDIR}/afs \
! 			-I${TOP_OBJDIR}/src/config -I${TOP_OBJDIR}/src -I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS} \
  			-o kdump.o -c ${srcdir}/kdump.c ;; \
  	esac ;
  
***************
*** 250,256 ****
  		-I${TOP_OBJDIR}/src/afs/${MKAFS_OSTYPE} \
  		-I${TOP_OBJDIR}/src/config -I${TOP_OBJDIR}/src/libafs/afs \
  		-I${TOP_SRCDIR} -I${TOP_SRCDIR}/afs/${MKAFS_OSTYPE} \
! 		-I${TOP_INCDIR} ${XCFLAGS} -o kdump-linux-${LINUX_VERSION}.o \
  		-c ${srcdir}/kdump.c
  
  kdump-linux-@LINUX_VERSION@: kdump-linux-@LINUX_VERSION@.o
--- 250,256 ----
  		-I${TOP_OBJDIR}/src/afs/${MKAFS_OSTYPE} \
  		-I${TOP_OBJDIR}/src/config -I${TOP_OBJDIR}/src/libafs/afs \
  		-I${TOP_SRCDIR} -I${TOP_SRCDIR}/afs/${MKAFS_OSTYPE} \
! 		-I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS} -o kdump-linux-${LINUX_VERSION}.o \
  		-c ${srcdir}/kdump.c
  
  kdump-linux-@LINUX_VERSION@: kdump-linux-@LINUX_VERSION@.o
***************
*** 264,270 ****
  		-I${TOP_OBJDIR}/src/afs/${MKAFS_OSTYPE} \
  		-I${TOP_OBJDIR}/src/config -I${TOP_OBJDIR}/src/libafs/afs \
  		-I${TOP_SRCDIR} -I${TOP_SRCDIR}/afs/${MKAFS_OSTYPE} \
! 		-I${TOP_INCDIR} ${XCFLAGS} -mno-fp-regs -ffixed-8 \
  		-o kdump-alpha_linux-${LINUX_VERSION}.o -c ${srcdir}/kdump.c ;; \
  
  kdump-alpha_linux-@LINUX_VERSION@: kdump-alpha_linux-@LINUX_VERSION@.o
--- 264,270 ----
  		-I${TOP_OBJDIR}/src/afs/${MKAFS_OSTYPE} \
  		-I${TOP_OBJDIR}/src/config -I${TOP_OBJDIR}/src/libafs/afs \
  		-I${TOP_SRCDIR} -I${TOP_SRCDIR}/afs/${MKAFS_OSTYPE} \
! 		-I${TOP_INCDIR} ${XCFLAGS} ${ARCHFLAGS} -mno-fp-regs -ffixed-8 \
  		-o kdump-alpha_linux-${LINUX_VERSION}.o -c ${srcdir}/kdump.c ;; \
  
  kdump-alpha_linux-@LINUX_VERSION@: kdump-alpha_linux-@LINUX_VERSION@.o
Index: openafs/src/venus/fs.c
diff -c openafs/src/venus/fs.c:1.29 openafs/src/venus/fs.c:1.30
*** openafs/src/venus/fs.c:1.29	Mon Jan 23 16:04:31 2006
--- openafs/src/venus/fs.c	Thu Mar 30 12:13:40 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/fs.c,v 1.29 2006/01/23 21:04:31 shadow Exp $");
  
  #include &lt;afs/afs_args.h&gt;
  #include &lt;rx/xdr.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/fs.c,v 1.30 2006/03/30 17:13:40 rees Exp $");
  
  #include &lt;afs/afs_args.h&gt;
  #include &lt;rx/xdr.h&gt;
***************
*** 3131,3136 ****
--- 3131,3191 ----
      return 0;
  }
  
+ #ifdef AFS_DISCON_ENV
+ static char *modenames[] = {
+     "discon",
+     "fetchonly",
+     "partial",
+     "nat",
+     "full",
+     NULL
+ };
+ 
+ static afs_int32
+ DisconCmd(struct cmd_syndesc *as, char *arock)
+ {
+     struct cmd_item *ti;
+     char *modename;
+     int modelen;
+     afs_int32 mode, code;
+     struct ViceIoctl blob;
+ 
+     blob.in = NULL;
+     blob.in_size = 0;
+ 
+     ti = as-&gt;parms[0].items;
+     if (ti) {
+ 	modename = ti-&gt;data;
+ 	modelen = strlen(modename);
+ 	for (mode = 0; modenames[mode] != NULL; mode++)
+ 	    if (!strncasecmp(modename, modenames[mode], modelen))
+ 		break;
+ 	if (modenames[mode] == NULL)
+ 	    printf("Unknown discon mode \"%s\"\n", modename);
+ 	else {
+ 	    memcpy(space, &amp;mode, sizeof mode);
+ 	    blob.in = space;
+ 	    blob.in_size = sizeof mode;
+ 	}
+     }
+ 
+     blob.out_size = sizeof(mode);
+     blob.out = space;
+     code = pioctl(0, VIOC_DISCON, &amp;blob, 1);
+     if (code)
+ 	Die(errno, NULL);
+     else {
+ 	memcpy(&amp;mode, space, sizeof mode);
+ 	if (mode &lt; sizeof modenames / sizeof (char *))
+ 	    printf("Discon mode is now \"%s\"\n", modenames[mode]);
+ 	else
+ 	    printf("Unknown discon mode %d\n", mode);
+     }
+ 
+     return 0;
+ }
+ #endif
+ 
  #include "AFS_component_version_number.c"
  
  int
***************
*** 3442,3447 ****
--- 3497,3508 ----
  			  "get fid for file(s)");
      cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
  
+ #ifdef AFS_DISCON_ENV
+     ts = cmd_CreateSyntax("discon", DisconCmd, 0,
+ 			  "disconnection mode");
+     cmd_AddParm(ts, "-mode", CMD_SINGLE, CMD_OPTIONAL, "nat | full");
+ #endif
+ 
      code = cmd_Dispatch(argc, argv);
      if (rxInitDone)
  	rx_Finalize();
Index: openafs/src/venus/fstrace.c
diff -c openafs/src/venus/fstrace.c:1.22 openafs/src/venus/fstrace.c:1.23
*** openafs/src/venus/fstrace.c:1.22	Thu Oct 13 11:12:22 2005
--- openafs/src/venus/fstrace.c	Tue Apr  4 16:51:19 2006
***************
*** 14,20 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/fstrace.c,v 1.22 2005/10/13 15:12:22 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;sys/types.h&gt;
--- 14,20 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/fstrace.c,v 1.23 2006/04/04 20:51:19 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;sys/types.h&gt;
***************
*** 285,290 ****
--- 285,291 ----
      int status;
      int printed;		/* did we print the string yet? */
      afs_int32 *tlp;
+     time_t tmv;
  
      /* decode parameters */
      temp = alp[0];		/* type encoded in low-order 24 bits, t0 high */
***************
*** 354,360 ****
  #endif /* AFS_SGI64_ENV */
  	    break;
  	case ICL_TYPE_UNIXDATE:
! 	    printfParms[pfpix++] = (long)ctime((time_t *) &amp; alp[pix]);
  	    break;
  	default:
  	    printf("DisplayRecord: Bad type %d in decode switch.\n", type);
--- 355,362 ----
  #endif /* AFS_SGI64_ENV */
  	    break;
  	case ICL_TYPE_UNIXDATE:
! 	    tmv = alp[pix];
! 	    printfParms[pfpix++] = (long)ctime(&amp;tmv);
  	    break;
  	default:
  	    printf("DisplayRecord: Bad type %d in decode switch.\n", type);
***************
*** 450,457 ****
      }
      if (!printed) {
  	if (alp[1] == ICL_INFO_TIMESTAMP) {
  	    fprintf(outFilep, "time %d.%06d, pid %u: %s\n", alp[3] / 1000000,
! 		    alp[3] % 1000000, alp[2], ctime((time_t *) &amp; alp[4]));
  	} else {
  	    fprintf(outFilep, "raw op %d, time %d.%06d, pid %u\n", alp[1],
  		    alp[3] / 1000000, alp[3] % 1000000, alp[2]);
--- 452,460 ----
      }
      if (!printed) {
  	if (alp[1] == ICL_INFO_TIMESTAMP) {
+ 	    tmv = alp[4];
  	    fprintf(outFilep, "time %d.%06d, pid %u: %s\n", alp[3] / 1000000,
! 		    alp[3] % 1000000, alp[2], ctime(&amp;tmv));
  	} else {
  	    fprintf(outFilep, "raw op %d, time %d.%06d, pid %u\n", alp[1],
  		    alp[3] / 1000000, alp[3] % 1000000, alp[2]);
***************
*** 500,507 ****
  		    fprintf(outFilep, "p%d:%s ", i, (char *)&amp;alp[pix]);
  		    break;
  		case ICL_TYPE_UNIXDATE:
  		    fprintf(outFilep, "p%d:%s ", i,
! 			    ctime((time_t *) &amp; alp[pix]));
  		    break;
  		default:
  		    printf
--- 503,511 ----
  		    fprintf(outFilep, "p%d:%s ", i, (char *)&amp;alp[pix]);
  		    break;
  		case ICL_TYPE_UNIXDATE:
+ 		    tmv = alp[pix];
  		    fprintf(outFilep, "p%d:%s ", i,
! 			    ctime(&amp;tmv));
  		    break;
  		default:
  		    printf
Index: openafs/src/venus/test/Makefile.in
diff -c openafs/src/venus/test/Makefile.in:1.7 openafs/src/venus/test/Makefile.in:1.8
*** openafs/src/venus/test/Makefile.in:1.7	Thu Nov  1 00:01:17 2001
--- openafs/src/venus/test/Makefile.in	Thu Mar  9 01:35:09 2006
***************
*** 13,19 ****
  LDIRS= -L${TOP_LIBDIR} -L..
  LIBS= -lsys -lubik -lvldb -lauth -lrxkad -ldes -lcom_err -lcmd -lrx -llwp -lafsutil
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${XCFLAGS}
  
  all test:  fulltest owntest idtest getinitparams
  
--- 13,19 ----
  LDIRS= -L${TOP_LIBDIR} -L..
  LIBS= -lsys -lubik -lvldb -lauth -lrxkad -ldes -lcom_err -lcmd -lrx -llwp -lafsutil
  
! CFLAGS = ${OPTIMIZE} ${INCDIRS} ${XCFLAGS} ${ARCHFLAGS}
  
  all test:  fulltest owntest idtest getinitparams
  
Index: openafs/src/vfsck/Makefile.in
diff -c openafs/src/vfsck/Makefile.in:1.10 openafs/src/vfsck/Makefile.in:1.11
*** openafs/src/vfsck/Makefile.in:1.10	Sat Jan 11 02:35:00 2003
--- openafs/src/vfsck/Makefile.in	Thu Mar  9 01:35:11 2006
***************
*** 19,25 ****
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${VFSCK_CFLAGS}
  
  SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c \
  	pass4.c pass5.c setup.c utilities.c ufs_subr.c \
--- 19,25 ----
  srcdir=@srcdir@
  include @TOP_OBJDIR@/src/config/Makefile.config
  
! CFLAGS=${COMMON_CFLAGS} ${XCFLAGS} ${ARCHFLAGS} ${VFSCK_CFLAGS}
  
  SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c \
  	pass4.c pass5.c setup.c utilities.c ufs_subr.c \
Index: openafs/src/viced/Makefile.in
diff -c openafs/src/viced/Makefile.in:1.12 openafs/src/viced/Makefile.in:1.14
*** openafs/src/viced/Makefile.in:1.12	Fri Oct 24 02:26:17 2003
--- openafs/src/viced/Makefile.in	Fri Mar 17 14:54:47 2006
***************
*** 14,22 ****
  
  CFLAGS=${DBG} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I. -I${TOP_INCDIR} \
  	-I${TOP_INCDIR}/afs -I${TOP_OBJDIR} -I${TOP_OBJDIR}/fsint\
! 	 ${XCFLAGS} -DRXDEBUG -DNINTERFACE
  
! LDFLAGS = ${DBUG} ${XLDFLAGS}
  
  LIBS=${TOP_LIBDIR}/libacl.a	\
  	${TOP_LIBDIR}/libvldb.a	\
--- 14,22 ----
  
  CFLAGS=${DBG} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I. -I${TOP_INCDIR} \
  	-I${TOP_INCDIR}/afs -I${TOP_OBJDIR} -I${TOP_OBJDIR}/fsint\
! 	 ${XCFLAGS} ${ARCHFLAGS} -DRXDEBUG -DNINTERFACE
  
! LDFLAGS = ${DBUG} ${XLDFLAGS} ${ARCHFLAGS}
  
  LIBS=${TOP_LIBDIR}/libacl.a	\
  	${TOP_LIBDIR}/libvldb.a	\
***************
*** 50,55 ****
--- 50,56 ----
  	${TOP_INCDIR}/afs/afsint.h	\
  	viced.h				\
  	host.h				\
+ 	callback.h			\
  	fs_stats.h
  
  objects=viced.o		\
Index: openafs/src/viced/NTMakefile
diff -c openafs/src/viced/NTMakefile:1.5 openafs/src/viced/NTMakefile:1.6
*** openafs/src/viced/NTMakefile:1.5	Sun Nov 20 20:57:39 2005
--- openafs/src/viced/NTMakefile	Mon Mar 20 11:07:20 2006
***************
*** 5,10 ****
--- 5,12 ----
  # License.  For details, see the LICENSE file in the top-level source
  # directory or online at http://www.openafs.org/dl/license10.html
  
+ AFSDEV_AUXCDEFINES = -DFSSYNC_BUILD_SERVER
+ 
  RELDIR=viced
  !INCLUDE ..\config\NTMakefile.$(SYS_NAME)
  !INCLUDE ..\config\NTMakefile.version
Index: openafs/src/viced/afsfileprocs.c
diff -c openafs/src/viced/afsfileprocs.c:1.101 openafs/src/viced/afsfileprocs.c:1.113
*** openafs/src/viced/afsfileprocs.c:1.101	Fri Feb 17 09:48:09 2006
--- openafs/src/viced/afsfileprocs.c	Tue Apr 25 02:40:48 2006
***************
*** 29,35 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/afsfileprocs.c,v 1.101 2006/02/17 14:48:09 jaltman Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
--- 29,35 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/afsfileprocs.c,v 1.113 2006/04/25 06:40:48 jaltman Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
***************
*** 80,88 ****
  #include &lt;afs/ihandle.h&gt;
  #include &lt;afs/vnode.h&gt;
  #include &lt;afs/volume.h&gt;
- #include &lt;afs/acl.h&gt;
  #include &lt;afs/ptclient.h&gt;
  #include &lt;afs/prs_fs.h&gt;
  #include &lt;rx/rx.h&gt;
  #include &lt;rx/rx_globals.h&gt;
  #include &lt;sys/stat.h&gt;
--- 80,89 ----
  #include &lt;afs/ihandle.h&gt;
  #include &lt;afs/vnode.h&gt;
  #include &lt;afs/volume.h&gt;
  #include &lt;afs/ptclient.h&gt;
+ #include &lt;afs/ptuser.h&gt;
  #include &lt;afs/prs_fs.h&gt;
+ #include &lt;afs/acl.h&gt;
  #include &lt;rx/rx.h&gt;
  #include &lt;rx/rx_globals.h&gt;
  #include &lt;sys/stat.h&gt;
***************
*** 111,116 ****
--- 112,118 ----
  #include "viced_prototypes.h"
  #include "viced.h"
  #include "host.h"
+ #include "callback.h"
  #include &lt;afs/unified_afs.h&gt;
  #include &lt;afs/audit.h&gt;
  #include &lt;afs/afsutil.h&gt;
***************
*** 208,214 ****
  /*
   * Externals used by the xstat code.
   */
! extern int VolumeCacheSize, VolumeGets, VolumeReplacements;
  extern int CEs, CEBlocks;
  
  extern int HTs, HTBlocks;
--- 210,216 ----
  /*
   * Externals used by the xstat code.
   */
! extern VolPkgStats VStats;
  extern int CEs, CEBlocks;
  
  extern int HTs, HTBlocks;
***************
*** 300,306 ****
   */
  static int
  CallPreamble(register struct rx_call *acall, int activecall,
! 	     struct rx_connection **tconn)
  {
      struct host *thost;
      struct client *tclient;
--- 302,308 ----
   */
  static int
  CallPreamble(register struct rx_call *acall, int activecall,
! 	     struct rx_connection **tconn, struct host **ahostp)
  {
      struct host *thost;
      struct client *tclient;
***************
*** 316,324 ****
--- 318,328 ----
      H_LOCK;
    retry:
      tclient = h_FindClient_r(*tconn);
+     thost = tclient-&gt;host;
      if (tclient-&gt;prfail == 1) {	/* couldn't get the CPS */
  	if (!retry_flag) {
  	    h_ReleaseClient_r(tclient);
+ 	    h_Release_r(thost);
  	    ViceLog(0, ("CallPreamble: Couldn't get CPS. Fail\n"));
  	    H_UNLOCK;
  	    return -1001;
***************
*** 333,338 ****
--- 337,343 ----
  	H_LOCK;
  	if (code) {
  	    h_ReleaseClient_r(tclient);
+ 	    h_Release_r(thost);
  	    H_UNLOCK;
  	    ViceLog(0, ("CallPreamble: couldn't reconnect to ptserver\n"));
  	    return -1001;
***************
*** 340,349 ****
  
  	tclient-&gt;prfail = 2;	/* Means re-eval client's cps */
  	h_ReleaseClient_r(tclient);
  	goto retry;
      }
  
-     thost = tclient-&gt;host;
      tclient-&gt;LastCall = thost-&gt;LastCall = FT_ApproxTime();
      if (activecall)		/* For all but "GetTime", "GetStats", and "GetCaps" calls */
  	thost-&gt;ActiveCall = thost-&gt;LastCall;
--- 345,354 ----
  
  	tclient-&gt;prfail = 2;	/* Means re-eval client's cps */
  	h_ReleaseClient_r(tclient);
+ 	h_Release_r(thost);
  	goto retry;
      }
  
      tclient-&gt;LastCall = thost-&gt;LastCall = FT_ApproxTime();
      if (activecall)		/* For all but "GetTime", "GetStats", and "GetCaps" calls */
  	thost-&gt;ActiveCall = thost-&gt;LastCall;
***************
*** 388,404 ****
      h_ReleaseClient_r(tclient);
      h_Unlock_r(thost);
      H_UNLOCK;
      return code;
  
  }				/*CallPreamble */
  
  
  static afs_int32
! CallPostamble(register struct rx_connection *aconn, afs_int32 ret)
  {
      struct host *thost;
      struct client *tclient;
      int translate = 0;
  
      H_LOCK;
      tclient = h_FindClient_r(aconn);
--- 393,412 ----
      h_ReleaseClient_r(tclient);
      h_Unlock_r(thost);
      H_UNLOCK;
+     *ahostp = thost;
      return code;
  
  }				/*CallPreamble */
  
  
  static afs_int32
! CallPostamble(register struct rx_connection *aconn, afs_int32 ret,
! 	      struct host *ahost)
  {
      struct host *thost;
      struct client *tclient;
      int translate = 0;
+     int held;
  
      H_LOCK;
      tclient = h_FindClient_r(aconn);
***************
*** 406,412 ****
      if (thost-&gt;hostFlags &amp; HERRORTRANS)
  	translate = 1;
      h_ReleaseClient_r(tclient);
!     h_Release_r(thost);
      H_UNLOCK;
      return (translate ? sys_error_to_et(ret) : ret);
  }				/*CallPostamble */
--- 414,431 ----
      if (thost-&gt;hostFlags &amp; HERRORTRANS)
  	translate = 1;
      h_ReleaseClient_r(tclient);
!     held = h_Held_r(thost);
!     if (held)
! 	h_Release_r(thost);
!     if (ahost != thost) {
! 	char hoststr[16], hoststr2[16];	
! 	ViceLog(0, ("CallPostamble: ahost %s:%d (%x) != thost %s:%d (%x)\n",
! 		afs_inet_ntoa_r(thost-&gt;host, hoststr), ntohs(thost-&gt;port),
! 		ahost, 
! 		afs_inet_ntoa_r(thost-&gt;host, hoststr2), ntohs(thost-&gt;port),
! 		thost));
! 	h_Release_r(ahost);
!     }
      H_UNLOCK;
      return (translate ? sys_error_to_et(ret) : ret);
  }				/*CallPostamble */
***************
*** 420,426 ****
  CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
  {
      int fileCode = 0;
!     int errorCode = -1;
      static struct timeval restartedat = { 0, 0 };
  
      if (fid-&gt;Volume == 0 || fid-&gt;Vnode == 0)	/* not: || fid-&gt;Unique == 0) */
--- 439,445 ----
  CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
  {
      int fileCode = 0;
!     afs_int32 local_errorCode, errorCode = -1;
      static struct timeval restartedat = { 0, 0 };
  
      if (fid-&gt;Volume == 0 || fid-&gt;Vnode == 0)	/* not: || fid-&gt;Unique == 0) */
***************
*** 430,436 ****
  
  	while (1) {
  	    errorCode = 0;
! 	    *volptr = VGetVolume(&amp;errorCode, (afs_int32) fid-&gt;Volume);
  	    if (!errorCode) {
  		assert(*volptr);
  		break;
--- 449,455 ----
  
  	while (1) {
  	    errorCode = 0;
! 	    *volptr = VGetVolume(&amp;local_errorCode, &amp;errorCode, (afs_int32) fid-&gt;Volume);
  	    if (!errorCode) {
  		assert(*volptr);
  		break;
***************
*** 507,514 ****
  		    }
  		}
  	    }
! 	    /* allow read operations on busy volume */
! 	    else if (errorCode == VBUSY &amp;&amp; lock == READ_LOCK) {
  		errorCode = 0;
  		break;
  	    } else if (errorCode)
--- 526,535 ----
  		    }
  		}
  	    }
! 	    /* allow read operations on busy volume. 
! 	     * must check local_errorCode because demand attach fs
! 	     * can have local_errorCode == VSALVAGING, errorCode == VBUSY */
! 	    else if (local_errorCode == VBUSY &amp;&amp; lock == READ_LOCK) {
  		errorCode = 0;
  		break;
  	    } else if (errorCode)
***************
*** 1133,1138 ****
--- 1154,1161 ----
  			 wrlen, errno));
  #ifdef FAST_RESTART		/* if running in no-salvage, don't core the server */
  		ViceLog(0, ("CopyOnWrite failed: taking volume offline\n"));
+ #elif defined(AFS_DEMAND_ATTACH_FS)
+ 		ViceLog(0, ("CopyOnWrite failed: requesting salvage\n"));
  #else /* Avoid further corruption and try to get a core. */
  		assert(0);
  #endif
***************
*** 1667,1680 ****
   * SAFS_ReleaseLock)
   */
  static afs_int32
! HandleLocking(Vnode * targetptr, afs_int32 rights, ViceLockType LockingType)
  {
      int Time;			/* Used for time */
      int writeVnode = targetptr-&gt;changed_oldTime;	/* save original status */
  
-     /* Does the caller has Lock priviledges; root extends locks, however */
-     if (LockingType != LockExtend &amp;&amp; !(rights &amp; PRSFS_LOCK))
- 	return (EACCES);
      targetptr-&gt;changed_oldTime = 1;	/* locking doesn't affect any time stamp */
      Time = FT_ApproxTime();
      switch (LockingType) {
--- 1690,1700 ----
   * SAFS_ReleaseLock)
   */
  static afs_int32
! HandleLocking(Vnode * targetptr, struct client *client, afs_int32 rights, ViceLockType LockingType)
  {
      int Time;			/* Used for time */
      int writeVnode = targetptr-&gt;changed_oldTime;	/* save original status */
  
      targetptr-&gt;changed_oldTime = 1;	/* locking doesn't affect any time stamp */
      Time = FT_ApproxTime();
      switch (LockingType) {
***************
*** 1685,1696 ****
  		0;
  	Time += AFS_LOCKWAIT;
  	if (LockingType == LockRead) {
  	    if (targetptr-&gt;disk.lock.lockCount &gt;= 0) {
  		++(targetptr-&gt;disk.lock.lockCount);
  		targetptr-&gt;disk.lock.lockTime = Time;
  	    } else
  		return (EAGAIN);
! 	} else {
  	    if (targetptr-&gt;disk.lock.lockCount == 0) {
  		targetptr-&gt;disk.lock.lockCount = -1;
  		targetptr-&gt;disk.lock.lockTime = Time;
--- 1705,1723 ----
  		0;
  	Time += AFS_LOCKWAIT;
  	if (LockingType == LockRead) {
+ 	    if ( !(rights &amp; PRSFS_LOCK) )
+ 		return(EACCES);
+ 
  	    if (targetptr-&gt;disk.lock.lockCount &gt;= 0) {
  		++(targetptr-&gt;disk.lock.lockCount);
  		targetptr-&gt;disk.lock.lockTime = Time;
  	    } else
  		return (EAGAIN);
! 	} else if (LockingType == LockWrite) {
! 	    if ( !(rights &amp; PRSFS_WRITE) &amp;&amp; 
! 		 !(OWNSp(client, targetptr) &amp;&amp; (rights &amp; PRSFS_INSERT)) )
! 		return(EACCES);
! 
  	    if (targetptr-&gt;disk.lock.lockCount == 0) {
  		targetptr-&gt;disk.lock.lockCount = -1;
  		targetptr-&gt;disk.lock.lockTime = Time;
***************
*** 1977,1982 ****
--- 2004,2010 ----
      Volume *volptr = 0;		/* pointer to the volume */
      struct client *client = 0;	/* pointer to the client data */
      struct rx_connection *tcon;	/* the connection we're part of */
+     struct host *thost;
      afs_int32 rights, anyrights;	/* rights for this and any user */
      struct client *t_client = NULL;	/* tmp ptr to client data */
      struct in_addr logHostAddr;	/* host ip holder for inet_ntoa */
***************
*** 2009,2015 ****
      FS_LOCK;
      AFSCallStats.FetchData++, AFSCallStats.TotalCalls++;
      FS_UNLOCK;
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_FetchData;
  
      /* Get ptr to client data for user Id for logging */
--- 2037,2043 ----
      FS_LOCK;
      AFSCallStats.FetchData++, AFSCallStats.TotalCalls++;
      FS_UNLOCK;
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_FetchData;
  
      /* Get ptr to client data for user Id for logging */
***************
*** 2165,2171 ****
      (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
  			   volptr, &amp;client);
      ViceLog(2, ("SRXAFS_FetchData returns %d\n", errorCode));
!     errorCode = CallPostamble(tcon, errorCode);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 2193,2199 ----
      (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
  			   volptr, &amp;client);
      ViceLog(2, ("SRXAFS_FetchData returns %d\n", errorCode));
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 2241,2246 ****
--- 2269,2275 ----
      struct client *client = 0;	/* pointer to the client data */
      afs_int32 rights, anyrights;	/* rights for this and any user */
      struct rx_connection *tcon = rx_ConnectionOf(acall);
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
      struct in_addr logHostAddr;	/* host ip holder for inet_ntoa */
  #if FS_STATS_DETAILED
***************
*** 2265,2271 ****
      FS_LOCK;
      AFSCallStats.FetchACL++, AFSCallStats.TotalCalls++;
      FS_UNLOCK;
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_FetchACL;
  
      /* Get ptr to client data for user Id for logging */
--- 2294,2300 ----
      FS_LOCK;
      AFSCallStats.FetchACL++, AFSCallStats.TotalCalls++;
      FS_UNLOCK;
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_FetchACL;
  
      /* Get ptr to client data for user Id for logging */
***************
*** 2316,2322 ****
      ViceLog(2,
  	    ("SAFS_FetchACL returns %d (ACL=%s)\n", errorCode,
  	     AccessList-&gt;AFSOpaque_val));
!     errorCode = CallPostamble(tcon, errorCode);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 2345,2351 ----
      ViceLog(2,
  	    ("SAFS_FetchACL returns %d (ACL=%s)\n", errorCode,
  	     AccessList-&gt;AFSOpaque_val));
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 2437,2442 ****
--- 2466,2472 ----
      afs_int32 rights, anyrights;	/* rights for this and any user */
      register struct AFSFid *tfid;	/* file id we're dealing with now */
      struct rx_connection *tcon = rx_ConnectionOf(acall);
+     struct host *thost;
      struct client *t_client = NULL;     /* tmp pointer to the client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 2480,2486 ****
      }
      CallBacks-&gt;AFSCBs_len = nfiles;
  
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_BulkStatus;
  
      tfid = Fids-&gt;AFSCBFids_val;
--- 2510,2516 ----
      }
      CallBacks-&gt;AFSCBs_len = nfiles;
  
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_BulkStatus;
  
      tfid = Fids-&gt;AFSCBFids_val;
***************
*** 2538,2544 ****
      /* Update and store volume/vnode and parent vnodes back */
      (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
  			   volptr, &amp;client);
!     errorCode = CallPostamble(tcon, errorCode);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 2568,2574 ----
      /* Update and store volume/vnode and parent vnodes back */
      (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
  			   volptr, &amp;client);
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 2585,2590 ****
--- 2615,2621 ----
      afs_int32 rights, anyrights;	/* rights for this and any user */
      register struct AFSFid *tfid;	/* file id we're dealing with now */
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
      AFSFetchStatus *tstatus;
  #if FS_STATS_DETAILED
***************
*** 2629,2635 ****
      }
      CallBacks-&gt;AFSCBs_len = nfiles;
  
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon))) {
  	goto Bad_InlineBulkStatus;
      }
  
--- 2660,2666 ----
      }
      CallBacks-&gt;AFSCBs_len = nfiles;
  
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost))) {
  	goto Bad_InlineBulkStatus;
      }
  
***************
*** 2705,2711 ****
      /* Update and store volume/vnode and parent vnodes back */
      (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
  			   volptr, &amp;client);
!     errorCode = CallPostamble(tcon, errorCode);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 2736,2742 ----
      /* Update and store volume/vnode and parent vnodes back */
      (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
  			   volptr, &amp;client);
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 2744,2749 ****
--- 2775,2781 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 2761,2773 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_FetchStatus;
  
      code = SAFSS_FetchStatus(acall, Fid, OutStatus, CallBack, Sync);
  
    Bad_FetchStatus:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 2793,2805 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_FetchStatus;
  
      code = SAFSS_FetchStatus(acall, Fid, OutStatus, CallBack, Sync);
  
    Bad_FetchStatus:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 2814,2819 ****
--- 2846,2852 ----
      struct client *t_client = NULL;	/* tmp ptr to client data */
      struct in_addr logHostAddr;	/* host ip holder for inet_ntoa */
      struct rx_connection *tcon;
+     struct host *thost;
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
      struct fs_stats_xferData *xferP;	/* Ptr to this op's byte size struct */
***************
*** 2842,2848 ****
      FS_LOCK;
      AFSCallStats.StoreData++, AFSCallStats.TotalCalls++;
      FS_UNLOCK;
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_StoreData;
  
      /* Get ptr to client data for user Id for logging */
--- 2875,2881 ----
      FS_LOCK;
      AFSCallStats.StoreData++, AFSCallStats.TotalCalls++;
      FS_UNLOCK;
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_StoreData;
  
      /* Get ptr to client data for user Id for logging */
***************
*** 2991,2997 ****
  			   volptr, &amp;client);
      ViceLog(2, ("SAFS_StoreData	returns	%d\n", errorCode));
  
!     errorCode = CallPostamble(tcon, errorCode);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 3024,3030 ----
  			   volptr, &amp;client);
      ViceLog(2, ("SAFS_StoreData	returns	%d\n", errorCode));
  
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 3022,3027 ****
--- 3055,3064 ----
  		 afs_uint32 Length, afs_uint32 FileLength,
  		 struct AFSFetchStatus * OutStatus, struct AFSVolSync * Sync)
  {
+     if (FileLength &gt; 0x7fffffff || Pos &gt; 0x7fffffff || 
+ 	(0x7fffffff - Pos) &lt; Length)
+         return EFBIG;
+ 
      return common_StoreData64(acall, Fid, InStatus, Pos, Length, FileLength,
  	                      OutStatus, Sync);
  }				/*SRXAFS_StoreData */
***************
*** 3073,3078 ****
--- 3110,3116 ----
      struct client *client = 0;	/* pointer to client structure */
      afs_int32 rights, anyrights;	/* rights for this and any user */
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
      struct in_addr logHostAddr;	/* host ip holder for inet_ntoa */
  #if FS_STATS_DETAILED
***************
*** 3090,3096 ****
      FS_UNLOCK;
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_StoreACL;
  
      /* Get ptr to client data for user Id for logging */
--- 3128,3134 ----
      FS_UNLOCK;
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_StoreACL;
  
      /* Get ptr to client data for user Id for logging */
***************
*** 3148,3154 ****
      PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, 
  		     volptr, &amp;client);
      ViceLog(2, ("SAFS_StoreACL returns %d\n", errorCode));
!     errorCode = CallPostamble(tcon, errorCode);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 3186,3192 ----
      PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, 
  		     volptr, &amp;client);
      ViceLog(2, ("SAFS_StoreACL returns %d\n", errorCode));
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 3268,3273 ****
--- 3306,3312 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 3285,3297 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_StoreStatus;
  
      code = SAFSS_StoreStatus(acall, Fid, InStatus, OutStatus, Sync);
  
    Bad_StoreStatus:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 3324,3336 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_StoreStatus;
  
      code = SAFSS_StoreStatus(acall, Fid, InStatus, OutStatus, Sync);
  
    Bad_StoreStatus:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 3430,3435 ****
--- 3469,3475 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 3447,3459 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_RemoveFile;
  
      code = SAFSS_RemoveFile(acall, DirFid, Name, OutDirStatus, Sync);
  
    Bad_RemoveFile:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 3487,3499 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_RemoveFile;
  
      code = SAFSS_RemoveFile(acall, DirFid, Name, OutDirStatus, Sync);
  
    Bad_RemoveFile:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 3596,3601 ****
--- 3636,3642 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 3615,3621 ****
  
      memset(OutFid, 0, sizeof(struct AFSFid));
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_CreateFile;
  
      code =
--- 3656,3662 ----
  
      memset(OutFid, 0, sizeof(struct AFSFid));
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_CreateFile;
  
      code =
***************
*** 3623,3629 ****
  			 OutDirStatus, CallBack, Sync);
  
    Bad_CreateFile:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 3664,3670 ----
  			 OutDirStatus, CallBack, Sync);
  
    Bad_CreateFile:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 4085,4090 ****
--- 4126,4132 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 4102,4108 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_Rename;
  
      code =
--- 4144,4150 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_Rename;
  
      code =
***************
*** 4110,4116 ****
  		     OutOldDirStatus, OutNewDirStatus, Sync);
  
    Bad_Rename:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 4152,4158 ----
  		     OutOldDirStatus, OutNewDirStatus, Sync);
  
    Bad_Rename:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 4291,4296 ****
--- 4333,4339 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 4308,4314 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_Symlink;
  
      code =
--- 4351,4357 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_Symlink;
  
      code =
***************
*** 4316,4322 ****
  		      OutFidStatus, OutDirStatus, Sync);
  
    Bad_Symlink:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 4359,4365 ----
  		      OutFidStatus, OutDirStatus, Sync);
  
    Bad_Symlink:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 4491,4496 ****
--- 4534,4540 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 4508,4514 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_Link;
  
      code =
--- 4552,4558 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_Link;
  
      code =
***************
*** 4516,4522 ****
  		   OutDirStatus, Sync);
  
    Bad_Link:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 4560,4566 ----
  		   OutDirStatus, Sync);
  
    Bad_Link:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 4691,4696 ****
--- 4735,4741 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 4707,4713 ****
      FS_UNLOCK;
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_MakeDir;
  
      code =
--- 4752,4758 ----
      FS_UNLOCK;
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_MakeDir;
  
      code =
***************
*** 4715,4721 ****
  		      OutDirStatus, CallBack, Sync);
  
    Bad_MakeDir:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 4760,4766 ----
  		      OutDirStatus, CallBack, Sync);
  
    Bad_MakeDir:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 4853,4858 ****
--- 4898,4904 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 4870,4882 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_RemoveDir;
  
      code = SAFSS_RemoveDir(acall, DirFid, Name, OutDirStatus, Sync);
  
    Bad_RemoveDir:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 4916,4928 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_RemoveDir;
  
      code = SAFSS_RemoveDir(acall, DirFid, Name, OutDirStatus, Sync);
  
    Bad_RemoveDir:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 4922,4928 ****
      afs_int32 rights, anyrights;	/* rights for this and any user */
      struct client *t_client;	/* tmp ptr to client data */
      struct in_addr logHostAddr;	/* host ip holder for inet_ntoa */
!     static char *locktype[2] = { "LockRead", "LockWrite" };
      struct rx_connection *tcon = rx_ConnectionOf(acall);
  
      if (type != LockRead &amp;&amp; type != LockWrite) {
--- 4968,4974 ----
      afs_int32 rights, anyrights;	/* rights for this and any user */
      struct client *t_client;	/* tmp ptr to client data */
      struct in_addr logHostAddr;	/* host ip holder for inet_ntoa */
!     static char *locktype[4] = { "LockRead", "LockWrite", "LockExtend", "LockRelease" };
      struct rx_connection *tcon = rx_ConnectionOf(acall);
  
      if (type != LockRead &amp;&amp; type != LockWrite) {
***************
*** 4954,4960 ****
      SetVolumeSync(Sync, volptr);
  
      /* Handle the particular type of set locking, type */
!     errorCode = HandleLocking(targetptr, rights, type);
  
    Bad_SetLock:
      /* Write the all modified vnodes (parent, new files) and volume back */
--- 5000,5006 ----
      SetVolumeSync(Sync, volptr);
  
      /* Handle the particular type of set locking, type */
!     errorCode = HandleLocking(targetptr, client, rights, type);
  
    Bad_SetLock:
      /* Write the all modified vnodes (parent, new files) and volume back */
***************
*** 4984,4989 ****
--- 5030,5036 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 5001,5013 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_SetLock;
  
      code = SAFSS_SetLock(acall, Fid, type, Sync);
  
    Bad_SetLock:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 5048,5060 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_SetLock;
  
      code = SAFSS_SetLock(acall, Fid, type, Sync);
  
    Bad_SetLock:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 5079,5085 ****
      SetVolumeSync(Sync, volptr);
  
      /* Handle the actual lock extension */
!     errorCode = HandleLocking(targetptr, rights, LockExtend);
  
    Bad_ExtendLock:
      /* Put back file's vnode and volume */
--- 5126,5132 ----
      SetVolumeSync(Sync, volptr);
  
      /* Handle the actual lock extension */
!     errorCode = HandleLocking(targetptr, client, rights, LockExtend);
  
    Bad_ExtendLock:
      /* Put back file's vnode and volume */
***************
*** 5109,5114 ****
--- 5156,5162 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 5126,5138 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_ExtendLock;
  
      code = SAFSS_ExtendLock(acall, Fid, Sync);
  
    Bad_ExtendLock:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 5174,5186 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_ExtendLock;
  
      code = SAFSS_ExtendLock(acall, Fid, Sync);
  
    Bad_ExtendLock:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 5205,5211 ****
      SetVolumeSync(Sync, volptr);
  
      /* Handle the actual lock release */
!     if ((errorCode = HandleLocking(targetptr, rights, LockRelease)))
  	goto Bad_ReleaseLock;
  
      /* if no more locks left, a callback would be triggered here */
--- 5253,5259 ----
      SetVolumeSync(Sync, volptr);
  
      /* Handle the actual lock release */
!     if ((errorCode = HandleLocking(targetptr, client, rights, LockRelease)))
  	goto Bad_ReleaseLock;
  
      /* if no more locks left, a callback would be triggered here */
***************
*** 5244,5249 ****
--- 5292,5298 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 5261,5273 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_ReleaseLock;
  
      code = SAFSS_ReleaseLock(acall, Fid, Sync);
  
    Bad_ReleaseLock:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 5310,5322 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_ReleaseLock;
  
      code = SAFSS_ReleaseLock(acall, Fid, Sync);
  
    Bad_ReleaseLock:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 5378,5383 ****
--- 5427,5433 ----
  {
      afs_int32 code;
      struct rx_connection *tcon = rx_ConnectionOf(acall);
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 5395,5401 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, NOTACTIVECALL, &amp;tcon)))
  	goto Bad_GetStatistics;
  
      ViceLog(1, ("SAFS_GetStatistics Received\n"));
--- 5445,5451 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, NOTACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_GetStatistics;
  
      ViceLog(1, ("SAFS_GetStatistics Received\n"));
***************
*** 5408,5414 ****
      SetSystemStats((struct AFSStatistics *)Statistics);
  
    Bad_GetStatistics:
!     code = CallPostamble(tcon, code);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 5458,5464 ----
      SetSystemStats((struct AFSStatistics *)Statistics);
  
    Bad_GetStatistics:
!     code = CallPostamble(tcon, code, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 5527,5533 ****
  static void
  FillPerfValues(struct afs_PerfStats *a_perfP)
  {				/*FillPerfValues */
! 
      int dir_Buffers;		/*# buffers in use by dir package */
      int dir_Calls;		/*# read calls in dir package */
      int dir_IOs;		/*# I/O ops in dir package */
--- 5577,5583 ----
  static void
  FillPerfValues(struct afs_PerfStats *a_perfP)
  {				/*FillPerfValues */
!     afs_uint32 hi, lo;
      int dir_Buffers;		/*# buffers in use by dir package */
      int dir_Calls;		/*# read calls in dir package */
      int dir_IOs;		/*# I/O ops in dir package */
***************
*** 5545,5553 ****
      a_perfP-&gt;vcache_S_Gets = VnodeClassInfo[vSmall].gets;
      a_perfP-&gt;vcache_S_Reads = VnodeClassInfo[vSmall].reads;
      a_perfP-&gt;vcache_S_Writes = VnodeClassInfo[vSmall].writes;
!     a_perfP-&gt;vcache_H_Entries = VolumeCacheSize;
!     a_perfP-&gt;vcache_H_Gets = VolumeGets;
!     a_perfP-&gt;vcache_H_Replacements = VolumeReplacements;
  
      /*
       * Directory section.
--- 5595,5605 ----
      a_perfP-&gt;vcache_S_Gets = VnodeClassInfo[vSmall].gets;
      a_perfP-&gt;vcache_S_Reads = VnodeClassInfo[vSmall].reads;
      a_perfP-&gt;vcache_S_Writes = VnodeClassInfo[vSmall].writes;
!     a_perfP-&gt;vcache_H_Entries = VStats.hdr_cache_size;
!     SplitInt64(VStats.hdr_gets, hi, lo);
!     a_perfP-&gt;vcache_H_Gets = lo;
!     SplitInt64(VStats.hdr_loads, hi, lo);
!     a_perfP-&gt;vcache_H_Replacements = lo;
  
      /*
       * Directory section.
***************
*** 5780,5785 ****
--- 5832,5867 ----
  #endif
  	break;
  
+     case AFS_XSTATSCOLL_CBSTATS:
+ 	afs_perfstats.numPerfCalls++;
+ 
+ 	dataBytes = sizeof(struct cbcounters);
+ 	dataBuffP = (afs_int32 *) malloc(dataBytes);
+ 	{
+ 	    extern struct cbcounters cbstuff;
+ 	    dataBuffP[0]=cbstuff.DeleteFiles;
+ 	    dataBuffP[1]=cbstuff.DeleteCallBacks;
+ 	    dataBuffP[2]=cbstuff.BreakCallBacks;
+ 	    dataBuffP[3]=cbstuff.AddCallBacks;
+ 	    dataBuffP[4]=cbstuff.GotSomeSpaces;
+ 	    dataBuffP[5]=cbstuff.DeleteAllCallBacks;
+ 	    dataBuffP[6]=cbstuff.nFEs;
+ 	    dataBuffP[7]=cbstuff.nCBs;
+ 	    dataBuffP[8]=cbstuff.nblks;
+ 	    dataBuffP[9]=cbstuff.CBsTimedOut;
+ 	    dataBuffP[10]=cbstuff.nbreakers;
+ 	    dataBuffP[11]=cbstuff.GSS1;
+ 	    dataBuffP[12]=cbstuff.GSS2;
+ 	    dataBuffP[13]=cbstuff.GSS3;
+ 	    dataBuffP[14]=cbstuff.GSS4;
+ 	    dataBuffP[15]=cbstuff.GSS5;
+ 	}
+ 
+ 	a_dataP-&gt;AFS_CollData_len = dataBytes &gt;&gt; 2;
+ 	a_dataP-&gt;AFS_CollData_val = dataBuffP;
+ 	break;
+ 
+ 
      default:
  	/*
  	 * Illegal collection number.
***************
*** 5820,5825 ****
--- 5902,5908 ----
      register int i;
      struct client *client = 0;
      struct rx_connection *tcon;
+     struct host *thost;
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
      struct timeval opStartTime, opStopTime;	/* Start/stop times for RPC op */
***************
*** 5845,5851 ****
      FS_LOCK;
      AFSCallStats.GiveUpCallBacks++, AFSCallStats.TotalCalls++;
      FS_UNLOCK;
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_GiveUpCallBacks;
  
      if (!FidArray &amp;&amp; !CallBackArray) {
--- 5928,5934 ----
      FS_LOCK;
      AFSCallStats.GiveUpCallBacks++, AFSCallStats.TotalCalls++;
      FS_UNLOCK;
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_GiveUpCallBacks;
  
      if (!FidArray &amp;&amp; !CallBackArray) {
***************
*** 5878,5884 ****
      }
  
    Bad_GiveUpCallBacks:
!     errorCode = CallPostamble(tcon, errorCode);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 5961,5967 ----
      }
  
    Bad_GiveUpCallBacks:
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 5947,5976 ****
  {
      afs_int32 code;
      struct rx_connection *tcon;
      afs_int32 *dataBuffP;
      afs_int32 dataBytes;
- #if FS_STATS_DETAILED
-     struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
-     struct timeval opStartTime, opStopTime;	/* Start/stop times for RPC op */
-     struct timeval elapsedTime;	/* Transfer time */
  
-     /*
-      * Set our stats pointer, remember when the RPC operation started, and
-      * tally the operation.
-      */
-     opP = &amp;(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETCAPABILITIES]);
      FS_LOCK;
!     (opP-&gt;numOps)++;
      FS_UNLOCK;
!     TM_GetTimeOfDay(&amp;opStartTime, 0);
! #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, NOTACTIVECALL, &amp;tcon)))
  	goto Bad_GetCaps;
  
-     FS_LOCK;
-     AFSCallStats.GetCapabilities++, AFSCallStats.TotalCalls++;
-     FS_UNLOCK;
      dataBytes = 1 * sizeof(afs_int32);
      dataBuffP = (afs_int32 *) malloc(dataBytes);
      dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS;
--- 6030,6048 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      afs_int32 *dataBuffP;
      afs_int32 dataBytes;
  
      FS_LOCK;
!     AFSCallStats.GetCapabilities++, AFSCallStats.TotalCalls++;
!     afs_FullPerfStats.overall.fs_nGetCaps++;
      FS_UNLOCK;
!     ViceLog(2, ("SAFS_GetCapabilties\n"));
  
!     if ((code = CallPreamble(acall, NOTACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_GetCaps;
  
      dataBytes = 1 * sizeof(afs_int32);
      dataBuffP = (afs_int32 *) malloc(dataBytes);
      dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS;
***************
*** 5981,6008 ****
      capabilities-&gt;Capabilities_len = dataBytes / sizeof(afs_int32);
      capabilities-&gt;Capabilities_val = dataBuffP;
  
-     ViceLog(2, ("SAFS_GetCapabilties\n"));
- 
    Bad_GetCaps:
!     code = CallPostamble(tcon, code);
  
- #if FS_STATS_DETAILED
-     TM_GetTimeOfDay(&amp;opStopTime, 0);
-     fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-     if (code == 0) {
- 	FS_LOCK;
- 	(opP-&gt;numSuccesses)++;
- 	fs_stats_AddTo((opP-&gt;sumTime), elapsedTime);
- 	fs_stats_SquareAddTo((opP-&gt;sqrTime), elapsedTime);
- 	if (fs_stats_TimeLessThan(elapsedTime, (opP-&gt;minTime))) {
- 	    fs_stats_TimeAssign((opP-&gt;minTime), elapsedTime);
- 	}
- 	if (fs_stats_TimeGreaterThan(elapsedTime, (opP-&gt;maxTime))) {
- 	    fs_stats_TimeAssign((opP-&gt;maxTime), elapsedTime);
- 	}
- 	FS_UNLOCK;
-     }
- #endif /* FS_STATS_DETAILED */
      return 0;
  }
  
--- 6053,6062 ----
      capabilities-&gt;Capabilities_len = dataBytes / sizeof(afs_int32);
      capabilities-&gt;Capabilities_val = dataBuffP;
  
    Bad_GetCaps:
!     code = CallPostamble(tcon, code, thost);
! 
  
      return 0;
  }
  
***************
*** 6033,6039 ****
      for (i = 0; i &lt; nids; i++, vd++) {
  	if (!*vd)
  	    continue;
! 	client = h_ID2Client(*vd);	/* returns client write locked, or NULL */
  	if (!client)
  	    continue;
  
--- 6087,6093 ----
      for (i = 0; i &lt; nids; i++, vd++) {
  	if (!*vd)
  	    continue;
! 	client = h_ID2Client(*vd);	/* returns write locked and refCounted, or NULL */
  	if (!client)
  	    continue;
  
***************
*** 6049,6054 ****
--- 6103,6109 ----
  	    client-&gt;CPS.prlist_len = 0;
  	}
  	ReleaseWriteLock(&amp;client-&gt;lock);
+ 	PutClient(&amp;client);
      }
  
      addr = addrs-&gt;IPAddrs_val;
***************
*** 6191,6196 ****
--- 6246,6252 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
      struct timeval opStartTime, opStopTime;	/* Start/stop times for RPC op */
***************
*** 6206,6212 ****
      FS_UNLOCK;
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_GetVolumeInfo;
  
      FS_LOCK;
--- 6262,6268 ----
      FS_UNLOCK;
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_GetVolumeInfo;
  
      FS_LOCK;
***************
*** 6220,6226 ****
      avolinfo-&gt;Type4 = 0xabcd9999;	/* tell us to try new vldb */
  
    Bad_GetVolumeInfo:
!     code = CallPostamble(tcon, code);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 6276,6282 ----
      avolinfo-&gt;Type4 = 0xabcd9999;	/* tell us to try new vldb */
  
    Bad_GetVolumeInfo:
!     code = CallPostamble(tcon, code, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 6258,6263 ****
--- 6314,6320 ----
      afs_int32 rights, anyrights;	/* rights for this and any user */
      AFSFid dummyFid;
      struct rx_connection *tcon;
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 6277,6283 ****
  #endif /* FS_STATS_DETAILED */
  
      ViceLog(1, ("SAFS_GetVolumeStatus for volume %u\n", avolid));
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_GetVolumeStatus;
  
      FS_LOCK;
--- 6334,6340 ----
  #endif /* FS_STATS_DETAILED */
  
      ViceLog(1, ("SAFS_GetVolumeStatus for volume %u\n", avolid));
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_GetVolumeStatus;
  
      FS_LOCK;
***************
*** 6319,6325 ****
  	*OfflineMsg = (char *)malloc(1);
  	**OfflineMsg = 0;
      }
!     errorCode = CallPostamble(tcon, errorCode);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 6376,6382 ----
  	*OfflineMsg = (char *)malloc(1);
  	**OfflineMsg = 0;
      }
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 6362,6367 ****
--- 6419,6425 ----
      afs_int32 rights, anyrights;	/* rights for this and any user */
      AFSFid dummyFid;
      struct rx_connection *tcon = rx_ConnectionOf(acall);
+     struct host *thost;
      struct client *t_client = NULL;	/* tmp ptr to client data */
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 6381,6387 ****
  #endif /* FS_STATS_DETAILED */
  
      ViceLog(1, ("SAFS_SetVolumeStatus for volume %u\n", avolid));
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_SetVolumeStatus;
  
      FS_LOCK;
--- 6439,6445 ----
  #endif /* FS_STATS_DETAILED */
  
      ViceLog(1, ("SAFS_SetVolumeStatus for volume %u\n", avolid));
!     if ((errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_SetVolumeStatus;
  
      FS_LOCK;
***************
*** 6416,6422 ****
      PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, 
  		     volptr, &amp;client);
      ViceLog(2, ("SAFS_SetVolumeStatus returns %d\n", errorCode));
!     errorCode = CallPostamble(tcon, errorCode);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
--- 6474,6480 ----
      PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, 
  		     volptr, &amp;client);
      ViceLog(2, ("SAFS_SetVolumeStatus returns %d\n", errorCode));
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
      t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
  
***************
*** 6454,6459 ****
--- 6512,6518 ----
      int len;
      char *temp;
      struct rx_connection *tcon;
+     struct host *thost;
  #endif
      int errorCode = 0;
  #if FS_STATS_DETAILED
***************
*** 6478,6484 ****
      return FSERR_EOPNOTSUPP;
  
  #ifdef	notdef
!     if (errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon))
  	goto Bad_GetRootVolume;
      FS_LOCK;
      AFSCallStats.GetRootVolume++, AFSCallStats.TotalCalls++;
--- 6537,6543 ----
      return FSERR_EOPNOTSUPP;
  
  #ifdef	notdef
!     if (errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost))
  	goto Bad_GetRootVolume;
      FS_LOCK;
      AFSCallStats.GetRootVolume++, AFSCallStats.TotalCalls++;
***************
*** 6507,6513 ****
      *VolumeName = temp;		/* freed by rx server-side stub */
  
    Bad_GetRootVolume:
!     errorCode = CallPostamble(tcon, errorCode);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 6566,6572 ----
      *VolumeName = temp;		/* freed by rx server-side stub */
  
    Bad_GetRootVolume:
!     errorCode = CallPostamble(tcon, errorCode, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 6540,6545 ****
--- 6599,6605 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
      struct timeval opStartTime, opStopTime;	/* Start/stop times for RPC op */
***************
*** 6556,6568 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon)))
  	goto Bad_CheckToken;
  
      code = FSERR_ECONNREFUSED;
  
    Bad_CheckToken:
!     code = CallPostamble(tcon, code);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 6616,6628 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_CheckToken;
  
      code = FSERR_ECONNREFUSED;
  
    Bad_CheckToken:
!     code = CallPostamble(tcon, code, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 6592,6597 ****
--- 6652,6658 ----
  {
      afs_int32 code;
      struct rx_connection *tcon;
+     struct host *thost;
      struct timeval tpl;
  #if FS_STATS_DETAILED
      struct fs_stats_opTimingData *opP;	/* Ptr to this op's timing struct */
***************
*** 6609,6615 ****
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, NOTACTIVECALL, &amp;tcon)))
  	goto Bad_GetTime;
  
      FS_LOCK;
--- 6670,6676 ----
      TM_GetTimeOfDay(&amp;opStartTime, 0);
  #endif /* FS_STATS_DETAILED */
  
!     if ((code = CallPreamble(acall, NOTACTIVECALL, &amp;tcon, &amp;thost)))
  	goto Bad_GetTime;
  
      FS_LOCK;
***************
*** 6622,6628 ****
      ViceLog(2, ("SAFS_GetTime returns %u, %u\n", *Seconds, *USeconds));
  
    Bad_GetTime:
!     code = CallPostamble(tcon, code);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
--- 6683,6689 ----
      ViceLog(2, ("SAFS_GetTime returns %u, %u\n", *Seconds, *USeconds));
  
    Bad_GetTime:
!     code = CallPostamble(tcon, code, thost);
  
  #if FS_STATS_DETAILED
      TM_GetTimeOfDay(&amp;opStopTime, 0);
***************
*** 7279,7289 ****
--- 7340,7364 ----
      sys2et[EMEDIUMTYPE] = UAEMEDIUMTYPE;
  }
  
+ /* NOTE:  2006-03-01                                                     
+  *  SRXAFS_CallBackRxConnAddr should be re-written as follows:           
+  *  - pass back the connection, client, and host from CallPreamble       
+  *  - keep a ref on the client, which we don't now                       
+  *  - keep a hold on the host, which we already do                       
+  *  - pass the connection, client, and host down into SAFSS_*, and use   
+  *    them instead of independently discovering them via rx_ConnectionOf 
+  *    (safe) and rx_GetSpecific (not so safe)                            
+  *  The idea being that we decide what client and host we're going to use
+  *  when CallPreamble is called, and stay consistent throughout the call.
+  *  This change is too invasive for 1.4.1 but should be made in 1.5.x.   
+  */                                                                      
+ 
  afs_int32
  SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
  {
      Error errorCode = 0;
      struct rx_connection *tcon;
+     struct host *tcallhost;
  #ifdef __EXPERIMENTAL_CALLBACK_CONN_MOVING
      struct host *thost;
      struct client *tclient;
***************
*** 7292,7298 ****
      struct rx_connection *conn;
  #endif
      
!     if (errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon))
  	    goto Bad_CallBackRxConnAddr1;
      
  #ifndef __EXPERIMENTAL_CALLBACK_CONN_MOVING
--- 7367,7373 ----
      struct rx_connection *conn;
  #endif
      
!     if (errorCode = CallPreamble(acall, ACTIVECALL, &amp;tcon, &amp;tcallhost))
  	    goto Bad_CallBackRxConnAddr1;
      
  #ifndef __EXPERIMENTAL_CALLBACK_CONN_MOVING
***************
*** 7341,7357 ****
  	thost-&gt;host           = addr;
  	rx_SetConnDeadTime(thost-&gt;callback_rxcon, 50);
  	rx_SetConnHardDeadTime(thost-&gt;callback_rxcon, AFS_HARDDEADTIME);
  	H_UNLOCK;
! 	errorCode = CallPostamble(tcon, errorCode);
  	return errorCode;
      } else {
  	rx_DestroyConnection(conn);
      }	    
    Bad_CallBackRxConnAddr:
      H_UNLOCK;
  #endif
  
!     errorCode = CallPostamble(tcon, errorCode);
   Bad_CallBackRxConnAddr1:
      return errorCode;          /* failure */
  }
--- 7416,7436 ----
  	thost-&gt;host           = addr;
  	rx_SetConnDeadTime(thost-&gt;callback_rxcon, 50);
  	rx_SetConnHardDeadTime(thost-&gt;callback_rxcon, AFS_HARDDEADTIME);
+ 	h_ReleaseClient_r(tclient);
+ 	/* The hold on thost will be released by CallPostamble */
  	H_UNLOCK;
! 	errorCode = CallPostamble(tcon, errorCode, tcallhost);
  	return errorCode;
      } else {
  	rx_DestroyConnection(conn);
      }	    
    Bad_CallBackRxConnAddr:
+     h_ReleaseClient_r(tclient);
+     /* The hold on thost will be released by CallPostamble */
      H_UNLOCK;
  #endif
  
!     errorCode = CallPostamble(tcon, errorCode, tcallhost);
   Bad_CallBackRxConnAddr1:
      return errorCode;          /* failure */
  }
Index: openafs/src/viced/callback.c
diff -c openafs/src/viced/callback.c:1.74 openafs/src/viced/callback.c:1.77
*** openafs/src/viced/callback.c:1.74	Tue Feb 14 11:58:13 2006
--- openafs/src/viced/callback.c	Fri Mar 17 14:54:49 2006
***************
*** 5,10 ****
--- 5,12 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /*
***************
*** 83,89 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/callback.c,v 1.74 2006/02/14 16:58:13 rees Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;		/* for malloc() */
--- 85,91 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/callback.c,v 1.77 2006/03/17 19:54:49 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;		/* for malloc() */
***************
*** 120,213 ****
  
  #include &lt;afs/ptclient.h&gt;	/* need definition of prlist for host.h */
  #include "host.h"
  
  extern afsUUID FS_HostUUID;
  extern int hostCount;
! int ShowProblems = 1;
! 
! /* Maximum number of call backs to break at once, single fid */
! /* There is some debate as to just how large this value should be */
! /* Ideally, it would be very very large, but I am afraid that the */
! /* cache managers will all send in their responses simultaneously, */
! /* thereby swamping the file server.  As a result, something like */
! /* 10 or 15 might be a better bet. */
! #define MAX_CB_HOSTS	10
! 
! /* max time to break a callback, otherwise client is dead or net is hosed */
! #define MAXCBT 25
! 
! #define u_byte	unsigned char
  
  struct cbcounters cbstuff;
  
! struct cbstruct {
!     struct host *hp;
!     afs_uint32 thead;
! };
  
! struct FileEntry {
!     afs_uint32 vnode;
!     afs_uint32 unique;
!     afs_uint32 volid;
!     afs_uint32 fnext;
!     afs_uint32 ncbs;
!     afs_uint32 firstcb;
!     afs_uint32 status;
!     afs_uint32 spare;
! } *FE;				/* Don't use FE[0] */
! #define FE_LATER 0x1
! 
! struct CallBack {
!     afs_uint32 cnext;		/* Next call back entry */
!     afs_uint32 fhead;		/* Head of this call back chain */
!     u_byte thead;		/* Head of timeout chain */
!     u_byte status;		/* Call back status; see definitions, below */
!     afs_uint32 hhead;		/* Head of host table chain */
!     afs_uint32 tprev, tnext;	/* Timeout chain */
!     afs_uint32 hprev, hnext;	/* Chain from host table */
!     unsigned short spare;	/* make it a multiple of 32 bits. */
! } *CB;				/* Don't use CB[0] */
! 
! /* status values for status field of CallBack structure */
! #define CB_NORMAL   1		/* Normal call back */
! #define CB_DELAYED  2		/* Delayed call back due to rpc problems.
! 				 * The call back entry will be added back to the
! 				 * host list at the END of the list, so that
! 				 * searching backwards in the list will find all
! 				 * the (consecutive)host. delayed call back entries */
! #define CB_VOLUME   3		/* Callback for a volume */
! #define CB_BULK     4		/* Normal callbacks, handed out from FetchBulkStatus */
! 
! /* call back indices to pointers, and vice-versa */
! #define itocb(i)    ((i)?CB+(i):0)
! #define cbtoi(cbp)  (!(cbp)?0:(cbp)-CB)
! 
! /* file entry indices to pointers, and vice-versa */
! #define itofe(i)    ((i)?FE+(i):0)
! #define fetoi(fep)  (!(fep)?0:(fep)-FE)
! 
! /* Timeouts:  there are 128 possible timeout values in effect at any
!  * given time.  Each timeout represents timeouts in an interval of 128
!  * seconds.  So the maximum timeout for a call back is 128*128=16384
!  * seconds, or 4 1/2 hours.  The timeout cleanup stuff is called only
!  * if space runs out or by the file server every 5 minutes.  This 5
!  * minute slack should be allowed for--so a maximum time of 4 hours
!  * is safer.
!  *
!  * Timeouts must be chosen to correspond to an exact multiple
!  * of 128, because all times are truncated to a 128 multiple, and
!  * timed out if the current truncated time is &lt;= to the truncated time
!  * corresponding to the timeout queue.
!  */
  
- /* Unix time to Call Back time, and vice-versa.  Call back time is
-    in units of 128 seconds, corresponding to time queues. */
- #define CBtime(uxtime)	((uxtime)&gt;&gt;7)
- #define UXtime(cbtime)	((cbtime)&lt;&lt;7)
- 
- /* Given a Unix time, compute the closest Unix time that corresponds to
-    a time queue, rounding up */
- #define TimeCeiling(uxtime)	(((uxtime)+127)&amp;~127)
  
  /* Time to live for call backs depends upon number of users of the file.
   * TimeOuts is indexed by this number/8 (using TimeOut macro).  Times
--- 122,145 ----
  
  #include &lt;afs/ptclient.h&gt;	/* need definition of prlist for host.h */
  #include "host.h"
+ #include "callback.h"
+ #ifdef AFS_DEMAND_ATTACH_FS
+ #include "../tviced/serialize_state.h"
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  
  extern afsUUID FS_HostUUID;
  extern int hostCount;
! static int ShowProblems = 1;
  
  struct cbcounters cbstuff;
  
! static struct FileEntry * FE = NULL;    /* don't use FE[0] */
! static struct CallBack * CB = NULL;     /* don't use CB[0] */
  
! static struct CallBack * CBfree = NULL;
! static struct FileEntry * FEfree = NULL;
  
  
  /* Time to live for call backs depends upon number of users of the file.
   * TimeOuts is indexed by this number/8 (using TimeOut macro).  Times
***************
*** 229,280 ****
  /* minimum time given for a call back */
  static int MinTimeOut = (7 * 60);
  
- #define TimeOutCutoff   ((sizeof(TimeOuts)/sizeof(TimeOuts[0]))*8)
- #define TimeOut(nusers)  ((nusers)&gt;=TimeOutCutoff? MinTimeOut: TimeOuts[(nusers)&gt;&gt;3])
- 
- /* time out at server is 3 minutes more than ws */
- #define ServerBias	  (3*60)
- 
  /* Heads of CB queues; a timeout index is 1+index into this array */
! static afs_uint32 timeout[128];
! 
! /* Convert cbtime to timeout queue index */
! #define TIndex(cbtime)  (((cbtime)&amp;127)+1)
! 
! /* Convert cbtime to pointer to timeout queue head */
! #define THead(cbtime)	(&amp;timeout[TIndex(cbtime)-1])
  
  static afs_int32 tfirst;	/* cbtime of oldest unexpired call back time queue */
  
- /* Normalize index into timeout array so that two such indices will be
-    ordered correctly, so that they can be compared to see which times
-    sooner, or so that the difference in time out times between them
-    can be computed. */
- #define TNorm(index)   ((index)&lt;TIndex(tfirst)?(index)+128:(index))
- 
- /* This converts a timeout index into the actual time it will expire */
- #define TIndexToTime(index) (UXtime(TNorm(index) - TIndex(tfirst) + tfirst))
- 
- 
- /* Convert pointer to timeout queue head to index, and vice versa */
- #define ttoi(t)		((t-timeout)+1)
- #define itot(i)		((timeout)+(i-1))
  
  /* 16 byte object get/free routines */
  struct object {
      struct object *next;
  };
  
- struct VCBParams {
-     struct cbstruct cba[MAX_CB_HOSTS];	/* re-entrant storage */
-     unsigned int ncbas;
-     afs_uint32 thead;		/* head of timeout queue for youngest callback */
-     struct AFSFid *fid;
- };
- 
- struct CallBack *CBfree = 0;
- struct FileEntry *FEfree = 0;
- 
  /* Prototypes for static routines */
  static struct FileEntry *FindFE(register AFSFid * fid);
  static struct CallBack *iGetCB(register int *nused);
--- 161,177 ----
  /* minimum time given for a call back */
  static int MinTimeOut = (7 * 60);
  
  /* Heads of CB queues; a timeout index is 1+index into this array */
! static afs_uint32 timeout[CB_NUM_TIMEOUT_QUEUES];
  
  static afs_int32 tfirst;	/* cbtime of oldest unexpired call back time queue */
  
  
  /* 16 byte object get/free routines */
  struct object {
      struct object *next;
  };
  
  /* Prototypes for static routines */
  static struct FileEntry *FindFE(register AFSFid * fid);
  static struct CallBack *iGetCB(register int *nused);
***************
*** 300,307 ****
  				    struct VCBParams *parms);
  static int MultiBreakVolumeLaterCallBack(struct host *host, int isheld,
  					 struct VCBParams *parms);
- static int lih_r(register struct host *host, register int held,
- 		 register struct host *hostp);
  static int GetSomeSpace_r(struct host *hostp, int locked);
  static int ClearHostCallbacks_r(struct host *hp, int locked);
  
--- 197,202 ----
***************
*** 310,321 ****
  #define FreeCB(cb) iFreeCB((struct CallBack *)cb, &amp;cbstuff.nCBs)
  #define FreeFE(fe) iFreeFE((struct FileEntry *)fe, &amp;cbstuff.nFEs)
  
  /* Other protos - move out sometime */
! extern void ShutDown();
  
! #define VHASH 512		/* Power of 2 */
! static afs_uint32 HashTable[VHASH];	/* File entry hash table */
! #define VHash(volume, unique) (((volume)+(unique))&amp;(VHASH-1))
  
  static struct FileEntry *
  FindFE(register AFSFid * fid)
--- 205,215 ----
  #define FreeCB(cb) iFreeCB((struct CallBack *)cb, &amp;cbstuff.nCBs)
  #define FreeFE(fe) iFreeFE((struct FileEntry *)fe, &amp;cbstuff.nFEs)
  
+ 
  /* Other protos - move out sometime */
! void PrintCB(register struct CallBack *cb, afs_uint32 now);
  
! static afs_uint32 HashTable[FEHASH_SIZE];	/* File entry hash table */
  
  static struct FileEntry *
  FindFE(register AFSFid * fid)
***************
*** 324,330 ****
      register int fei;
      register struct FileEntry *fe;
  
!     hash = VHash(fid-&gt;Volume, fid-&gt;Unique);
      for (fei = HashTable[hash]; fei; fei = fe-&gt;fnext) {
  	fe = itofe(fei);
  	if (fe-&gt;volid == fid-&gt;Volume &amp;&amp; fe-&gt;unique == fid-&gt;Unique
--- 218,224 ----
      register int fei;
      register struct FileEntry *fe;
  
!     hash = FEHash(fid-&gt;Volume, fid-&gt;Unique);
      for (fei = HashTable[hash]; fei; fei = fe-&gt;fnext) {
  	fe = itofe(fei);
  	if (fe-&gt;volid == fid-&gt;Volume &amp;&amp; fe-&gt;unique == fid-&gt;Unique
***************
*** 423,433 ****
      if (!host-&gt;cblist) {
  	host-&gt;cblist = cb-&gt;hnext = cb-&gt;hprev = cbtoi(cb);
      } else {
! 	register struct CallBack *hhp = itocb(host-&gt;cblist);
  
! 	cb-&gt;hprev = hhp-&gt;hprev;
! 	cb-&gt;hnext = host-&gt;cblist;
! 	hhp-&gt;hprev = (itocb(hhp-&gt;hprev)-&gt;hnext = cbtoi(cb));
      }
      return 0;
  }
--- 317,327 ----
      if (!host-&gt;cblist) {
  	host-&gt;cblist = cb-&gt;hnext = cb-&gt;hprev = cbtoi(cb);
      } else {
! 	register struct CallBack *fcb = itocb(host-&gt;cblist);
  
! 	cb-&gt;hprev = fcb-&gt;hprev;
! 	cb-&gt;hnext = cbtoi(fcb);
! 	fcb-&gt;hprev = (itocb(fcb-&gt;hprev)-&gt;hnext = cbtoi(cb));
      }
      return 0;
  }
***************
*** 477,483 ****
  /* N.B.  This one also deletes the CB, and also possibly parent FE, so
   * make sure that it is not on any other list before calling this
   * routine */
! int Ccdelpt = 0, CcdelB = 0;
  
  static int
  CDelPtr(register struct FileEntry *fe, register afs_uint32 * cbp,
--- 371,377 ----
  /* N.B.  This one also deletes the CB, and also possibly parent FE, so
   * make sure that it is not on any other list before calling this
   * routine */
! static int Ccdelpt = 0, CcdelB = 0;
  
  static int
  CDelPtr(register struct FileEntry *fe, register afs_uint32 * cbp,
***************
*** 524,530 ****
  FDel(register struct FileEntry *fe)
  {
      register int fei = fetoi(fe);
!     register afs_uint32 *p = &amp;HashTable[VHash(fe-&gt;volid, fe-&gt;unique)];
  
      while (*p &amp;&amp; *p != fei)
  	p = &amp;itofe(*p)-&gt;fnext;
--- 418,424 ----
  FDel(register struct FileEntry *fe)
  {
      register int fei = fetoi(fe);
!     register afs_uint32 *p = &amp;HashTable[FEHash(fe-&gt;volid, fe-&gt;unique)];
  
      while (*p &amp;&amp; *p != fei)
  	p = &amp;itofe(*p)-&gt;fnext;
***************
*** 534,539 ****
--- 428,434 ----
      return 0;
  }
  
+ /* initialize the callback package */
  int
  InitCallBack(int nblks)
  {
***************
*** 541,559 ****
      tfirst = CBtime(FT_ApproxTime());
      /* N.B. The "-1", below, is because
       * FE[0] and CB[0] are not used--and not allocated */
!     FE = ((struct FileEntry *)(calloc(nblks, sizeof(struct FileEntry)))) - 1;
      if (!FE) {
  	ViceLog(0, ("Failed malloc in InitCallBack\n"));
  	assert(0);
      }
      cbstuff.nFEs = nblks;
      while (cbstuff.nFEs)
  	FreeFE(&amp;FE[cbstuff.nFEs]);	/* This is correct */
!     CB = ((struct CallBack *)(calloc(nblks, sizeof(struct CallBack)))) - 1;
      if (!CB) {
  	ViceLog(0, ("Failed malloc in InitCallBack\n"));
  	assert(0);
      }
      cbstuff.nCBs = nblks;
      while (cbstuff.nCBs)
  	FreeCB(&amp;CB[cbstuff.nCBs]);	/* This is correct */
--- 436,456 ----
      tfirst = CBtime(FT_ApproxTime());
      /* N.B. The "-1", below, is because
       * FE[0] and CB[0] are not used--and not allocated */
!     FE = ((struct FileEntry *)(calloc(nblks, sizeof(struct FileEntry))));
      if (!FE) {
  	ViceLog(0, ("Failed malloc in InitCallBack\n"));
  	assert(0);
      }
+     FE--;  /* FE[0] is supposed to point to junk */
      cbstuff.nFEs = nblks;
      while (cbstuff.nFEs)
  	FreeFE(&amp;FE[cbstuff.nFEs]);	/* This is correct */
!     CB = ((struct CallBack *)(calloc(nblks, sizeof(struct CallBack))));
      if (!CB) {
  	ViceLog(0, ("Failed malloc in InitCallBack\n"));
  	assert(0);
      }
+     CB--;  /* CB[0] is supposed to point to junk */
      cbstuff.nCBs = nblks;
      while (cbstuff.nCBs)
  	FreeCB(&amp;CB[cbstuff.nCBs]);	/* This is correct */
***************
*** 698,704 ****
  	fe-&gt;unique = fid-&gt;Unique;
  	fe-&gt;ncbs = 0;
  	fe-&gt;status = 0;
! 	hash = VHash(fid-&gt;Volume, fid-&gt;Unique);
  	fe-&gt;fnext = HashTable[hash];
  	HashTable[hash] = fetoi(fe);
      }
--- 595,601 ----
  	fe-&gt;unique = fid-&gt;Unique;
  	fe-&gt;ncbs = 0;
  	fe-&gt;status = 0;
! 	hash = FEHash(fid-&gt;Volume, fid-&gt;Unique);
  	fe-&gt;fnext = HashTable[hash];
  	HashTable[hash] = fetoi(fe);
      }
***************
*** 1304,1310 ****
  
      H_LOCK;
      fid.Volume = volume, fid.Vnode = fid.Unique = 0;
!     for (hash = 0; hash &lt; VHASH; hash++) {
  	for (feip = &amp;HashTable[hash]; (fe = itofe(*feip));) {
  	    if (fe-&gt;volid == volume) {
  		register struct CallBack *cbnext;
--- 1201,1207 ----
  
      H_LOCK;
      fid.Volume = volume, fid.Vnode = fid.Unique = 0;
!     for (hash = 0; hash &lt; FEHASH_SIZE; hash++) {
  	for (feip = &amp;HashTable[hash]; (fe = itofe(*feip));) {
  	    if (fe-&gt;volid == volume) {
  		register struct CallBack *cbnext;
***************
*** 1362,1368 ****
  BreakVolumeCallBacksLater(afs_uint32 volume)
  {
      int hash;
!     afs_int32 *feip;
      struct FileEntry *fe;
      struct CallBack *cb;
      struct host *host;
--- 1259,1265 ----
  BreakVolumeCallBacksLater(afs_uint32 volume)
  {
      int hash;
!     afs_uint32 *feip;
      struct FileEntry *fe;
      struct CallBack *cb;
      struct host *host;
***************
*** 1370,1377 ****
  
      ViceLog(25, ("Setting later on volume %u\n", volume));
      H_LOCK;
!     for (hash = 0; hash &lt; VHASH; hash++) {
! 	for (feip = &amp;HashTable[hash]; fe = itofe(*feip);) {
  	    if (fe-&gt;volid == volume) {
  		register struct CallBack *cbnext;
  		for (cb = itocb(fe-&gt;firstcb); cb; cb = cbnext) {
--- 1267,1274 ----
  
      ViceLog(25, ("Setting later on volume %u\n", volume));
      H_LOCK;
!     for (hash = 0; hash &lt; FEHASH_SIZE; hash++) {
! 	for (feip = &amp;HashTable[hash]; (fe = itofe(*feip)) != NULL; ) {
  	    if (fe-&gt;volid == volume) {
  		register struct CallBack *cbnext;
  		for (cb = itocb(fe-&gt;firstcb); cb; cb = cbnext) {
***************
*** 1383,1389 ****
  		FSYNC_LOCK;
  		fe-&gt;status |= FE_LATER;
  		FSYNC_UNLOCK;
! 		found++;
  	    }
  	    feip = &amp;fe-&gt;fnext;
  	}
--- 1280,1286 ----
  		FSYNC_LOCK;
  		fe-&gt;status |= FE_LATER;
  		FSYNC_UNLOCK;
! 		found = 1;
  	    }
  	    feip = &amp;fe-&gt;fnext;
  	}
***************
*** 1410,1416 ****
  {
      struct AFSFid fid;
      int hash;
!     afs_int32 *feip;
      struct CallBack *cb;
      struct FileEntry *fe = NULL;
      struct FileEntry *myfe = NULL;
--- 1307,1313 ----
  {
      struct AFSFid fid;
      int hash;
!     afs_uint32 *feip;
      struct CallBack *cb;
      struct FileEntry *fe = NULL;
      struct FileEntry *myfe = NULL;
***************
*** 1426,1433 ****
      /* Pick the first volume we see to clean up */
      fid.Volume = fid.Vnode = fid.Unique = 0;
  
!     for (hash = 0; hash &lt; VHASH; hash++) {
! 	for (feip = &amp;HashTable[hash]; fe = itofe(*feip);) {
  	    if (fe &amp;&amp; (fe-&gt;status &amp; FE_LATER)
  		&amp;&amp; (fid.Volume == 0 || fid.Volume == fe-&gt;volid)) {
  		/* Ugly, but used to avoid left side casting */
--- 1323,1330 ----
      /* Pick the first volume we see to clean up */
      fid.Volume = fid.Vnode = fid.Unique = 0;
  
!     for (hash = 0; hash &lt; FEHASH_SIZE; hash++) {
! 	for (feip = &amp;HashTable[hash]; (fe = itofe(*feip)) != NULL; ) {
  	    if (fe &amp;&amp; (fe-&gt;status &amp; FE_LATER)
  		&amp;&amp; (fid.Volume == 0 || fid.Volume == fe-&gt;volid)) {
  		/* Ugly, but used to avoid left side casting */
***************
*** 1558,1580 ****
  static struct host *lih_host;
  static int lih_host_held;
  
- static int
- lih_r(register struct host *host, register int held,
-       register struct host *hostp)
- {
-     if (host-&gt;cblist
- 	&amp;&amp; ((hostp &amp;&amp; host != hostp) || (!held &amp;&amp; !h_OtherHolds_r(host)))
- 	&amp;&amp; (!lih_host || host-&gt;ActiveCall &lt; lih_host-&gt;ActiveCall)) {
- 	if (lih_host != NULL &amp;&amp; lih_host_held) {
- 	    h_Release_r(lih_host);
- 	}
- 	lih_host = host;
- 	lih_host_held = !held;
- 	held = 1;
-     }
-     return held;
- }
- 
  /* This version does not allow 'host' to be selected unless its ActiveCall 
   * is newer than 'hostp' which is the host with the oldest ActiveCall from
   * the last pass (if it is provided).  We filter out any hosts that are
--- 1455,1460 ----
***************
*** 1794,1799 ****
--- 1674,2646 ----
  
  #ifndef INTERPRET_DUMP
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * demand attach fs
+  * callback state serialization
+  */
+ static int cb_stateSaveTimeouts(struct fs_dump_state * state);
+ static int cb_stateSaveFEHash(struct fs_dump_state * state);
+ static int cb_stateSaveFEs(struct fs_dump_state * state);
+ static int cb_stateSaveFE(struct fs_dump_state * state, struct FileEntry * fe);
+ static int cb_stateRestoreTimeouts(struct fs_dump_state * state);
+ static int cb_stateRestoreFEHash(struct fs_dump_state * state);
+ static int cb_stateRestoreFEs(struct fs_dump_state * state);
+ static int cb_stateRestoreFE(struct fs_dump_state * state);
+ static int cb_stateRestoreCBs(struct fs_dump_state * state, struct FileEntry * fe, 
+ 			      struct iovec * iov, int niovecs);
+ 
+ static int cb_stateVerifyFEHash(struct fs_dump_state * state);
+ static int cb_stateVerifyFE(struct fs_dump_state * state, struct FileEntry * fe);
+ static int cb_stateVerifyFCBList(struct fs_dump_state * state, struct FileEntry * fe);
+ static int cb_stateVerifyTimeoutQueues(struct fs_dump_state * state);
+ 
+ static int cb_stateFEToDiskEntry(struct FileEntry *, struct FEDiskEntry *);
+ static int cb_stateDiskEntryToFE(struct fs_dump_state * state,
+ 				 struct FEDiskEntry *, struct FileEntry *);
+ 
+ static int cb_stateCBToDiskEntry(struct CallBack *, struct CBDiskEntry *);
+ static int cb_stateDiskEntryToCB(struct fs_dump_state * state,
+ 				 struct CBDiskEntry *, struct CallBack *);
+ 
+ static int cb_stateFillHeader(struct callback_state_header * hdr);
+ static int cb_stateCheckHeader(struct callback_state_header * hdr);
+ 
+ static int cb_stateAllocMap(struct fs_dump_state * state);
+ 
+ int
+ cb_stateSave(struct fs_dump_state * state)
+ {
+     int ret = 0;
+ 
+     AssignInt64(state-&gt;eof_offset, &amp;state-&gt;hdr-&gt;cb_offset);
+ 
+     /* invalidate callback state header */
+     memset(state-&gt;cb_hdr, 0, sizeof(struct callback_state_header));
+     if (fs_stateWriteHeader(state, &amp;state-&gt;hdr-&gt;cb_offset, state-&gt;cb_hdr,
+ 			    sizeof(struct callback_state_header))) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     fs_stateIncEOF(state, sizeof(struct callback_state_header));
+ 
+     /* dump timeout state */
+     if (cb_stateSaveTimeouts(state)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     /* dump fe hashtable state */
+     if (cb_stateSaveFEHash(state)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     /* dump callback state */
+     if (cb_stateSaveFEs(state)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     /* write the callback state header to disk */
+     cb_stateFillHeader(state-&gt;cb_hdr);
+     if (fs_stateWriteHeader(state, &amp;state-&gt;hdr-&gt;cb_offset, state-&gt;cb_hdr,
+ 			    sizeof(struct callback_state_header))) {
+ 	ret = 1;
+ 	goto done;
+     }
+     
+  done:
+     return ret;
+ }
+ 
+ int
+ cb_stateRestore(struct fs_dump_state * state)
+ {
+     int ret = 0;
+ 
+     if (fs_stateReadHeader(state, &amp;state-&gt;hdr-&gt;cb_offset, state-&gt;cb_hdr,
+ 			   sizeof(struct callback_state_header))) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (cb_stateCheckHeader(state-&gt;cb_hdr)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (cb_stateAllocMap(state)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (cb_stateRestoreTimeouts(state)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (cb_stateRestoreFEHash(state)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     /* restore FEs and CBs from disk */
+     if (cb_stateRestoreFEs(state)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     /* restore the timeout queue heads */
+     tfirst = state-&gt;cb_hdr-&gt;tfirst;
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ cb_stateRestoreIndices(struct fs_dump_state * state)
+ {
+     int i, ret = 0;
+     struct FileEntry * fe;
+     struct CallBack * cb;
+ 
+     /* restore indices in the FileEntry structures */
+     for (i = 1; i &lt; state-&gt;fe_map.len; i++) {
+ 	if (state-&gt;fe_map.entries[i].new_idx) {
+ 	    fe = itofe(state-&gt;fe_map.entries[i].new_idx);
+ 
+ 	    /* restore the fe-&gt;fnext entry */
+ 	    if (fe_OldToNew(state, fe-&gt;fnext, &amp;fe-&gt;fnext)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 
+ 	    /* restore the fe-&gt;firstcb entry */
+ 	    if (cb_OldToNew(state, fe-&gt;firstcb, &amp;fe-&gt;firstcb)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 	}
+     }
+     
+     /* restore indices in the CallBack structures */
+     for (i = 1; i &lt; state-&gt;cb_map.len; i++) {
+ 	if (state-&gt;cb_map.entries[i].new_idx) {
+ 	    cb = itocb(state-&gt;cb_map.entries[i].new_idx);
+ 
+ 	    /* restore the cb-&gt;cnext entry */
+ 	    if (cb_OldToNew(state, cb-&gt;cnext, &amp;cb-&gt;cnext)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 	    
+ 	    /* restore the cb-&gt;fhead entry */
+ 	    if (fe_OldToNew(state, cb-&gt;fhead, &amp;cb-&gt;fhead)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 
+ 	    /* restore the cb-&gt;hhead entry */
+ 	    if (h_OldToNew(state, cb-&gt;hhead, &amp;cb-&gt;hhead)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 
+ 	    /* restore the cb-&gt;tprev entry */
+ 	    if (cb_OldToNew(state, cb-&gt;tprev, &amp;cb-&gt;tprev)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 
+ 	    /* restore the cb-&gt;tnext entry */
+ 	    if (cb_OldToNew(state, cb-&gt;tnext, &amp;cb-&gt;tnext)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 
+ 	    /* restore the cb-&gt;hprev entry */
+ 	    if (cb_OldToNew(state, cb-&gt;hprev, &amp;cb-&gt;hprev)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 
+ 	    /* restore the cb-&gt;hnext entry */
+ 	    if (cb_OldToNew(state, cb-&gt;hnext, &amp;cb-&gt;hnext)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 	}
+     }
+ 
+     /* restore the timeout queue head indices */
+     for (i = 0; i &lt; state-&gt;cb_timeout_hdr-&gt;records; i++) {
+ 	if (cb_OldToNew(state, timeout[i], &amp;timeout[i])) {
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     }
+ 
+     /* restore the FE hash table queue heads */
+     for (i = 0; i &lt; state-&gt;cb_fehash_hdr-&gt;records; i++) {
+ 	if (fe_OldToNew(state, HashTable[i], &amp;HashTable[i])) {
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ cb_stateVerify(struct fs_dump_state * state)
+ {
+     int ret = 0;
+ 
+     if (cb_stateVerifyFEHash(state)) {
+ 	ret = 1;
+     }
+ 
+     if (cb_stateVerifyTimeoutQueues(state)) {
+ 	ret = 1;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateVerifyFEHash(struct fs_dump_state * state)
+ {
+     int ret = 0, i;
+     struct FileEntry * fe;
+     afs_uint32 fei, chain_len;
+ 
+     for (i = 0; i &lt; FEHASH_SIZE; i++) {
+ 	chain_len = 0;
+ 	for (fei = HashTable[i], fe = itofe(fei);
+ 	     fe;
+ 	     fei = fe-&gt;fnext, fe = itofe(fei)) {
+ 	    if (fei &gt; cbstuff.nblks) {
+ 		ViceLog(0, ("cb_stateVerifyFEHash: error: index out of range (fei=%d)\n", fei));
+ 		ret = 1;
+ 		break;
+ 	    }
+ 	    if (cb_stateVerifyFE(state, fe)) {
+ 		ret = 1;
+ 	    }
+ 	    if (chain_len &gt; FS_STATE_FE_MAX_HASH_CHAIN_LEN) {
+ 		ViceLog(0, ("cb_stateVerifyFEHash: error: hash chain %d length exceeds %d; assuming there's a loop\n",
+ 			    i, FS_STATE_FE_MAX_HASH_CHAIN_LEN));
+ 		ret = 1;
+ 		break;
+ 	    }
+ 	    chain_len++;
+ 	}
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateVerifyFE(struct fs_dump_state * state, struct FileEntry * fe)
+ {
+     int ret = 0;
+ 
+     if ((fe-&gt;firstcb &amp;&amp; !fe-&gt;ncbs) ||
+ 	(!fe-&gt;firstcb &amp;&amp; fe-&gt;ncbs)) {
+ 	ViceLog(0, ("cb_stateVerifyFE: error: fe-&gt;firstcb does not agree with fe-&gt;ncbs (fei=%d, fe-&gt;firstcb=%d, fe-&gt;ncbs=%d)\n",
+ 		    fetoi(fe), fe-&gt;firstcb, fe-&gt;ncbs));
+ 	ret = 1;
+     }
+     if (cb_stateVerifyFCBList(state, fe)) {
+ 	ViceLog(0, ("cb_stateVerifyFE: error: FCBList failed verification (fei=%d)\n", fetoi(fe)));
+ 	ret = 1;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateVerifyFCBList(struct fs_dump_state * state, struct FileEntry * fe)
+ {
+     int ret = 0;
+     afs_uint32 cbi, fei, chain_len = 0;
+     struct CallBack * cb;
+ 
+     fei = fetoi(fe);
+ 
+     for (cbi = fe-&gt;firstcb, cb = itocb(cbi);
+ 	 cb;
+ 	 cbi = cb-&gt;cnext, cb = itocb(cbi)) {
+ 	if (cbi &gt; cbstuff.nblks) {
+ 	    ViceLog(0, ("cb_stateVerifyFCBList: error: list index out of range (cbi=%d, ncbs=%d)\n",
+ 			cbi, cbstuff.nblks));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	if (cb-&gt;fhead != fei) {
+ 	    ViceLog(0, ("cb_stateVerifyFCBList: error: cb-&gt;fhead != fei (fei=%d, cb-&gt;fhead=%d)\n",
+ 			fei, cb-&gt;fhead));
+ 	    ret = 1;
+ 	}
+ 	if (chain_len &gt; FS_STATE_FCB_MAX_LIST_LEN) {
+ 	    ViceLog(0, ("cb_stateVerifyFCBList: error: list length exceeds %d (fei=%d); assuming there's a loop\n",
+ 			FS_STATE_FCB_MAX_LIST_LEN, fei));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	chain_len++;
+     }
+ 
+     if (fe-&gt;ncbs != chain_len) {
+ 	ViceLog(0, ("cb_stateVerifyFCBList: error: list length mismatch (len=%d, fe-&gt;ncbs=%d)\n",
+ 		    chain_len, fe-&gt;ncbs));
+ 	ret = 1;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ cb_stateVerifyHCBList(struct fs_dump_state * state, struct host * host)
+ {
+     int ret = 0;
+     afs_uint32 hi, chain_len, cbi;
+     struct CallBack *cb, *ncb;
+ 
+     hi = h_htoi(host);
+     chain_len = 0;
+ 
+     for (cbi = host-&gt;cblist, cb = itocb(cbi);
+ 	 cb;
+ 	 cbi = cb-&gt;hnext, cb = ncb) {
+ 	if (chain_len &amp;&amp; (host-&gt;cblist == cbi)) {
+ 	    /* we've wrapped around the circular list, and everything looks ok */
+ 	    break;
+ 	}
+ 	if (cb-&gt;hhead != hi) {
+ 	    ViceLog(0, ("cb_stateVerifyHCBList: error: incorrect cb-&gt;hhead (cbi=%d, h-&gt;index=%d, cb-&gt;hhead=%d)\n",
+ 			cbi, hi, cb-&gt;hhead));
+ 	    ret = 1;
+ 	}
+ 	if (!cb-&gt;hprev || !cb-&gt;hnext) {
+ 	    ViceLog(0, ("cb_stateVerifyHCBList: error: null index in circular list (cbi=%d, h-&gt;index=%d)\n",
+ 			cbi, hi));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	if ((cb-&gt;hprev &gt; cbstuff.nblks) ||
+ 	    (cb-&gt;hnext &gt; cbstuff.nblks)) {
+ 	    ViceLog(0, ("cb_stateVerifyHCBList: error: list index out of range (cbi=%d, h-&gt;index=%d, cb-&gt;hprev=%d, cb-&gt;hnext=%d, nCBs=%d)\n",
+ 			cbi, hi, cb-&gt;hprev, cb-&gt;hnext, cbstuff.nblks));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	ncb = itocb(cb-&gt;hnext);
+ 	if (cbi != ncb-&gt;hprev) {
+ 	    ViceLog(0, ("cb_stateVerifyHCBList: error: corrupt linked list (cbi=%d, h-&gt;index=%d)\n",
+ 			cbi, hi));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	if (chain_len &gt; FS_STATE_HCB_MAX_LIST_LEN) {
+ 	    ViceLog(0, ("cb_stateVerifyFCBList: error: list length exceeds %d (h-&gt;index=%d); assuming there's a loop\n",
+ 			FS_STATE_HCB_MAX_LIST_LEN, hi));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	chain_len++;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateVerifyTimeoutQueues(struct fs_dump_state * state)
+ {
+     int ret = 0, i;
+     afs_uint32 cbi, chain_len;
+     struct CallBack *cb, *ncb;
+ 
+     for (i = 0; i &lt; CB_NUM_TIMEOUT_QUEUES; i++) {
+ 	chain_len = 0;
+ 	for (cbi = timeout[i], cb = itocb(cbi);
+ 	     cb;
+ 	     cbi = cb-&gt;tnext, cb = ncb) {
+ 	    if (chain_len &amp;&amp; (cbi == timeout[i])) {
+ 		/* we've wrapped around the circular list, and everything looks ok */
+ 		break;
+ 	    }
+ 	    if (cbi &gt; cbstuff.nblks) {
+ 		ViceLog(0, ("cb_stateVerifyTimeoutQueues: error: list index out of range (cbi=%d, tindex=%d)\n",
+ 			    cbi, i));
+ 		ret = 1;
+ 		break;
+ 	    }
+ 	    if (itot(cb-&gt;thead) != &amp;timeout[i]) {
+ 		ViceLog(0, ("cb_stateVerifyTimeoutQueues: error: cb-&gt;thead points to wrong timeout queue (tindex=%d, cbi=%d, cb-&gt;thead=%d)\n",
+ 			    i, cbi, cb-&gt;thead));
+ 		ret = 1;
+ 	    }
+ 	    if (!cb-&gt;tprev || !cb-&gt;tnext) {
+ 		ViceLog(0, ("cb_stateVerifyTimeoutQueues: null index in circular list (cbi=%d, tindex=%d)\n",
+ 			    cbi, i));
+ 		ret = 1;
+ 		break;
+ 	    }
+ 	    if ((cb-&gt;tprev &gt; cbstuff.nblks) ||
+ 		(cb-&gt;tnext &gt; cbstuff.nblks)) {
+ 		ViceLog(0, ("cb_stateVerifyTimeoutQueues: list index out of range (cbi=%d, tindex=%d, cb-&gt;tprev=%d, cb-&gt;tnext=%d, nCBs=%d)\n",
+ 			    cbi, i, cb-&gt;tprev, cb-&gt;tnext, cbstuff.nblks));
+ 		ret = 1;
+ 		break;
+ 	    }
+ 	    ncb = itocb(cb-&gt;tnext);
+ 	    if (cbi != ncb-&gt;tprev) {
+ 		ViceLog(0, ("cb_stateVerifyTimeoutQueues: corrupt linked list (cbi=%d, tindex=%d)\n",
+ 			    cbi, i));
+ 		ret = 1;
+ 		break;
+ 	    }
+ 	    if (chain_len &gt; FS_STATE_TCB_MAX_LIST_LEN) {
+ 		ViceLog(0, ("cb_stateVerifyTimeoutQueues: list length exceeds %d (tindex=%d); assuming there's a loop\n",
+ 			    FS_STATE_TCB_MAX_LIST_LEN, i));
+ 		ret = 1;
+ 		break;
+ 	    }
+ 	    chain_len++;
+ 	}
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateSaveTimeouts(struct fs_dump_state * state)
+ {
+     int ret = 0;
+     struct iovec iov[2];
+ 
+     AssignInt64(state-&gt;eof_offset, &amp;state-&gt;cb_hdr-&gt;timeout_offset);
+ 
+     memset(state-&gt;cb_timeout_hdr, 0, sizeof(struct callback_state_fehash_header));
+     state-&gt;cb_timeout_hdr-&gt;magic = CALLBACK_STATE_TIMEOUT_MAGIC;
+     state-&gt;cb_timeout_hdr-&gt;records = CB_NUM_TIMEOUT_QUEUES;
+     state-&gt;cb_timeout_hdr-&gt;len = sizeof(struct callback_state_timeout_header) +
+ 	(state-&gt;cb_timeout_hdr-&gt;records * sizeof(afs_uint32));
+ 
+     iov[0].iov_base = (char *)state-&gt;cb_timeout_hdr;
+     iov[0].iov_len = sizeof(struct callback_state_timeout_header);
+     iov[1].iov_base = (char *)timeout;
+     iov[1].iov_len = sizeof(timeout);
+ 
+     if (fs_stateSeek(state, &amp;state-&gt;cb_hdr-&gt;timeout_offset)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateWriteV(state, iov, 2)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     fs_stateIncEOF(state, state-&gt;cb_timeout_hdr-&gt;len);
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateRestoreTimeouts(struct fs_dump_state * state)
+ {
+     int ret = 0, len;
+ 
+     if (fs_stateReadHeader(state, &amp;state-&gt;cb_hdr-&gt;timeout_offset,
+ 			   state-&gt;cb_timeout_hdr, 
+ 			   sizeof(struct callback_state_timeout_header))) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (state-&gt;cb_timeout_hdr-&gt;magic != CALLBACK_STATE_TIMEOUT_MAGIC) {
+ 	ret = 1;
+ 	goto done;
+     }
+     if (state-&gt;cb_timeout_hdr-&gt;records != CB_NUM_TIMEOUT_QUEUES) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     len = state-&gt;cb_timeout_hdr-&gt;records * sizeof(afs_uint32);
+ 
+     if (state-&gt;cb_timeout_hdr-&gt;len !=
+ 	(sizeof(struct callback_state_timeout_header) + len)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateRead(state, timeout, len)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateSaveFEHash(struct fs_dump_state * state)
+ {
+     int ret = 0;
+     struct iovec iov[2];
+ 
+     AssignInt64(state-&gt;eof_offset, &amp;state-&gt;cb_hdr-&gt;fehash_offset);
+ 
+     memset(state-&gt;cb_fehash_hdr, 0, sizeof(struct callback_state_fehash_header));
+     state-&gt;cb_fehash_hdr-&gt;magic = CALLBACK_STATE_FEHASH_MAGIC;
+     state-&gt;cb_fehash_hdr-&gt;records = FEHASH_SIZE;
+     state-&gt;cb_fehash_hdr-&gt;len = sizeof(struct callback_state_fehash_header) +
+ 	(state-&gt;cb_fehash_hdr-&gt;records * sizeof(afs_uint32));
+ 
+     iov[0].iov_base = (char *)state-&gt;cb_fehash_hdr;
+     iov[0].iov_len = sizeof(struct callback_state_fehash_header);
+     iov[1].iov_base = (char *)HashTable;
+     iov[1].iov_len = sizeof(HashTable);
+ 
+     if (fs_stateSeek(state, &amp;state-&gt;cb_hdr-&gt;fehash_offset)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateWriteV(state, iov, 2)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     fs_stateIncEOF(state, state-&gt;cb_fehash_hdr-&gt;len);
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateRestoreFEHash(struct fs_dump_state * state)
+ {
+     int ret = 0, len;
+ 
+     if (fs_stateReadHeader(state, &amp;state-&gt;cb_hdr-&gt;fehash_offset,
+ 			   state-&gt;cb_fehash_hdr, 
+ 			   sizeof(struct callback_state_fehash_header))) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (state-&gt;cb_fehash_hdr-&gt;magic != CALLBACK_STATE_FEHASH_MAGIC) {
+ 	ret = 1;
+ 	goto done;
+     }
+     if (state-&gt;cb_fehash_hdr-&gt;records != FEHASH_SIZE) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     len = state-&gt;cb_fehash_hdr-&gt;records * sizeof(afs_uint32);
+ 
+     if (state-&gt;cb_fehash_hdr-&gt;len !=
+ 	(sizeof(struct callback_state_fehash_header) + len)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateRead(state, HashTable, len)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateSaveFEs(struct fs_dump_state * state)
+ {
+     int ret = 0;
+     register int fei, hash;
+     register struct FileEntry *fe;
+ 
+     AssignInt64(state-&gt;eof_offset, &amp;state-&gt;cb_hdr-&gt;fe_offset);
+ 
+     for (hash = 0; hash &lt; FEHASH_SIZE ; hash++) {
+ 	for (fei = HashTable[hash]; fei; fei = fe-&gt;fnext) {
+ 	    fe = itofe(fei);
+ 	    if (cb_stateSaveFE(state, fe)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 	}
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateRestoreFEs(struct fs_dump_state * state)
+ {
+     int count, nFEs, ret = 0;
+ 
+     nFEs = state-&gt;cb_hdr-&gt;nFEs;
+ 
+     for (count = 0; count &lt; nFEs; count++) {
+ 	if (cb_stateRestoreFE(state)) {
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateSaveFE(struct fs_dump_state * state, struct FileEntry * fe)
+ {
+     int ret = 0, iovcnt, cbi, idx, len, written = 0;
+     afs_uint32 fei;
+     struct callback_state_entry_header hdr;
+     struct FEDiskEntry fedsk;
+     struct CBDiskEntry cbdsk[16];
+     struct iovec iov[16];
+     struct CallBack *cb;
+ 
+     fei = fetoi(fe);
+     if (fei &gt; state-&gt;cb_hdr-&gt;fe_max) {
+ 	state-&gt;cb_hdr-&gt;fe_max = fei;
+     }
+ 
+     memset(&amp;hdr, 0, sizeof(struct callback_state_entry_header));
+ 
+     if (cb_stateFEToDiskEntry(fe, &amp;fedsk)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     iov[0].iov_base = (char *)&amp;hdr;
+     len = iov[0].iov_len = sizeof(hdr);
+     iov[1].iov_base = (char *)&amp;fedsk;
+     len += iov[1].iov_len = sizeof(struct FEDiskEntry);
+     iovcnt = 2;
+ 
+     for (cbi = fe-&gt;firstcb, cb = itocb(cbi), idx = 2; 
+ 	 cb != NULL; 
+ 	 cbi = cb-&gt;cnext, cb = itocb(cbi), idx++, hdr.nCBs++) {
+ 	if (cbi &gt; state-&gt;cb_hdr-&gt;cb_max) {
+ 	    state-&gt;cb_hdr-&gt;cb_max = cbi;
+ 	}
+ 	if (cb_stateCBToDiskEntry(cb, &amp;cbdsk[idx])) {
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	cbdsk[idx].index = cbi;
+ 	iov[idx].iov_base = (char *)&amp;cbdsk[idx];
+ 	len += iov[idx].iov_len = sizeof(struct CBDiskEntry);
+ 	iovcnt++;
+ 	if ((iovcnt == 16) || (!cb-&gt;cnext)) {
+ 	    if (fs_stateWriteV(state, iov, iovcnt)) {
+ 		ret = 1;
+ 		goto done;
+ 	    }
+ 	    written = 1;
+ 	    iovcnt = 0;
+ 	    len = 0;
+ 	}
+     }
+ 
+     hdr.magic = CALLBACK_STATE_ENTRY_MAGIC;
+     hdr.len = sizeof(hdr) + sizeof(struct FEDiskEntry) + 
+ 	(hdr.nCBs * sizeof(struct CBDiskEntry));
+ 
+     if (!written) {
+ 	if (fs_stateWriteV(state, iov, iovcnt)) {
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     } else {
+ 	if (fs_stateWriteHeader(state, &amp;state-&gt;eof_offset, &amp;hdr, sizeof(hdr))) {
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     }
+ 
+     fs_stateIncEOF(state, hdr.len);
+ 
+     if (written) {
+ 	if (fs_stateSeek(state, &amp;state-&gt;eof_offset)) {
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     }
+ 
+     state-&gt;cb_hdr-&gt;nFEs++;
+     state-&gt;cb_hdr-&gt;nCBs += hdr.nCBs;
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateRestoreFE(struct fs_dump_state * state)
+ {
+     int ret = 0, iovcnt, len, nCBs, idx;
+     struct callback_state_entry_header hdr;
+     struct FEDiskEntry fedsk;
+     struct CBDiskEntry cbdsk[16];
+     struct iovec iov[16];
+     struct FileEntry * fe;
+     struct CallBack * cb;
+ 
+     iov[0].iov_base = (char *)&amp;hdr;
+     len = iov[0].iov_len = sizeof(hdr);
+     iov[1].iov_base = (char *)&amp;fedsk;
+     len += iov[1].iov_len = sizeof(fedsk);
+     iovcnt = 2;
+ 
+     if (fs_stateReadV(state, iov, iovcnt)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (hdr.magic != CALLBACK_STATE_ENTRY_MAGIC) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     fe = GetFE();
+     if (fe == NULL) {
+ 	ViceLog(0, ("cb_stateRestoreFE: ran out of free FileEntry structures\n"));
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (cb_stateDiskEntryToFE(state, &amp;fedsk, fe)) {
+ 	ret = 1;
+ 	goto done;
+     }
+ 
+     if (hdr.nCBs) {
+ 	for (iovcnt = 0, idx = 0, len = 0, nCBs = 0;
+ 	     nCBs &lt; hdr.nCBs;
+ 	     idx++, nCBs++) {
+ 	    iov[idx].iov_base = (char *)&amp;cbdsk[idx];
+ 	    len += iov[idx].iov_len = sizeof(struct CBDiskEntry);
+ 	    iovcnt++;
+ 	    if ((iovcnt == 16) || (nCBs == hdr.nCBs - 1)) {
+ 		if (fs_stateReadV(state, iov, iovcnt)) {
+ 		    ret = 1;
+ 		    goto done;
+ 		}
+ 		if (cb_stateRestoreCBs(state, fe, iov, iovcnt)) {
+ 		    ret = 1;
+ 		    goto done;
+ 		}
+ 		len = 0;
+ 		iovcnt = 0;
+ 	    }
+ 	}
+     }
+     
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateRestoreCBs(struct fs_dump_state * state, struct FileEntry * fe, 
+ 		   struct iovec * iov, int niovecs)
+ {
+     int ret = 0, idx;
+     register struct CallBack * cb;
+     struct CBDiskEntry * cbdsk;
+     afs_uint32 fei;
+ 
+     fei = fetoi(fe);
+ 
+     for (idx = 0; idx &lt; niovecs; idx++) {
+ 	cbdsk = (struct CBDiskEntry *) iov[idx].iov_base;
+ 	if ((cb = GetCB()) == NULL) {
+ 	    ViceLog(0, ("cb_stateRestoreCBs: ran out of free CallBack structures\n"));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	if (cb_stateDiskEntryToCB(state, cbdsk, cb)) {
+ 	    ViceLog(0, ("cb_stateRestoreCBs: corrupt CallBack disk entry\n"));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ 
+ static int
+ cb_stateFillHeader(struct callback_state_header * hdr)
+ {
+     hdr-&gt;stamp.magic = CALLBACK_STATE_MAGIC;
+     hdr-&gt;stamp.version = CALLBACK_STATE_VERSION;
+     hdr-&gt;tfirst = tfirst;
+     return 0;
+ }
+ 
+ static int
+ cb_stateCheckHeader(struct callback_state_header * hdr)
+ {
+     int ret = 0;
+ 
+     if (hdr-&gt;stamp.magic != CALLBACK_STATE_MAGIC) {
+ 	ret = 1;
+     } else if (hdr-&gt;stamp.version != CALLBACK_STATE_VERSION) {
+ 	ret = 1;
+     } else if ((hdr-&gt;nFEs &gt; cbstuff.nblks) || (hdr-&gt;nCBs &gt; cbstuff.nblks)) {
+ 	ViceLog(0, ("cb_stateCheckHeader: saved callback state larger than callback memory allocation\n"));
+ 	ret = 1;
+     }
+     return ret;
+ }
+ 
+ /* disk entry conversion routines */
+ static int
+ cb_stateFEToDiskEntry(struct FileEntry * in, struct FEDiskEntry * out)
+ {
+     memcpy(&amp;out-&gt;fe, in, sizeof(struct FileEntry));
+     out-&gt;index = fetoi(in);
+     return 0;
+ }
+ 
+ static int
+ cb_stateDiskEntryToFE(struct fs_dump_state * state, 
+ 		      struct FEDiskEntry * in, struct FileEntry * out)
+ {
+     int ret = 0;
+ 
+     memcpy(out, &amp;in-&gt;fe, sizeof(struct FileEntry));
+ 
+     /* setup FE map entry */
+     if (!in-&gt;index || (in-&gt;index &gt;= state-&gt;fe_map.len)) {
+ 	ViceLog(0, ("cb_stateDiskEntryToFE: index (%d) out of range",
+ 		    in-&gt;index));
+ 	ret = 1;
+ 	goto done;
+     }
+     state-&gt;fe_map.entries[in-&gt;index].old_idx = in-&gt;index;
+     state-&gt;fe_map.entries[in-&gt;index].new_idx = fetoi(out);
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ cb_stateCBToDiskEntry(struct CallBack * in, struct CBDiskEntry * out)
+ {
+     memcpy(&amp;out-&gt;cb, in, sizeof(struct CallBack));
+     out-&gt;index = cbtoi(in);
+     return 0;
+ }
+ 
+ static int
+ cb_stateDiskEntryToCB(struct fs_dump_state * state,
+ 		      struct CBDiskEntry * in, struct CallBack * out)
+ {
+     int ret = 0;
+ 
+     memcpy(out, &amp;in-&gt;cb, sizeof(struct CallBack));
+ 
+     /* setup CB map entry */
+     if (!in-&gt;index || (in-&gt;index &gt;= state-&gt;cb_map.len)) {
+ 	ViceLog(0, ("cb_stateDiskEntryToCB: index (%d) out of range\n",
+ 		    in-&gt;index));
+ 	ret = 1;
+ 	goto done;
+     }
+     state-&gt;cb_map.entries[in-&gt;index].old_idx = in-&gt;index;
+     state-&gt;cb_map.entries[in-&gt;index].new_idx = cbtoi(out);
+ 
+  done:
+     return ret;
+ }
+ 
+ /* index map routines */
+ static int
+ cb_stateAllocMap(struct fs_dump_state * state)
+ {
+     state-&gt;fe_map.len = state-&gt;cb_hdr-&gt;fe_max + 1;
+     state-&gt;cb_map.len = state-&gt;cb_hdr-&gt;cb_max + 1;
+     state-&gt;fe_map.entries = (struct idx_map_entry_t *)
+ 	calloc(state-&gt;fe_map.len, sizeof(struct idx_map_entry_t));
+     state-&gt;cb_map.entries = (struct idx_map_entry_t *)
+ 	calloc(state-&gt;cb_map.len, sizeof(struct idx_map_entry_t));
+     return ((state-&gt;fe_map.entries != NULL) &amp;&amp; (state-&gt;cb_map.entries != NULL)) ? 0 : 1;
+ }
+ 
+ int
+ fe_OldToNew(struct fs_dump_state * state, afs_uint32 old, afs_uint32 * new)
+ {
+     int ret = 0;
+ 
+     /* FEs use a one-based indexing system, so old==0 implies no mapping */
+     if (!old) {
+ 	*new = 0;
+ 	goto done;
+     }
+ 
+     if (old &gt;= state-&gt;fe_map.len) {
+ 	ViceLog(0, ("fe_OldToNew: index %d is out of range\n", old));
+ 	ret = 1;
+     } else if (state-&gt;fe_map.entries[old].old_idx != old) { /* sanity check */
+ 	ViceLog(0, ("fe_OldToNew: index %d points to an invalid FileEntry record\n", old));
+ 	ret = 1;
+     } else {
+ 	*new = state-&gt;fe_map.entries[old].new_idx;
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ int
+ cb_OldToNew(struct fs_dump_state * state, afs_uint32 old, afs_uint32 * new)
+ {
+     int ret = 0;
+ 
+     /* CBs use a one-based indexing system, so old==0 implies no mapping */
+     if (!old) {
+ 	*new = 0;
+ 	goto done;
+     }
+ 
+     if (old &gt;= state-&gt;cb_map.len) {
+ 	ViceLog(0, ("cb_OldToNew: index %d is out of range\n", old));
+ 	ret = 1;
+     } else if (state-&gt;cb_map.entries[old].old_idx != old) { /* sanity check */
+ 	ViceLog(0, ("cb_OldToNew: index %d points to an invalid CallBack record\n", old));
+ 	ret = 1;
+     } else {
+ 	*new = state-&gt;cb_map.entries[old].new_idx;
+     }
+ 
+  done:
+     return ret;
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  int
  DumpCallBackState(void)
  {
***************
*** 1826,1832 ****
      return 0;
  }
  
! #endif
  
  #ifdef INTERPRET_DUMP
  
--- 2673,2679 ----
      return 0;
  }
  
! #endif /* !INTERPRET_DUMP */
  
  #ifdef INTERPRET_DUMP
  
***************
*** 1945,1956 ****
  	PrintCallBackStats();
      }
      if (all || vol) {
! 	register hash;
! 	register afs_uint32 *feip;
! 	register struct CallBack *cb;
! 	register struct FileEntry *fe;
  
! 	for (hash = 0; hash &lt; VHASH; hash++) {
  	    for (feip = &amp;HashTable[hash]; fe = itofe(*feip);) {
  		if (!vol || (fe-&gt;volid == vol)) {
  		    register struct CallBack *cbnext;
--- 2792,2803 ----
  	PrintCallBackStats();
      }
      if (all || vol) {
! 	int hash;
! 	afs_uint32 *feip;
! 	struct CallBack *cb;
! 	struct FileEntry *fe;
  
! 	for (hash = 0; hash &lt; FEHASH_SIZE; hash++) {
  	    for (feip = &amp;HashTable[hash]; fe = itofe(*feip);) {
  		if (!vol || (fe-&gt;volid == vol)) {
  		    register struct CallBack *cbnext;
***************
*** 1986,2001 ****
  	}
      }
      if (raw) {
- 	struct FileEntry *fe;
  	afs_int32 *p, i;
  	for (i = 1; i &lt; cbstuff.nblks; i++) {
  	    p = (afs_int32 *) &amp; FE[i];
  	    printf("%d:%12x%12x%12x%12x\n", i, p[0], p[1], p[2], p[3]);
  	}
      }
  }
  
! int
  PrintCB(register struct CallBack *cb, afs_uint32 now)
  {
      struct FileEntry *fe = itofe(cb-&gt;fhead);
--- 2833,2848 ----
  	}
      }
      if (raw) {
  	afs_int32 *p, i;
  	for (i = 1; i &lt; cbstuff.nblks; i++) {
  	    p = (afs_int32 *) &amp; FE[i];
  	    printf("%d:%12x%12x%12x%12x\n", i, p[0], p[1], p[2], p[3]);
  	}
      }
+     exit(0);
  }
  
! void
  PrintCB(register struct CallBack *cb, afs_uint32 now)
  {
      struct FileEntry *fe = itofe(cb-&gt;fhead);
***************
*** 2220,2225 ****
--- 3067,3081 ----
                  H_UNLOCK;
              }
          }
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	/* try to bail ASAP if the fileserver is shutting down */
+ 	FS_STATE_RDLOCK;
+ 	if (fs_state.mode == FS_MODE_SHUTDOWN) {
+ 	    FS_STATE_UNLOCK;
+ 	    multi_Abort;
+ 	}
+ 	FS_STATE_UNLOCK;
+ #endif
      }
      multi_End_Ignore;
      H_LOCK;
Index: openafs/src/viced/callback.h
diff -c /dev/null openafs/src/viced/callback.h:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/viced/callback.h	Fri Mar 17 23:20:17 2006
***************
*** 0 ****
--- 1,158 ----
+ /*
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
+  */
+ 
+ #ifndef _AFS_VICED_CALLBACK_H
+ #define _AFS_VICED_CALLBACK_H
+ 
+ /* Maximum number of call backs to break at once, single fid
+  * There is some debate as to just how large this value should be
+  * Ideally, it would be very very large, but I am afraid that the
+  * cache managers will all send in their responses simultaneously,
+  * thereby swamping the file server.  As a result, something like
+  * 10 or 15 might be a better bet.
+  */
+ #define MAX_CB_HOSTS	10
+ 
+ /* max time to break a callback, otherwise client is dead or net is hosed */
+ #define MAXCBT 25
+ 
+ #define u_byte	unsigned char
+ 
+ struct cbcounters {
+     afs_int32 DeleteFiles;
+     afs_int32 DeleteCallBacks;
+     afs_int32 BreakCallBacks;
+     afs_int32 AddCallBacks;
+     afs_int32 GotSomeSpaces;
+     afs_int32 DeleteAllCallBacks;
+     afs_int32 nFEs, nCBs, nblks;
+     afs_int32 CBsTimedOut;
+     afs_int32 nbreakers;
+     afs_int32 GSS1, GSS2, GSS3, GSS4, GSS5;
+ };
+ extern struct cbcounters cbstuff;
+ 
+ struct cbstruct {
+     struct host *hp;
+     afs_uint32 thead;
+ };
+ 
+ /* structure MUST be multiple of 8 bytes, otherwise the casts to
+  * struct object will have alignment issues on *P64 userspaces */
+ struct FileEntry {
+     afs_uint32 vnode;
+     afs_uint32 unique;
+     afs_uint32 volid;
+     afs_uint32 fnext;           /* index of next FE in hash chain */
+     afs_uint32 ncbs;            /* number of callbacks for this FE */
+     afs_uint32 firstcb;         /* index of first cb in per-FE list */
+     afs_uint32 status;          /* status bits for this FE */
+     afs_uint32 spare;
+ };
+ #define FE_LATER 0x1
+ 
+ /* structure MUST be multiple of 8 bytes, otherwise the casts to
+  * struct object will have alignment issues on *P64 userspaces */
+ struct CallBack {
+     afs_uint32 cnext;		/* index of next cb in per-FE list */
+     afs_uint32 fhead;		/* index of associated FE */
+     u_byte thead;		/* Head of timeout chain */
+     u_byte status;		/* Call back status; see definitions, below */
+     unsigned short spare;	/* ensure proper alignment */
+     afs_uint32 hhead;		/* Head of host table chain */
+     afs_uint32 tprev, tnext;	/* per-timeout circular list of callbacks */
+     afs_uint32 hprev, hnext;	/* per-host circular list of callbacks */
+ };
+ 
+ struct VCBParams {
+     struct cbstruct cba[MAX_CB_HOSTS];	/* re-entrant storage */
+     unsigned int ncbas;
+     afs_uint32 thead;		/* head of timeout queue for youngest callback */
+     struct AFSFid *fid;
+ };
+ 
+ 
+ /* callback hash macros */
+ #define FEHASH_SIZE 512		/* Power of 2 */
+ #define FEHASH_MASK (FEHASH_SIZE-1)
+ #define FEHash(volume, unique) (((volume)+(unique))&amp;(FEHASH_MASK))
+ 
+ #define CB_NUM_TIMEOUT_QUEUES 128
+ 
+ 
+ /* status values for status field of CallBack structure */
+ #define CB_NORMAL   1		/* Normal call back */
+ #define CB_DELAYED  2		/* Delayed call back due to rpc problems.
+ 				 * The call back entry will be added back to the
+ 				 * host list at the END of the list, so that
+ 				 * searching backwards in the list will find all
+ 				 * the (consecutive)host. delayed call back entries */
+ #define CB_VOLUME   3		/* Callback for a volume */
+ #define CB_BULK     4		/* Normal callbacks, handed out from FetchBulkStatus */
+ 
+ /* call back indices to pointers, and vice-versa */
+ #define itocb(i)    ((i)?CB+(i):0)
+ #define cbtoi(cbp)  (!(cbp)?0:(cbp)-CB)
+ 
+ /* file entry indices to pointers, and vice-versa */
+ #define itofe(i)    ((i)?FE+(i):0)
+ #define fetoi(fep)  (!(fep)?0:(fep)-FE)
+ 
+ /* Timeouts:  there are 128 possible timeout values in effect at any
+  * given time.  Each timeout represents timeouts in an interval of 128
+  * seconds.  So the maximum timeout for a call back is 128*128=16384
+  * seconds, or 4 1/2 hours.  The timeout cleanup stuff is called only
+  * if space runs out or by the file server every 5 minutes.  This 5
+  * minute slack should be allowed for--so a maximum time of 4 hours
+  * is safer.
+  *
+  * Timeouts must be chosen to correspond to an exact multiple
+  * of 128, because all times are truncated to a 128 multiple, and
+  * timed out if the current truncated time is &lt;= to the truncated time
+  * corresponding to the timeout queue.
+  */
+ 
+ /* Unix time to Call Back time, and vice-versa.  Call back time is
+    in units of 128 seconds, corresponding to time queues. */
+ #define CBtime(uxtime)	((uxtime)&gt;&gt;7)
+ #define UXtime(cbtime)	((cbtime)&lt;&lt;7)
+ 
+ /* Given a Unix time, compute the closest Unix time that corresponds to
+    a time queue, rounding up */
+ #define TimeCeiling(uxtime)	(((uxtime)+127)&amp;~127)
+ 
+ #define TimeOutCutoff   ((sizeof(TimeOuts)/sizeof(TimeOuts[0]))*8)
+ #define TimeOut(nusers)  ((nusers)&gt;=TimeOutCutoff? MinTimeOut: TimeOuts[(nusers)&gt;&gt;3])
+ 
+ /* time out at server is 3 minutes more than ws */
+ #define ServerBias	  (3*60)
+ 
+ /* Convert cbtime to timeout queue index */
+ #define TIndex(cbtime)  (((cbtime)&amp;127)+1)
+ 
+ /* Convert cbtime to pointer to timeout queue head */
+ #define THead(cbtime)	(&amp;timeout[TIndex(cbtime)-1])
+ 
+ /* Normalize index into timeout array so that two such indices will be
+    ordered correctly, so that they can be compared to see which times
+    sooner, or so that the difference in time out times between them
+    can be computed. */
+ #define TNorm(index)   ((index)&lt;TIndex(tfirst)?(index)+128:(index))
+ 
+ /* This converts a timeout index into the actual time it will expire */
+ #define TIndexToTime(index) (UXtime(TNorm(index) - TIndex(tfirst) + tfirst))
+ 
+ 
+ /* Convert pointer to timeout queue head to index, and vice versa */
+ #define ttoi(t)		((t-timeout)+1)
+ #define itot(i)		((timeout)+(i-1))
+ 
+ #endif /* _AFS_VICED_CALLBACK_H */
Index: openafs/src/viced/fs_stats.h
diff -c openafs/src/viced/fs_stats.h:1.5 openafs/src/viced/fs_stats.h:1.6
*** openafs/src/viced/fs_stats.h:1.5	Wed Feb  1 10:58:31 2006
--- openafs/src/viced/fs_stats.h	Fri Apr  7 01:34:26 2006
***************
*** 126,135 ****
      afs_int32 rx_nBusies;	/*Ttl VBUSYs sent to shed load */
      afs_int32 fs_nBusies;	/*Ttl VBUSYs sent during restart/vol clone */
  
      /*
       * Spares
       */
!     afs_int32 spare[29];
  };
  
  #if FS_STATS_DETAILED
--- 126,139 ----
      afs_int32 rx_nBusies;	/*Ttl VBUSYs sent to shed load */
      afs_int32 fs_nBusies;	/*Ttl VBUSYs sent during restart/vol clone */
  
+     /* 
+      * Can't count this as an RPC because it breaks the data structure
+      */
+     afs_int32 fs_nGetCaps;	/* Number of GetCapabilities calls */
      /*
       * Spares
       */
!     afs_int32 spare[28];
  };
  
  #if FS_STATS_DETAILED
***************
*** 164,172 ****
  #define FS_STATS_RPCIDX_BULKSTATUS	25
  #define FS_STATS_RPCIDX_XSTATSVERSION	26
  #define FS_STATS_RPCIDX_GETXSTATS	27
- #define FS_STATS_RPCIDX_GETCAPABILITIES 28
  
! #define FS_STATS_NUM_RPC_OPS		29
  
  /*
   * Assign an index to each of the File Server's RPC interface routines
--- 168,175 ----
  #define FS_STATS_RPCIDX_BULKSTATUS	25
  #define FS_STATS_RPCIDX_XSTATSVERSION	26
  #define FS_STATS_RPCIDX_GETXSTATS	27
  
! #define FS_STATS_NUM_RPC_OPS		28
  
  /*
   * Assign an index to each of the File Server's RPC interface routines
Index: openafs/src/viced/fsprobe.c
diff -c openafs/src/viced/fsprobe.c:1.11 openafs/src/viced/fsprobe.c:1.12
*** openafs/src/viced/fsprobe.c:1.11	Tue Jul 15 19:17:30 2003
--- openafs/src/viced/fsprobe.c	Wed Feb 22 15:29:01 2006
***************
*** 11,24 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/fsprobe.c,v 1.11 2003/07/15 23:17:30 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;afs/afsint.h&gt;
- #include &lt;rx/rx_globals.h&gt;
- #include &lt;netdb.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;ubik.h&gt;
  
  #ifdef HAVE_STRING_H
--- 11,25 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/fsprobe.c,v 1.12 2006/02/22 20:29:01 rees Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;afs/afsint.h&gt;
  #include &lt;sys/socket.h&gt;
+ #include &lt;rx/rx_globals.h&gt;
  #include &lt;netinet/in.h&gt;
+ #include &lt;arpa/inet.h&gt;
+ #include &lt;netdb.h&gt;
  #include &lt;ubik.h&gt;
  
  #ifdef HAVE_STRING_H
***************
*** 133,146 ****
  	    exit(1);
  	}
      }
!     if (code = pxclient_Initialize(noAuth, host.sin_addr.s_addr)) {
  	printf("Couldn't initialize fs library (code=%d).\n", code);
  	exit(1);
      }
  
      code = ubik_Call(RXAFS_GetTime, cstruct, 0, &amp;tv.tv_sec, &amp;tv.tv_usec);
      if (!code)
! 	printf("AFS_GetTime on %s sec=%d, usec=%d\n", av[0], tv.tv_sec,
  	       tv.tv_usec);
      else
  	printf("return code is %d\n", code);
--- 134,147 ----
  	    exit(1);
  	}
      }
!     if ((code = pxclient_Initialize(noAuth, host.sin_addr.s_addr)) != 0) {
  	printf("Couldn't initialize fs library (code=%d).\n", code);
  	exit(1);
      }
  
      code = ubik_Call(RXAFS_GetTime, cstruct, 0, &amp;tv.tv_sec, &amp;tv.tv_usec);
      if (!code)
! 	printf("AFS_GetTime on %s sec=%ld, usec=%ld\n", av[0], tv.tv_sec,
  	       tv.tv_usec);
      else
  	printf("return code is %d\n", code);
Index: openafs/src/viced/host.c
diff -c openafs/src/viced/host.c:1.76 openafs/src/viced/host.c:1.93
*** openafs/src/viced/host.c:1.76	Mon Feb 13 12:09:36 2006
--- openafs/src/viced/host.c	Tue Apr  4 16:51:19 2006
***************
*** 5,17 ****
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
   */
  
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/host.c,v 1.76 2006/02/13 17:09:36 jaltman Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;errno.h&gt;
--- 5,19 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/host.c,v 1.93 2006/04/04 20:51:19 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;errno.h&gt;
***************
*** 49,54 ****
--- 51,57 ----
  #endif
  #include &lt;afs/acl.h&gt;
  #include &lt;afs/ptclient.h&gt;
+ #include &lt;afs/ptuser.h&gt;
  #include &lt;afs/prs_fs.h&gt;
  #include &lt;afs/auth.h&gt;
  #include &lt;afs/afsutil.h&gt;
***************
*** 58,64 ****
  #include "viced_prototypes.h"
  #include "viced.h"
  #include "host.h"
! 
  
  #ifdef AFS_PTHREAD_ENV
  pthread_mutex_t host_glock_mutex;
--- 61,71 ----
  #include "viced_prototypes.h"
  #include "viced.h"
  #include "host.h"
! #include "callback.h"
! #ifdef AFS_DEMAND_ATTACH_FS
! #include "../util/afsutil_prototypes.h"
! #include "../tviced/serialize_state.h"
! #endif /* AFS_DEMAND_ATTACH_FS */
  
  #ifdef AFS_PTHREAD_ENV
  pthread_mutex_t host_glock_mutex;
***************
*** 82,87 ****
--- 89,101 ----
  int rxcon_ident_key;
  int rxcon_client_key;
  
+ static struct rx_securityClass *sc = NULL;
+ 
+ static void h_SetupCallbackConn_r(struct host * host);
+ static void h_AddHostToHashTable_r(afs_uint32 addr, afs_uint16 port, struct host * host);
+ static void h_AddHostToUuidHashTable_r(afsUUID * uuid, struct host * host);
+ static int h_DeleteHostFromHashTableByAddr_r(afs_uint32 addr, afs_uint16 port, struct host *host);
+ 
  #define CESPERBLOCK 73
  struct CEBlock {		/* block of CESPERBLOCK file entries */
      struct client entry[CESPERBLOCK];
***************
*** 198,203 ****
--- 212,222 ----
      register int i;
      static int index = 0;
  
+     if (HTBlocks == h_MAXHOSTTABLES) {
+ 	ViceLog(0, ("h_MAXHOSTTABLES reached\n"));
+ 	ShutDownAndCore(PANIC);
+     }
+ 
      block = (struct HTBlock *)malloc(sizeof(struct HTBlock));
      if (!block) {
  	ViceLog(0, ("Failed malloc in GetHTBlock\n"));
***************
*** 226,234 ****
  {
      register struct host *entry;
  
!     if (HTFree == 0)
  	GetHTBlock();
!     assert(HTFree != 0);
      entry = HTFree;
      HTFree = entry-&gt;next;
      HTs++;
--- 245,253 ----
  {
      register struct host *entry;
  
!     if (HTFree == NULL)
  	GetHTBlock();
!     assert(HTFree != NULL);
      entry = HTFree;
      HTFree = entry-&gt;next;
      HTs++;
***************
*** 442,451 ****
  	free(host-&gt;hcps.prlist_val);	/* this is for hostaclRefresh */
      host-&gt;hcps.prlist_val = NULL;
      host-&gt;hcps.prlist_len = 0;
!     slept ? (host-&gt;cpsCall = FT_ApproxTime()) : (host-&gt;cpsCall = now);
  
      H_UNLOCK;
!     code = pr_GetHostCPS(htonl(host-&gt;host), &amp;host-&gt;hcps);
      H_LOCK;
      if (code) {
  	/*
--- 461,470 ----
  	free(host-&gt;hcps.prlist_val);	/* this is for hostaclRefresh */
      host-&gt;hcps.prlist_val = NULL;
      host-&gt;hcps.prlist_len = 0;
!     host-&gt;cpsCall = slept ? (FT_ApproxTime()) : (now);
  
      H_UNLOCK;
!     code = pr_GetHostCPS(ntohl(host-&gt;host), &amp;host-&gt;hcps);
      H_LOCK;
      if (code) {
  	/*
***************
*** 499,505 ****
  
  /* args in net byte order */
  void
! h_flushhostcps(register afs_uint32 hostaddr, register afs_uint32 hport)
  {
      register struct host *host;
      int held = 0;
--- 518,524 ----
  
  /* args in net byte order */
  void
! h_flushhostcps(register afs_uint32 hostaddr, register afs_uint16 hport)
  {
      register struct host *host;
      int held = 0;
***************
*** 526,554 ****
  h_Alloc_r(register struct rx_connection *r_con)
  {
      struct servent *serverentry;
!     register index = h_HashIndex(rxr_HostOf(r_con));
!     register struct host *host;
!     static struct rx_securityClass *sc = 0;
      afs_int32 now;
-     struct h_hashChain *h_hashChain;
  #if FS_STATS_DETAILED
      afs_uint32 newHostAddr_HBO;	/*New host IP addr, in host byte order */
  #endif /* FS_STATS_DETAILED */
  
      host = GetHT();
  
-     h_hashChain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
-     if (!h_hashChain) {
- 	ViceLog(0, ("Failed malloc in h_Alloc_r\n"));
- 	assert(0);
-     }
-     h_hashChain-&gt;hostPtr = host;
-     h_hashChain-&gt;addr = rxr_HostOf(r_con);
-     h_hashChain-&gt;next = hostHashTable[index];
-     hostHashTable[index] = h_hashChain;
- 
      host-&gt;host = rxr_HostOf(r_con);
      host-&gt;port = rxr_PortOf(r_con);
      if (consolePort == 0) {	/* find the portal number for console */
  #if	defined(AFS_OSF_ENV)
  	serverentry = getservbyname("ropcons", "");
--- 545,563 ----
  h_Alloc_r(register struct rx_connection *r_con)
  {
      struct servent *serverentry;
!     struct host *host;
      afs_int32 now;
  #if FS_STATS_DETAILED
      afs_uint32 newHostAddr_HBO;	/*New host IP addr, in host byte order */
  #endif /* FS_STATS_DETAILED */
  
      host = GetHT();
  
      host-&gt;host = rxr_HostOf(r_con);
      host-&gt;port = rxr_PortOf(r_con);
+ 
+     h_AddHostToHashTable_r(host-&gt;host, host-&gt;port, host);
+ 
      if (consolePort == 0) {	/* find the portal number for console */
  #if	defined(AFS_OSF_ENV)
  	serverentry = getservbyname("ropcons", "");
***************
*** 564,587 ****
  	host-&gt;Console = 1;
      /* Make a callback channel even for the console, on the off chance that it
       * makes a request that causes a break call back.  It shouldn't. */
!     {
! 	if (!sc)
! 	    sc = rxnull_NewClientSecurityObject();
! 	host-&gt;callback_rxcon =
! 	    rx_NewConnection(host-&gt;host, host-&gt;port, 1, sc, 0);
! 	rx_SetConnDeadTime(host-&gt;callback_rxcon, 50);
! 	rx_SetConnHardDeadTime(host-&gt;callback_rxcon, AFS_HARDDEADTIME);
!     }
      now = host-&gt;LastCall = host-&gt;cpsCall = host-&gt;ActiveCall = FT_ApproxTime();
      host-&gt;hostFlags = 0;
      host-&gt;hcps.prlist_val = NULL;
      host-&gt;hcps.prlist_len = 0;
!     host-&gt;interface = 0;
  #ifdef undef
      host-&gt;hcpsfailed = 0;	/* save cycles */
      h_gethostcps(host);		/* do this under host hold/lock */
  #endif
!     host-&gt;FirstClient = 0;
      h_Hold_r(host);
      h_Lock_r(host);
      h_InsertList_r(host);	/* update global host List */
--- 573,589 ----
  	host-&gt;Console = 1;
      /* Make a callback channel even for the console, on the off chance that it
       * makes a request that causes a break call back.  It shouldn't. */
!     h_SetupCallbackConn_r(host);
      now = host-&gt;LastCall = host-&gt;cpsCall = host-&gt;ActiveCall = FT_ApproxTime();
      host-&gt;hostFlags = 0;
      host-&gt;hcps.prlist_val = NULL;
      host-&gt;hcps.prlist_len = 0;
!     host-&gt;interface = NULL;
  #ifdef undef
      host-&gt;hcpsfailed = 0;	/* save cycles */
      h_gethostcps(host);		/* do this under host hold/lock */
  #endif
!     host-&gt;FirstClient = NULL;
      h_Hold_r(host);
      h_Lock_r(host);
      h_InsertList_r(host);	/* update global host List */
***************
*** 599,615 ****
  }				/*h_Alloc_r */
  
  
  /* Lookup a host given an IP address and UDP port number. */
  /* hostaddr and hport are in network order */
  /* Note: host should be released by caller if 0 == *heldp and non-null */
  /* hostaddr and hport are in network order */
  struct host *
! h_Lookup_r(afs_uint32 haddr, afs_uint32 hport, int *heldp)
  {
!     register afs_int32 now;
!     register struct host *host = 0;
!     register struct h_hashChain *chain;
!     register index = h_HashIndex(haddr);
      extern int hostaclRefresh;
  
    restart:
--- 601,631 ----
  }				/*h_Alloc_r */
  
  
+ 
+ /* Make a callback channel even for the console, on the off chance that it
+  * makes a request that causes a break call back.  It shouldn't. */
+ static void
+ h_SetupCallbackConn_r(struct host * host)
+ {
+     if (!sc)
+ 	sc = rxnull_NewClientSecurityObject();
+     host-&gt;callback_rxcon =
+ 	rx_NewConnection(host-&gt;host, host-&gt;port, 1, sc, 0);
+     rx_SetConnDeadTime(host-&gt;callback_rxcon, 50);
+     rx_SetConnHardDeadTime(host-&gt;callback_rxcon, AFS_HARDDEADTIME);
+ }
+ 
  /* Lookup a host given an IP address and UDP port number. */
  /* hostaddr and hport are in network order */
  /* Note: host should be released by caller if 0 == *heldp and non-null */
  /* hostaddr and hport are in network order */
  struct host *
! h_Lookup_r(afs_uint32 haddr, afs_uint16 hport, int *heldp)
  {
!     afs_int32 now;
!     struct host *host = 0;
!     struct h_hashChain *chain;
!     int index = h_HashIndex(haddr);
      extern int hostaclRefresh;
  
    restart:
***************
*** 653,661 ****
  struct host *
  h_LookupUuid_r(afsUUID * uuidp)
  {
!     register struct host *host = 0;
!     register struct h_hashChain *chain;
!     register index = h_UuidHashIndex(uuidp);
  
      for (chain = hostUuidHashTable[index]; chain; chain = chain-&gt;next) {
  	host = chain-&gt;hostPtr;
--- 669,677 ----
  struct host *
  h_LookupUuid_r(afsUUID * uuidp)
  {
!     struct host *host = 0;
!     struct h_hashChain *chain;
!     int index = h_UuidHashIndex(uuidp);
  
      for (chain = hostUuidHashTable[index]; chain; chain = chain-&gt;next) {
  	host = chain-&gt;hostPtr;
***************
*** 708,733 ****
      /* ASSUMPTION: rxi_FreeConnection() does not yield */
      for (cp = &amp;host-&gt;FirstClient; (client = *cp);) {
  	if ((host-&gt;hostFlags &amp; HOSTDELETED) || client-&gt;deleted) {
  	    if (client-&gt;refCount) {
  		char hoststr[16];
  		ViceLog(0,
! 			("Warning: Host %s:%d client %x refcount %d while deleting, failing.\n",
  			 afs_inet_ntoa_r(host-&gt;host, hoststr),
  			 ntohs(host-&gt;port), client, client-&gt;refCount));
  		/* This is the same thing we do if the host is locked */
  		return;
  	    }
- 	    /* We can't protect this without dropping the H_LOCK */
  	    client-&gt;CPS.prlist_len = 0;
! 	    if ((client-&gt;ViceId != ANONYMOUSID) &amp;&amp; client-&gt;CPS.prlist_val) {
  		free(client-&gt;CPS.prlist_val);
! 		client-&gt;CPS.prlist_val = NULL;
! 	    }
  	    if (client-&gt;tcon) {
  		rx_SetSpecific(client-&gt;tcon, rxcon_client_key, (void *)0);
  	    }
  	    CurrentConnections--;
  	    *cp = client-&gt;next;
  	    FreeCE(client);
  	} else
  	    cp = &amp;client-&gt;next;
--- 724,761 ----
      /* ASSUMPTION: rxi_FreeConnection() does not yield */
      for (cp = &amp;host-&gt;FirstClient; (client = *cp);) {
  	if ((host-&gt;hostFlags &amp; HOSTDELETED) || client-&gt;deleted) {
+ 	    int code;
+ 	    ObtainWriteLockNoBlock(&amp;client-&gt;lock, code);
+ 	    if (code &lt; 0) {
+ 		char hoststr[16];
+ 		ViceLog(0,
+ 			("Warning: h_TossStuff_r failed: Host %s:%d client %x was locked.\n",
+ 			 afs_inet_ntoa_r(host-&gt;host, hoststr),
+ 			 ntohs(host-&gt;port), client));
+ 		return;
+ 	    }
+ 		 
  	    if (client-&gt;refCount) {
  		char hoststr[16];
  		ViceLog(0,
! 			("Warning: h_TossStuff_r failed: Host %s:%d client %x refcount %d.\n",
  			 afs_inet_ntoa_r(host-&gt;host, hoststr),
  			 ntohs(host-&gt;port), client, client-&gt;refCount));
  		/* This is the same thing we do if the host is locked */
+ 		ReleaseWriteLock(&amp;client-&gt;lock);
  		return;
  	    }
  	    client-&gt;CPS.prlist_len = 0;
! 	    if ((client-&gt;ViceId != ANONYMOUSID) &amp;&amp; client-&gt;CPS.prlist_val)
  		free(client-&gt;CPS.prlist_val);
! 	    client-&gt;CPS.prlist_val = NULL;
  	    if (client-&gt;tcon) {
  		rx_SetSpecific(client-&gt;tcon, rxcon_client_key, (void *)0);
+ 		rx_PutConnection(client-&gt;tcon);
  	    }
  	    CurrentConnections--;
  	    *cp = client-&gt;next;
+ 	    ReleaseWriteLock(&amp;client-&gt;lock);
  	    FreeCE(client);
  	} else
  	    cp = &amp;client-&gt;next;
***************
*** 754,761 ****
  	     * destroying the connection.
  	     */
  	    client = rx_GetSpecific(rxconn, rxcon_client_key);
! 	    if (client &amp;&amp; client-&gt;tcon == rxconn)
  		client-&gt;tcon = NULL;
  	    rx_SetSpecific(rxconn, rxcon_client_key, (void *)0);
  	    rx_DestroyConnection(rxconn);
  	}
--- 782,791 ----
  	     * destroying the connection.
  	     */
  	    client = rx_GetSpecific(rxconn, rxcon_client_key);
! 	    if (client &amp;&amp; client-&gt;tcon == rxconn) {
! 		rx_PutConnection(client-&gt;tcon);
  		client-&gt;tcon = NULL;
+ 	    }
  	    rx_SetSpecific(rxconn, rxcon_client_key, (void *)0);
  	    rx_DestroyConnection(rxconn);
  	}
***************
*** 824,831 ****
      client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
      if (client) {
  	H_LOCK;
! 	if (client-&gt;tcon == tcon)
! 	    client-&gt;tcon = (struct rx_connection *)0;
  	H_UNLOCK;
      }
      return 0;
--- 854,863 ----
      client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
      if (client) {
  	H_LOCK;
! 	if (client-&gt;tcon == tcon) {
! 	    rx_PutConnection(client-&gt;tcon);
! 	    client-&gt;tcon = NULL;
! 	}
  	H_UNLOCK;
      }
      return 0;
***************
*** 870,877 ****
      H_UNLOCK;
      for (i = 0; i &lt; count; i++) {
  	held[i] = (*proc) (list[i], held[i], param);
! 	if (!held[i])
  	    h_Release(list[i]);	/* this might free up the host */
      }
      free((void *)list);
      free((void *)held);
--- 902,912 ----
      H_UNLOCK;
      for (i = 0; i &lt; count; i++) {
  	held[i] = (*proc) (list[i], held[i], param);
! 	if (!H_ENUMERATE_ISSET_HELD(held[i]))
  	    h_Release(list[i]);	/* this might free up the host */
+ 	/* bail out of the enumeration early */
+ 	if (H_ENUMERATE_ISSET_BAIL(held[i]))
+ 	    break;
      }
      free((void *)list);
      free((void *)held);
***************
*** 899,916 ****
      if (enumstart &amp;&amp; !(held = h_Held_r(enumstart)))
  	h_Hold_r(enumstart); 
      for (host = enumstart; host; host = next, held = nheld) {
- 	held = (*proc) (host, held, param);
  	next = host-&gt;next;
! 	if (next &amp;&amp; !(nheld = h_Held_r(next)))
  	    h_Hold_r(next);
! 	if (!held)
  	    h_Release_r(host); /* this might free up the host */
      }
  }				/*h_Enumerate_r */
  
  /* inserts a new HashChain structure corresponding to this UUID */
! void
! hashInsertUuid_r(struct afsUUID *uuid, struct host *host)
  {
      int index;
      struct h_hashChain *chain;
--- 934,953 ----
      if (enumstart &amp;&amp; !(held = h_Held_r(enumstart)))
  	h_Hold_r(enumstart); 
      for (host = enumstart; host; host = next, held = nheld) {
  	next = host-&gt;next;
! 	if (next &amp;&amp; !(nheld = h_Held_r(next)) &amp;&amp; !H_ENUMERATE_ISSET_BAIL(held))
  	    h_Hold_r(next);
! 	held = (*proc) (host, held, param);
! 	if (!H_ENUMERATE_ISSET_HELD(held))
  	    h_Release_r(host); /* this might free up the host */
+ 	if (H_ENUMERATE_ISSET_BAIL(held))
+ 	    break;
      }
  }				/*h_Enumerate_r */
  
  /* inserts a new HashChain structure corresponding to this UUID */
! static void
! h_AddHostToUuidHashTable_r(struct afsUUID *uuid, struct host *host)
  {
      int index;
      struct h_hashChain *chain;
***************
*** 921,927 ****
      /* insert into beginning of list for this bucket */
      chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
      if (!chain) {
! 	ViceLog(0, ("Failed malloc in hashInsertUuid_r\n"));
  	assert(0);
      }
      assert(chain);
--- 958,964 ----
      /* insert into beginning of list for this bucket */
      chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
      if (!chain) {
! 	ViceLog(0, ("Failed malloc in h_AddHostToUuidHashTable_r\n"));
  	assert(0);
      }
      assert(chain);
***************
*** 932,939 ****
  
  
  /* inserts a new HashChain structure corresponding to this address */
! void
! hashInsert_r(afs_uint32 addr, afs_uint16 port, struct host *host)
  {
      int index;
      struct h_hashChain *chain;
--- 969,976 ----
  
  
  /* inserts a new HashChain structure corresponding to this address */
! static void
! h_AddHostToHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host)
  {
      int index;
      struct h_hashChain *chain;
***************
*** 944,950 ****
      /* insert into beginning of list for this bucket */
      chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
      if (!chain) {
! 	ViceLog(0, ("Failed malloc in hashInsert_r\n"));
  	assert(0);
      }
      chain-&gt;hostPtr = host;
--- 981,987 ----
      /* insert into beginning of list for this bucket */
      chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
      if (!chain) {
! 	ViceLog(0, ("Failed malloc in h_AddHostToHashTable_r\n"));
  	assert(0);
      }
      chain-&gt;hostPtr = host;
***************
*** 975,981 ****
      assert(host);
      assert(host-&gt;interface);
  
!     ViceLog(125, ("addInterfaceAddr : host %s:d addr %s:%d\n", 
  		   afs_inet_ntoa_r(host-&gt;host, hoststr), ntohs(host-&gt;port), 
  		   afs_inet_ntoa_r(addr, hoststr2), ntohs(port)));
  
--- 1012,1018 ----
      assert(host);
      assert(host-&gt;interface);
  
!     ViceLog(125, ("addInterfaceAddr : host %s:%d addr %s:%d\n", 
  		   afs_inet_ntoa_r(host-&gt;host, hoststr), ntohs(host-&gt;port), 
  		   afs_inet_ntoa_r(addr, hoststr2), ntohs(port)));
  
***************
*** 1009,1015 ****
      /*
       * Create a hash table entry for this address
       */
!     hashInsert_r(addr, port, host);
  
      return 0;
  }
--- 1046,1052 ----
      /*
       * Create a hash table entry for this address
       */
!     h_AddHostToHashTable_r(addr, port, host);
  
      return 0;
  }
***************
*** 1064,1070 ****
      /*
       * Remove the hash table entry for this address
       */
!     hashDelete_r(addr, port, host);
  
      return 0;
  }
--- 1101,1107 ----
      /*
       * Remove the hash table entry for this address
       */
!     h_DeleteHostFromHashTableByAddr_r(addr, port, host);
  
      return 0;
  }
***************
*** 1081,1088 ****
      struct interfaceAddr interf;
      int interfValid = 0;
      struct Identity *identP = NULL;
!     afs_int32 haddr;
!     afs_int16 hport;
      char hoststr[16], hoststr2[16];
      Capabilities caps;
      struct rx_connection *cb_conn = NULL;
--- 1118,1125 ----
      struct interfaceAddr interf;
      int interfValid = 0;
      struct Identity *identP = NULL;
!     afs_uint32 haddr;
!     afs_uint16 hport;
      char hoststr[16], hoststr2[16];
      Capabilities caps;
      struct rx_connection *cb_conn = NULL;
***************
*** 1380,1391 ****
  		    }
  		    host-&gt;hostFlags |= HOSTDELETED;
  		    h_Unlock_r(host);
! 		    if (!held)
! 			h_Release_r(host);
  		    host = oldHost;
  		} else {
  		    /* This really is a new host */
! 		    hashInsertUuid_r(&amp;identP-&gt;uuid, host);
  		    cb_conn = host-&gt;callback_rxcon;
  		    rx_GetConnection(cb_conn);		
  		    H_UNLOCK;
--- 1417,1429 ----
  		    }
  		    host-&gt;hostFlags |= HOSTDELETED;
  		    h_Unlock_r(host);
! 		    /* release host because it was allocated by h_Alloc_r */
! 		    h_Release_r(host);
  		    host = oldHost;
+ 		    /* the new host is held and locked */
  		} else {
  		    /* This really is a new host */
! 		    h_AddHostToUuidHashTable_r(&amp;identP-&gt;uuid, host);
  		    cb_conn = host-&gt;callback_rxcon;
  		    rx_GetConnection(cb_conn);		
  		    H_UNLOCK;
***************
*** 1493,1499 ****
  
      cnamelen = strlen(acell);
      if (cnamelen) {
! 	if (afs_is_foreign_ticket_name(aname, "", acell, localcellname)) {
  	    ViceLog(2,
  		    ("MapName: cell is foreign.  cell=%s, localcell=%s, localrealms={%s,%s,%s,%s}\n",
  		    acell, localcellname, local_realms[0],local_realms[1],local_realms[2],local_realms[3]));
--- 1531,1537 ----
  
      cnamelen = strlen(acell);
      if (cnamelen) {
! 	if (afs_is_foreign_ticket_name(aname, NULL, acell, localcellname)) {
  	    ViceLog(2,
  		    ("MapName: cell is foreign.  cell=%s, localcell=%s, localrealms={%s,%s,%s,%s}\n",
  		    acell, localcellname, local_realms[0],local_realms[1],local_realms[2],local_realms[3]));
***************
*** 1546,1552 ****
  /*MapName*/
  
  
! /* NOTE: this returns the client with a Write lock */
  struct client *
  h_ID2Client(afs_int32 vid)
  {
--- 1584,1590 ----
  /*MapName*/
  
  
! /* NOTE: this returns the client with a Write lock and a refCount */
  struct client *
  h_ID2Client(afs_int32 vid)
  {
***************
*** 1562,1570 ****
  		client-&gt;refCount++;
  		H_UNLOCK;
  		ObtainWriteLock(&amp;client-&gt;lock);
- 		H_LOCK;
- 		client-&gt;refCount--;
- 		H_UNLOCK;
  		return client;
  	    }
  	}
--- 1600,1605 ----
***************
*** 1580,1585 ****
--- 1615,1623 ----
   * isn't around. The client is returned with its reference count incremented
   * by one. The caller must call h_ReleaseClient_r when finished with
   * the client.
+  *
+  * the client-&gt;host is returned held.  h_ReleaseClient_r does not release
+  * the hold on client-&gt;host.
   */
  struct client *
  h_FindClient_r(struct rx_connection *tcon)
***************
*** 1684,1697 ****
  			(struct client *)rx_GetSpecific(client-&gt;tcon,
  							rxcon_client_key);
  		    if (oldClient) {
! 			if (oldClient == client)
  			    rx_SetSpecific(client-&gt;tcon, rxcon_client_key,
  					   NULL);
! 			else
  			    ViceLog(0,
  				    ("Client-conn mismatch: CL1=%x, CN=%x, CL2=%x\n",
  				     client, client-&gt;tcon, oldClient));
  		    }
  		    client-&gt;tcon = (struct rx_connection *)0;
  		}
  		client-&gt;refCount++;
--- 1722,1736 ----
  			(struct client *)rx_GetSpecific(client-&gt;tcon,
  							rxcon_client_key);
  		    if (oldClient) {
! 			if (oldClient == client) {
  			    rx_SetSpecific(client-&gt;tcon, rxcon_client_key,
  					   NULL);
! 			} else
  			    ViceLog(0,
  				    ("Client-conn mismatch: CL1=%x, CN=%x, CL2=%x\n",
  				     client, client-&gt;tcon, oldClient));
  		    }
+ 		    rx_PutConnection(client-&gt;tcon);
  		    client-&gt;tcon = (struct rx_connection *)0;
  		}
  		client-&gt;refCount++;
***************
*** 1726,1732 ****
  	    client-&gt;authClass = authClass;	/* rx only */
  	    client-&gt;sid = rxr_CidOf(tcon);
  	    client-&gt;VenusEpoch = rxr_GetEpoch(tcon);
! 	    client-&gt;CPS.prlist_val = 0;
  	    client-&gt;CPS.prlist_len = 0;
  	    h_Unlock_r(host);
  	}
--- 1765,1771 ----
  	    client-&gt;authClass = authClass;	/* rx only */
  	    client-&gt;sid = rxr_CidOf(tcon);
  	    client-&gt;VenusEpoch = rxr_GetEpoch(tcon);
! 	    client-&gt;CPS.prlist_val = NULL;
  	    client-&gt;CPS.prlist_len = 0;
  	    h_Unlock_r(host);
  	}
***************
*** 1734,1744 ****
      client-&gt;prfail = fail;
  
      if (!(client-&gt;CPS.prlist_val) || (viceid != client-&gt;ViceId)) {
! 	if (client-&gt;CPS.prlist_val &amp;&amp; (client-&gt;ViceId != ANONYMOUSID)) {
  	    free(client-&gt;CPS.prlist_val);
- 	}
  	client-&gt;CPS.prlist_val = NULL;
- 	client-&gt;CPS.prlist_len = 0;
  	client-&gt;ViceId = viceid;
  	client-&gt;expTime = expTime;
  
--- 1773,1782 ----
      client-&gt;prfail = fail;
  
      if (!(client-&gt;CPS.prlist_val) || (viceid != client-&gt;ViceId)) {
! 	client-&gt;CPS.prlist_len = 0;
! 	if (client-&gt;CPS.prlist_val &amp;&amp; (client-&gt;ViceId != ANONYMOUSID))
  	    free(client-&gt;CPS.prlist_val);
  	client-&gt;CPS.prlist_val = NULL;
  	client-&gt;ViceId = viceid;
  	client-&gt;expTime = expTime;
  
***************
*** 1797,1806 ****
  			    afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
  			    ntohs(rxr_PortOf(tcon)),
  			    oldClient, oldClient-&gt;sid));
! 		if ((client-&gt;ViceId != ANONYMOUSID) &amp;&amp; client-&gt;CPS.prlist_val) {
  		    free(client-&gt;CPS.prlist_val);
! 		    client-&gt;CPS.prlist_val = NULL;
! 		}
  		client-&gt;CPS.prlist_len = 0;
  		if (client-&gt;tcon) {
  		    rx_SetSpecific(client-&gt;tcon, rxcon_client_key, (void *)0);
--- 1835,1843 ----
  			    afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
  			    ntohs(rxr_PortOf(tcon)),
  			    oldClient, oldClient-&gt;sid));
! 		if ((client-&gt;ViceId != ANONYMOUSID) &amp;&amp; client-&gt;CPS.prlist_val)
  		    free(client-&gt;CPS.prlist_val);
! 		client-&gt;CPS.prlist_val = NULL;
  		client-&gt;CPS.prlist_len = 0;
  		if (client-&gt;tcon) {
  		    rx_SetSpecific(client-&gt;tcon, rxcon_client_key, (void *)0);
***************
*** 1817,1822 ****
--- 1854,1860 ----
  	    oldClient-&gt;refCount++;
  	    client = oldClient;
  	} else {
+ 	    rx_PutConnection(oldClient-&gt;tcon);
  	    oldClient-&gt;tcon = (struct rx_connection *)0;
  	    ViceLog(0, ("FindClient: deleted client %x(%x) already had conn %x (host %s:%d), stolen by client %x(%x)\n", 
  			oldClient, oldClient-&gt;sid, tcon, 
***************
*** 1834,1839 ****
--- 1872,1878 ----
  	h_Unlock_r(host);
  	CurrentConnections++;	/* increment number of connections */
      }
+     rx_GetConnection(tcon);
      client-&gt;tcon = tcon;
      rx_SetSpecific(tcon, rxcon_client_key, client);
      ReleaseWriteLock(&amp;client-&gt;lock);
***************
*** 1968,1975 ****
--- 2007,2016 ----
      char tmpStr[256];
      char tbuffer[32];
      char hoststr[16];
+     time_t LastCall, expTime;
  
      H_LOCK;
+     LastCall = host-&gt;LastCall;
      if (host-&gt;hostFlags &amp; HOSTDELETED) {
  	H_UNLOCK;
  	return held;
***************
*** 1978,1989 ****
  		       "Host %s:%d down = %d, LastCall %s",
  		       afs_inet_ntoa_r(host-&gt;host, hoststr),
  		       ntohs(host-&gt;port), (host-&gt;hostFlags &amp; VENUSDOWN),
! 		       afs_ctime((time_t *) &amp; host-&gt;LastCall, tbuffer,
  				 sizeof(tbuffer)));
      (void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
      for (client = host-&gt;FirstClient; client; client = client-&gt;next) {
  	if (!client-&gt;deleted) {
  	    if (client-&gt;tcon) {
  		(void)afs_snprintf(tmpStr, sizeof tmpStr,
  				   "    user id=%d,  name=%s, sl=%s till %s",
  				   client-&gt;ViceId, h_UserName(client),
--- 2019,2031 ----
  		       "Host %s:%d down = %d, LastCall %s",
  		       afs_inet_ntoa_r(host-&gt;host, hoststr),
  		       ntohs(host-&gt;port), (host-&gt;hostFlags &amp; VENUSDOWN),
! 		       afs_ctime(&amp;LastCall, tbuffer,
  				 sizeof(tbuffer)));
      (void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
      for (client = host-&gt;FirstClient; client; client = client-&gt;next) {
  	if (!client-&gt;deleted) {
  	    if (client-&gt;tcon) {
+ 		expTime = client-&gt;expTime;
  		(void)afs_snprintf(tmpStr, sizeof tmpStr,
  				   "    user id=%d,  name=%s, sl=%s till %s",
  				   client-&gt;ViceId, h_UserName(client),
***************
*** 1991,1998 ****
  				   authClass ? "Authenticated" :
  				   "Not authenticated",
  				   client-&gt;
! 				   authClass ? afs_ctime((time_t *) &amp; client-&gt;
! 							 expTime, tbuffer,
  							 sizeof(tbuffer))
  				   : "No Limit\n");
  		(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
--- 2033,2039 ----
  				   authClass ? "Authenticated" :
  				   "Not authenticated",
  				   client-&gt;
! 				   authClass ? afs_ctime(&amp;expTime, tbuffer,
  							 sizeof(tbuffer))
  				   : "No Limit\n");
  		(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
***************
*** 2127,2132 ****
--- 2168,2707 ----
  
  }				/*h_DumpHosts */
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * demand attach fs
+  * host state serialization
+  */
+ static int h_stateFillHeader(struct host_state_header * hdr);
+ static int h_stateCheckHeader(struct host_state_header * hdr);
+ static int h_stateAllocMap(struct fs_dump_state * state);
+ static int h_stateSaveHost(register struct host * host, int held, struct fs_dump_state * state);
+ static int h_stateRestoreHost(struct fs_dump_state * state);
+ static int h_stateRestoreIndex(struct host * h, int held, struct fs_dump_state * state);
+ static int h_stateVerifyHost(struct host * h, int held, struct fs_dump_state * state);
+ static int h_stateVerifyAddrHash(struct fs_dump_state * state, struct host * h, afs_uint32 addr, afs_uint16 port);
+ static int h_stateVerifyUuidHash(struct fs_dump_state * state, struct host * h);
+ static void h_hostToDiskEntry_r(struct host * in, struct hostDiskEntry * out);
+ static void h_diskEntryToHost_r(struct hostDiskEntry * in, struct host * out);
+ 
+ 
+ /* this procedure saves all host state to disk for fast startup */
+ int
+ h_stateSave(struct fs_dump_state * state)
+ {
+     AssignInt64(state-&gt;eof_offset, &amp;state-&gt;hdr-&gt;h_offset);
+ 
+     /* XXX debug */
+     ViceLog(0, ("h_stateSave:  hostCount=%d\n", hostCount));
+ 
+     /* invalidate host state header */
+     memset(state-&gt;h_hdr, 0, sizeof(struct host_state_header));
+ 
+     if (fs_stateWriteHeader(state, &amp;state-&gt;hdr-&gt;h_offset, state-&gt;h_hdr,
+ 			    sizeof(struct host_state_header))) {
+ 	state-&gt;bail = 1;
+ 	goto done;
+     }
+ 
+     fs_stateIncEOF(state, sizeof(struct host_state_header));
+ 
+     h_Enumerate_r(h_stateSaveHost, hostList, (char *)state);
+     if (state-&gt;bail) {
+ 	goto done;
+     }
+ 
+     h_stateFillHeader(state-&gt;h_hdr);
+ 
+     /* write the real header to disk */
+     state-&gt;bail = fs_stateWriteHeader(state, &amp;state-&gt;hdr-&gt;h_offset, state-&gt;h_hdr,
+ 				      sizeof(struct host_state_header));
+ 
+  done:
+     return state-&gt;bail;
+ }
+ 
+ /* demand attach fs
+  * host state serialization
+  *
+  * this procedure restores all host state from a disk for fast startup 
+  */
+ int
+ h_stateRestore(struct fs_dump_state * state)
+ {
+     int i, records;
+ 
+     /* seek to the right position and read in the host state header */
+     if (fs_stateReadHeader(state, &amp;state-&gt;hdr-&gt;h_offset, state-&gt;h_hdr,
+ 			   sizeof(struct host_state_header))) {
+ 	state-&gt;bail = 1;
+ 	goto done;
+     }
+ 
+     /* check the validity of the header */
+     if (h_stateCheckHeader(state-&gt;h_hdr)) {
+ 	state-&gt;bail = 1;
+ 	goto done;
+     }
+ 
+     records = state-&gt;h_hdr-&gt;records;
+ 
+     if (h_stateAllocMap(state)) {
+ 	state-&gt;bail = 1;
+ 	goto done;
+     }
+ 
+     /* iterate over records restoring host state */
+     for (i=0; i &lt; records; i++) {
+ 	if (h_stateRestoreHost(state) != 0) {
+ 	    state-&gt;bail = 1;
+ 	    break;
+ 	}
+     }
+ 
+  done:
+     return state-&gt;bail;
+ }
+ 
+ int
+ h_stateRestoreIndices(struct fs_dump_state * state)
+ {
+     h_Enumerate_r(h_stateRestoreIndex, hostList, (char *)state);
+     return state-&gt;bail;
+ }
+ 
+ static int
+ h_stateRestoreIndex(struct host * h, int held, struct fs_dump_state * state)
+ {
+     if (cb_OldToNew(state, h-&gt;cblist, &amp;h-&gt;cblist)) {
+ 	return H_ENUMERATE_BAIL(held);
+     }
+     return held;
+ }
+ 
+ int
+ h_stateVerify(struct fs_dump_state * state)
+ {
+     h_Enumerate_r(h_stateVerifyHost, hostList, (char *)state);
+     return state-&gt;bail;
+ }
+ 
+ static int
+ h_stateVerifyHost(struct host * h, int held, struct fs_dump_state * state)
+ {
+     int i;
+ 
+     if (h == NULL) {
+ 	ViceLog(0, ("h_stateVerifyHost: error: NULL host pointer in linked list\n"));
+ 	return H_ENUMERATE_BAIL(held);
+     }
+ 
+     if (h-&gt;interface) {
+ 	for (i = h-&gt;interface-&gt;numberOfInterfaces-1; i &gt;= 0; i--) {
+ 	    if (h_stateVerifyAddrHash(state, h, h-&gt;interface-&gt;interface[i].addr, 
+ 				      h-&gt;interface-&gt;interface[i].port)) {
+ 		state-&gt;bail = 1;
+ 	    }
+ 	}
+ 	if (h_stateVerifyUuidHash(state, h)) {
+ 	    state-&gt;bail = 1;
+ 	}
+     } else if (h_stateVerifyAddrHash(state, h, h-&gt;host, h-&gt;port)) {
+ 	state-&gt;bail = 1;
+     }
+ 
+     if (cb_stateVerifyHCBList(state, h)) {
+ 	state-&gt;bail = 1;
+     }
+ 
+  done:
+     return held;
+ }
+ 
+ static int
+ h_stateVerifyAddrHash(struct fs_dump_state * state, struct host * h, afs_uint32 addr, afs_uint16 port)
+ {
+     int ret = 0, found = 0;
+     struct host *host = NULL;
+     struct h_hashChain *chain;
+     int index = h_HashIndex(addr);
+     char tmp[16];
+     int chain_len = 0;
+ 
+     for (chain = hostHashTable[index]; chain; chain = chain-&gt;next) {
+ 	host = chain-&gt;hostPtr;
+ 	if (host == NULL) {
+ 	    afs_inet_ntoa_r(addr, tmp);
+ 	    ViceLog(0, ("h_stateVerifyAddrHash: error: addr hash chain has NULL host ptr (lookup addr %s)\n", tmp));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	if ((chain-&gt;addr == addr) &amp;&amp; (chain-&gt;port == port)) {
+ 	    if (host != h) {
+ 		ViceLog(0, ("h_stateVerifyAddrHash: warning: addr hash entry points to different host struct (%d, %d)\n", 
+ 			    h-&gt;index, host-&gt;index));
+ 		state-&gt;flags.warnings_generated = 1;
+ 	    }
+ 	    found = 1;
+ 	    break;
+ 	}
+ 	if (chain_len &gt; FS_STATE_H_MAX_ADDR_HASH_CHAIN_LEN) {
+ 	    ViceLog(0, ("h_stateVerifyAddrHash: error: hash chain length exceeds %d; assuming there's a loop\n",
+ 			FS_STATE_H_MAX_ADDR_HASH_CHAIN_LEN));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	chain_len++;
+     }
+ 
+     if (!found) {
+ 	afs_inet_ntoa_r(addr, tmp);
+ 	if (state-&gt;mode == FS_STATE_LOAD_MODE) {
+ 	    ViceLog(0, ("h_stateVerifyAddrHash: error: addr %s not found in hash\n", tmp));
+ 	    ret = 1;
+ 	    goto done;
+ 	} else {
+ 	    ViceLog(0, ("h_stateVerifyAddrHash: warning: addr %s not found in hash\n", tmp));
+ 	    state-&gt;flags.warnings_generated = 1;
+ 	}
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ static int
+ h_stateVerifyUuidHash(struct fs_dump_state * state, struct host * h)
+ {
+     int ret = 0, found = 0;
+     struct host *host = NULL;
+     struct h_hashChain *chain;
+     afsUUID * uuidp = &amp;h-&gt;interface-&gt;uuid;
+     int index = h_UuidHashIndex(uuidp);
+     char tmp[40];
+     int chain_len = 0;
+ 
+     for (chain = hostUuidHashTable[index]; chain; chain = chain-&gt;next) {
+ 	host = chain-&gt;hostPtr;
+ 	if (host == NULL) {
+ 	    afsUUID_to_string(uuidp, tmp, sizeof(tmp));
+ 	    ViceLog(0, ("h_stateVerifyUuidHash: error: uuid hash chain has NULL host ptr (lookup uuid %s)\n", tmp));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	if (host-&gt;interface &amp;&amp;
+ 	    afs_uuid_equal(&amp;host-&gt;interface-&gt;uuid, uuidp)) {
+ 	    if (host != h) {
+ 		ViceLog(0, ("h_stateVerifyUuidHash: warning: uuid hash entry points to different host struct (%d, %d)\n", 
+ 			    h-&gt;index, host-&gt;index));
+ 		state-&gt;flags.warnings_generated = 1;
+ 	    }
+ 	    found = 1;
+ 	    goto done;
+ 	}
+ 	if (chain_len &gt; FS_STATE_H_MAX_UUID_HASH_CHAIN_LEN) {
+ 	    ViceLog(0, ("h_stateVerifyUuidHash: error: hash chain length exceeds %d; assuming there's a loop\n",
+ 			FS_STATE_H_MAX_UUID_HASH_CHAIN_LEN));
+ 	    ret = 1;
+ 	    goto done;
+ 	}
+ 	chain_len++;
+     }
+ 
+     if (!found) {
+ 	afsUUID_to_string(uuidp, tmp, sizeof(tmp));
+ 	if (state-&gt;mode == FS_STATE_LOAD_MODE) {
+ 	    ViceLog(0, ("h_stateVerifyUuidHash: error: uuid %s not found in hash\n", tmp));
+ 	    ret = 1;
+ 	    goto done;
+ 	} else {
+ 	    ViceLog(0, ("h_stateVerifyUuidHash: warning: uuid %s not found in hash\n", tmp));
+ 	    state-&gt;flags.warnings_generated = 1;
+ 	}
+     }
+ 
+  done:
+     return ret;
+ }
+ 
+ /* create the host state header structure */
+ static int
+ h_stateFillHeader(struct host_state_header * hdr)
+ {
+     hdr-&gt;stamp.magic = HOST_STATE_MAGIC;
+     hdr-&gt;stamp.version = HOST_STATE_VERSION;
+ }
+ 
+ /* check the contents of the host state header structure */
+ static int
+ h_stateCheckHeader(struct host_state_header * hdr)
+ {
+     int ret=0;
+ 
+     if (hdr-&gt;stamp.magic != HOST_STATE_MAGIC) {
+ 	ViceLog(0, ("check_host_state_header: invalid state header\n"));
+ 	ret = 1;
+     }
+     else if (hdr-&gt;stamp.version != HOST_STATE_VERSION) {
+ 	ViceLog(0, ("check_host_state_header: unknown version number\n"));
+ 	ret = 1;
+     }
+     return ret;
+ }
+ 
+ /* allocate the host id mapping table */
+ static int
+ h_stateAllocMap(struct fs_dump_state * state)
+ {
+     state-&gt;h_map.len = state-&gt;h_hdr-&gt;index_max + 1;
+     state-&gt;h_map.entries = (struct idx_map_entry_t *)
+ 	calloc(state-&gt;h_map.len, sizeof(struct idx_map_entry_t));
+     return (state-&gt;h_map.entries != NULL) ? 0 : 1;
+ }
+ 
+ /* function called by h_Enumerate to save a host to disk */
+ static int
+ h_stateSaveHost(register struct host * host, int held, struct fs_dump_state * state)
+ {
+     int i, if_len=0, hcps_len=0;
+     struct hostDiskEntry hdsk;
+     struct host_state_entry_header hdr;
+     struct Interface * ifp = NULL;
+     afs_int32 * hcps = NULL;
+     struct iovec iov[4];
+     int iovcnt = 2;
+ 
+     memset(&amp;hdr, 0, sizeof(hdr));
+ 
+     if (state-&gt;h_hdr-&gt;index_max &lt; host-&gt;index) {
+ 	state-&gt;h_hdr-&gt;index_max = host-&gt;index;
+     }
+ 
+     h_hostToDiskEntry_r(host, &amp;hdsk);
+     if (host-&gt;interface) {
+ 	if_len = sizeof(struct Interface) + 
+ 	    ((host-&gt;interface-&gt;numberOfInterfaces-1) * sizeof(struct AddrPort));
+ 	ifp = (struct Interface *) malloc(if_len);
+ 	assert(ifp != NULL);
+ 	memcpy(ifp, host-&gt;interface, if_len);
+ 	hdr.interfaces = host-&gt;interface-&gt;numberOfInterfaces;
+ 	iov[iovcnt].iov_base = (char *) ifp;
+ 	iov[iovcnt].iov_len = if_len;
+ 	iovcnt++;
+     }
+     if (host-&gt;hcps.prlist_val) {
+ 	hdr.hcps = host-&gt;hcps.prlist_len;
+ 	hcps_len = hdr.hcps * sizeof(afs_int32);
+ 	hcps = (afs_int32 *) malloc(hcps_len);
+ 	assert(hcps != NULL);
+ 	memcpy(hcps, host-&gt;hcps.prlist_val, hcps_len);
+ 	iov[iovcnt].iov_base = (char *) hcps;
+ 	iov[iovcnt].iov_len = hcps_len;
+ 	iovcnt++;
+     }
+ 
+     if (hdsk.index &gt; state-&gt;h_hdr-&gt;index_max)
+ 	state-&gt;h_hdr-&gt;index_max = hdsk.index;
+ 
+     hdr.len = sizeof(struct host_state_entry_header) + 
+ 	sizeof(struct hostDiskEntry) + if_len + hcps_len;
+     hdr.magic = HOST_STATE_ENTRY_MAGIC;
+ 
+     iov[0].iov_base = (char *) &amp;hdr;
+     iov[0].iov_len = sizeof(hdr);
+     iov[1].iov_base = (char *) &amp;hdsk;
+     iov[1].iov_len = sizeof(struct hostDiskEntry);
+     
+     if (fs_stateWriteV(state, iov, iovcnt)) {
+ 	ViceLog(0, ("h_stateSaveHost: failed to save host %d", host-&gt;index));
+ 	state-&gt;bail = 1;
+     }
+ 
+     fs_stateIncEOF(state, hdr.len);
+ 
+     state-&gt;h_hdr-&gt;records++;
+ 
+  done:
+     if (ifp)
+ 	free(ifp);
+     if (hcps)
+ 	free(hcps);
+     if (state-&gt;bail) {
+ 	return H_ENUMERATE_BAIL(held);
+     }
+     return held;
+ }
+ 
+ /* restores a host from disk */
+ static int
+ h_stateRestoreHost(struct fs_dump_state * state)
+ {
+     int ifp_len=0, hcps_len=0, bail=0;
+     struct host_state_entry_header hdr;
+     struct hostDiskEntry hdsk;
+     struct host *host = NULL;
+     struct Interface *ifp = NULL;
+     afs_int32 * hcps = NULL;
+     struct iovec iov[3];
+     int iovcnt = 1;
+ 
+     if (fs_stateRead(state, &amp;hdr, sizeof(hdr))) {
+ 	ViceLog(0, ("h_stateRestoreHost: failed to read host entry header from dump file '%s'\n",
+ 		    state-&gt;fn));
+ 	bail = 1;
+ 	goto done;
+     }
+ 
+     if (hdr.magic != HOST_STATE_ENTRY_MAGIC) {
+ 	ViceLog(0, ("h_stateRestoreHost: fileserver state dump file '%s' is corrupt.\n",
+ 		    state-&gt;fn));
+ 	bail = 1;
+ 	goto done;
+     }
+ 
+     iov[0].iov_base = (char *) &amp;hdsk;
+     iov[0].iov_len = sizeof(struct hostDiskEntry);
+ 
+     if (hdr.interfaces) {
+ 	ifp_len = sizeof(struct Interface) +
+ 	    ((hdr.interfaces-1) * sizeof(struct AddrPort));
+ 	ifp = (struct Interface *) malloc(ifp_len);
+ 	assert(ifp != NULL);
+ 	iov[iovcnt].iov_base = (char *) ifp;
+ 	iov[iovcnt].iov_len = ifp_len;
+ 	iovcnt++;
+     }
+     if (hdr.hcps) {
+ 	hcps_len = hdr.hcps * sizeof(afs_int32);
+ 	hcps = (afs_int32 *) malloc(hcps_len);
+ 	assert(hcps != NULL);
+ 	iov[iovcnt].iov_base = (char *) hcps;
+ 	iov[iovcnt].iov_len = hcps_len;
+ 	iovcnt++;
+     }
+ 
+     if ((ifp_len + hcps_len + sizeof(hdsk) + sizeof(hdr)) != hdr.len) {
+ 	ViceLog(0, ("h_stateRestoreHost: host entry header length fields are inconsistent\n"));
+ 	bail = 1;
+ 	goto done;
+     }
+ 
+     if (fs_stateReadV(state, iov, iovcnt)) {
+ 	ViceLog(0, ("h_stateRestoreHost: failed to read host entry\n"));
+ 	bail = 1;
+ 	goto done;
+     }
+ 
+     if (!hdr.hcps &amp;&amp; hdsk.hcps_valid) {
+ 	/* valid, zero-length host cps ; does this ever happen? */
+ 	hcps = (afs_int32 *) malloc(sizeof(afs_int32));
+ 	assert(hcps != NULL);
+     }
+ 
+     host = GetHT();
+     assert(host != NULL);
+ 
+     if (ifp) {
+ 	host-&gt;interface = ifp;
+     }
+     if (hcps) {
+ 	host-&gt;hcps.prlist_val = hcps;
+ 	host-&gt;hcps.prlist_len = hdr.hcps;
+     }
+ 
+     h_diskEntryToHost_r(&amp;hdsk, host);
+     h_SetupCallbackConn_r(host);
+ 
+     if (ifp) {
+ 	int i;
+ 	for (i = ifp-&gt;numberOfInterfaces-1; i &gt;= 0; i--) {
+ 	    h_AddHostToHashTable_r(ifp-&gt;interface[i].addr, 
+ 				   ifp-&gt;interface[i].port, host);
+ 	}
+ 	h_AddHostToUuidHashTable_r(&amp;ifp-&gt;uuid, host);
+     } else {
+ 	h_AddHostToHashTable_r(host-&gt;host, host-&gt;port, host);
+     }
+     h_InsertList_r(host);
+ 
+     /* setup host id map entry */
+     state-&gt;h_map.entries[hdsk.index].old_idx = hdsk.index;
+     state-&gt;h_map.entries[hdsk.index].new_idx = host-&gt;index;
+ 
+  done:
+     if (bail) {
+ 	if (ifp)
+ 	    free(ifp);
+ 	if (hcps)
+ 	    free(hcps);
+     }
+     return bail;
+ }
+ 
+ /* serialize a host structure to disk */
+ static void
+ h_hostToDiskEntry_r(struct host * in, struct hostDiskEntry * out)
+ {
+     out-&gt;host = in-&gt;host;
+     out-&gt;port = in-&gt;port;
+     out-&gt;hostFlags = in-&gt;hostFlags;
+     out-&gt;Console = in-&gt;Console;
+     out-&gt;hcpsfailed = in-&gt;hcpsfailed;
+     out-&gt;LastCall = in-&gt;LastCall;
+     out-&gt;ActiveCall = in-&gt;ActiveCall;
+     out-&gt;cpsCall = in-&gt;cpsCall;
+     out-&gt;cblist = in-&gt;cblist;
+ #ifdef FS_STATS_DETAILED
+     out-&gt;InSameNetwork = in-&gt;InSameNetwork;
+ #endif
+ 
+     /* special fields we save, but are not memcpy'd back on restore */
+     out-&gt;index = in-&gt;index;
+     out-&gt;hcps_len = in-&gt;hcps.prlist_len;
+     out-&gt;hcps_valid = (in-&gt;hcps.prlist_val == NULL) ? 0 : 1;
+ }
+ 
+ /* restore a host structure from disk */
+ static void
+ h_diskEntryToHost_r(struct hostDiskEntry * in, struct host * out)
+ {
+     out-&gt;host = in-&gt;host;
+     out-&gt;port = in-&gt;port;
+     out-&gt;hostFlags = in-&gt;hostFlags;
+     out-&gt;Console = in-&gt;Console;
+     out-&gt;hcpsfailed = in-&gt;hcpsfailed;
+     out-&gt;LastCall = in-&gt;LastCall;
+     out-&gt;ActiveCall = in-&gt;ActiveCall;
+     out-&gt;cpsCall = in-&gt;cpsCall;
+     out-&gt;cblist = in-&gt;cblist;
+ #ifdef FS_STATS_DETAILED
+     out-&gt;InSameNetwork = in-&gt;InSameNetwork;
+ #endif
+ }
+ 
+ /* index translation routines */
+ int
+ h_OldToNew(struct fs_dump_state * state, afs_uint32 old, afs_uint32 * new)
+ {
+     int ret = 0;
+ 
+     /* hosts use a zero-based index, so old==0 is valid */
+ 
+     if (old &gt;= state-&gt;h_map.len) {
+ 	ViceLog(0, ("h_OldToNew: index %d is out of range\n", old));
+ 	ret = 1;
+     } else if (state-&gt;h_map.entries[old].old_idx != old) { /* sanity check */
+ 	ViceLog(0, ("h_OldToNew: index %d points to an invalid host record\n", old));
+ 	ret = 1;
+     } else {
+ 	*new = state-&gt;h_map.entries[old].new_idx;
+     }
+ 
+  done:
+     return ret;
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  
  /*
   * This counts the number of workstations, the number of active workstations,
***************
*** 2341,2353 ****
   * Since it can serialize them, and pile up, it should be a separate LWP
   * from other events.
   */
! int
  CheckHost(register struct host *host, int held)
  {
      register struct client *client;
      struct rx_connection *cb_conn = NULL;
      int code;
  
      /* Host is held by h_Enumerate */
      H_LOCK;
      for (client = host-&gt;FirstClient; client; client = client-&gt;next) {
--- 2916,2938 ----
   * Since it can serialize them, and pile up, it should be a separate LWP
   * from other events.
   */
! static int
  CheckHost(register struct host *host, int held)
  {
      register struct client *client;
      struct rx_connection *cb_conn = NULL;
      int code;
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+     /* kill the checkhost lwp ASAP during shutdown */
+     FS_STATE_RDLOCK;
+     if (fs_state.mode == FS_MODE_SHUTDOWN) {
+ 	FS_STATE_UNLOCK;
+ 	return H_ENUMERATE_BAIL(held);
+     }
+     FS_STATE_UNLOCK;
+ #endif
+ 
      /* Host is held by h_Enumerate */
      H_LOCK;
      for (client = host-&gt;FirstClient; client; client = client-&gt;next) {
***************
*** 2448,2454 ****
   * This routine is called roughly every 5 minutes.
   */
  void
! h_CheckHosts()
  {
      afs_uint32 now = FT_ApproxTime();
  
--- 3033,3039 ----
   * This routine is called roughly every 5 minutes.
   */
  void
! h_CheckHosts(void)
  {
      afs_uint32 now = FT_ApproxTime();
  
***************
*** 2563,2569 ****
  /* deleted a HashChain structure for this address and host */
  /* returns 1 on success */
  static int
! hashDelete_r(afs_uint32 addr, afs_uint16 port, struct host *host)
  {
      int flag;
      register struct h_hashChain **hp, *th;
--- 3148,3154 ----
  /* deleted a HashChain structure for this address and host */
  /* returns 1 on success */
  static int
! h_DeleteHostFromHashTableByAddr_r(afs_uint32 addr, afs_uint16 port, struct host *host)
  {
      int flag;
      register struct h_hashChain **hp, *th;
Index: openafs/src/viced/host.h
diff -c openafs/src/viced/host.h:1.16 openafs/src/viced/host.h:1.21
*** openafs/src/viced/host.h:1.16	Tue Feb 14 11:58:13 2006
--- openafs/src/viced/host.h	Fri Mar 17 14:54:49 2006
***************
*** 5,12 ****
--- 5,17 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
+ #ifndef _AFS_VICED_HOST_H
+ #define _AFS_VICED_HOST_H
+ 
  #include "fs_stats.h"		/*File Server stats package */
  
  #ifdef AFS_PTHREAD_ENV
***************
*** 59,64 ****
--- 64,70 ----
      struct AddrPort interface[1];/* there are actually more than one here */
      /* in network byte order */
  };
+ 
  struct host {
      struct host *next, *prev;	/* linked list of all hosts */
      struct rx_connection *callback_rxcon;	/* rx callback connection */
***************
*** 66,75 ****
      /* holds on this host; 1 bit per lwp.
       * A hold prevents this structure and
       * inferior structures from disappearing */
!     unsigned int host;		/* IP address of host interface that is
  				 * currently being used, in network
  				 * byte order */
!     unsigned short port;	/* port address of host */
      char Console;		/* XXXX This host is a console */
      unsigned short hostFlags;		/*  bit map */
  #if FS_STATS_DETAILED
--- 72,81 ----
      /* holds on this host; 1 bit per lwp.
       * A hold prevents this structure and
       * inferior structures from disappearing */
!     afs_uint32 host;		/* IP address of host interface that is
  				 * currently being used, in network
  				 * byte order */
!     afs_uint16 port;		/* port address of host */
      char Console;		/* XXXX This host is a console */
      unsigned short hostFlags;		/*  bit map */
  #if FS_STATS_DETAILED
***************
*** 85,91 ****
      struct client *FirstClient;	/* first connection from host */
      afs_uint32 cpsCall;		/* time of last cps call from this host */
      struct Interface *interface;	/* all alternate addr for client */
!     afs_uint32 cblist;		/* Call back list for this host */
      /*
       * These don't get zeroed, keep them at the end. If index doesn't
       * follow an unsigned short then we need to pad to ensure that
--- 91,97 ----
      struct client *FirstClient;	/* first connection from host */
      afs_uint32 cpsCall;		/* time of last cps call from this host */
      struct Interface *interface;	/* all alternate addr for client */
!     afs_uint32 cblist;		/* index of a cb in the per-host circular CB list */
      /*
       * These don't get zeroed, keep them at the end. If index doesn't
       * follow an unsigned short then we need to pad to ensure that
***************
*** 142,147 ****
--- 148,154 ----
  /* Don't zero the lock */
  #define CLIENT_TO_ZERO(C)	((int)(((char *)(&amp;((C)-&gt;lock))-(char *)(C))))
  
+ 
  /*
   * key for the client structure stored in connection specific data
   */
***************
*** 211,222 ****
  extern int MultiBreakCallBackAlternateAddress_r(struct host *host,
  				     struct AFSCBFids *afidp);
  extern int DumpCallBackState(void);
  extern void ShutDownAndCore(int dopanic);
  
  extern struct host *h_Alloc(register struct rx_connection *r_con);
  extern struct host *h_Alloc_r(register struct rx_connection *r_con);
! extern struct host *h_Lookup_r(afs_uint32 hostaddr, afs_uint32 hport,
  			       int *heldp);
  extern struct host *h_LookupUuid_r(afsUUID * uuidp);
  extern int h_FreeConnection(struct rx_connection *tcon);
  extern void h_Enumerate(int (*proc) (), char *param);
--- 218,233 ----
  extern int MultiBreakCallBackAlternateAddress_r(struct host *host,
  				     struct AFSCBFids *afidp);
  extern int DumpCallBackState(void);
+ extern int PrintCallBackStats(void);
+ extern int ShutDown(void);
  extern void ShutDownAndCore(int dopanic);
  
  extern struct host *h_Alloc(register struct rx_connection *r_con);
  extern struct host *h_Alloc_r(register struct rx_connection *r_con);
! extern struct host *h_Lookup_r(afs_uint32 hostaddr, afs_uint16 hport,
  			       int *heldp);
+ extern void   hashInsert_r(afs_uint32 addr, afs_uint16 port, 
+ 			   struct host* host);
  extern struct host *h_LookupUuid_r(afsUUID * uuidp);
  extern int h_FreeConnection(struct rx_connection *tcon);
  extern void h_Enumerate(int (*proc) (), char *param);
***************
*** 231,237 ****
  extern void h_PrintClients();
  extern void h_GetWorkStats();
  extern void h_flushhostcps(register afs_uint32 hostaddr,
! 			   register afs_uint32 hport);
  extern void h_GetHostNetStats(afs_int32 * a_numHostsP, afs_int32 * a_sameNetOrSubnetP,
  		  afs_int32 * a_diffSubnetP, afs_int32 * a_diffNetworkP);
  extern int h_NBLock_r(register struct host *host);
--- 242,248 ----
  extern void h_PrintClients();
  extern void h_GetWorkStats();
  extern void h_flushhostcps(register afs_uint32 hostaddr,
! 			   register afs_uint16 hport);
  extern void h_GetHostNetStats(afs_int32 * a_numHostsP, afs_int32 * a_sameNetOrSubnetP,
  		  afs_int32 * a_diffSubnetP, afs_int32 * a_diffNetworkP);
  extern int h_NBLock_r(register struct host *host);
***************
*** 241,246 ****
--- 252,270 ----
  struct Interface *MultiVerifyInterface_r();
  extern int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf);
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * demand attach fs
+  * state serialization
+  */
+ extern int h_SaveState(void);
+ extern int h_RestoreState(void);
+ #endif
+ 
+ #define H_ENUMERATE_BAIL(held)        ((held)|0x80000000)
+ #define H_ENUMERATE_ISSET_BAIL(held)  ((held)&amp;0x80000000)
+ #define H_ENUMERATE_ISSET_HELD(held)  ((held)&amp;0x7FFFFFFF)
+ 
  struct host *(hosttableptrs[h_MAXHOSTTABLES]);	/* Used by h_itoh */
  #define h_htoi(host) ((host)-&gt;index)	/* index isn't zeroed, no need to lock */
  #define h_itoh(hostindex) (hosttableptrs[(hostindex)&gt;&gt;h_HTSHIFT]+((hostindex)&amp;(h_HTSPERBLOCK-1)))
***************
*** 265,268 ****
  #define HFE_LATER                       0x80	/* host has FE_LATER callbacks */
  #define HERRORTRANS                    0x100	/* do error translation */
  
! 
--- 289,292 ----
  #define HFE_LATER                       0x80	/* host has FE_LATER callbacks */
  #define HERRORTRANS                    0x100	/* do error translation */
  
! #endif /* _AFS_VICED_HOST_H */
Index: openafs/src/viced/viced.c
diff -c openafs/src/viced/viced.c:1.69 openafs/src/viced/viced.c:1.75
*** openafs/src/viced/viced.c:1.69	Wed Feb  1 11:09:19 2006
--- openafs/src/viced/viced.c	Fri Mar 17 14:54:49 2006
***************
*** 5,10 ****
--- 5,12 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /*  viced.c	- File Server main loop					 */
***************
*** 20,26 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/viced.c,v 1.69 2006/02/01 16:09:19 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
--- 22,28 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/viced.c,v 1.75 2006/03/17 19:54:49 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
***************
*** 81,86 ****
--- 83,91 ----
  #include &lt;afs/vlserver.h&gt;
  #include &lt;afs/afsutil.h&gt;
  #include &lt;afs/fileutil.h&gt;
+ #include &lt;afs/ptuser.h&gt;
+ #include &lt;afs/audit.h&gt;
+ #include &lt;afs/partition.h&gt;
  #ifndef AFS_NT40_ENV
  #include &lt;afs/netutils.h&gt;
  #endif
***************
*** 113,122 ****
  extern int LogLevel, etext;
  extern afs_int32 BlocksSpare, PctSpare;
  
! void ShutDown(void);
  static void ClearXStatValues(), NewParms(), PrintCounters();
  static void ResetCheckDescriptors(void), ResetCheckSignal(void);
! static void CheckSignal(void);
  extern int GetKeysFromToken();
  extern int RXAFS_ExecuteRequest();
  extern int RXSTATS_ExecuteRequest();
--- 118,127 ----
  extern int LogLevel, etext;
  extern afs_int32 BlocksSpare, PctSpare;
  
! int ShutDown(void);
  static void ClearXStatValues(), NewParms(), PrintCounters();
  static void ResetCheckDescriptors(void), ResetCheckSignal(void);
! static int CheckSignal(void);
  extern int GetKeysFromToken();
  extern int RXAFS_ExecuteRequest();
  extern int RXSTATS_ExecuteRequest();
***************
*** 167,172 ****
--- 172,178 ----
  int debuglevel = 0;
  int printBanner = 0;
  int rxJumbograms = 1;		/* default is to send and receive jumbograms. */
+ int rxMaxMTU = -1;
  afs_int32 implicitAdminRights = PRSFS_LOOKUP;	/* The ADMINISTER right is 
  						 * already implied */
  afs_int32 readonlyServer = 0;
***************
*** 211,222 ****
  
  static void FlagMsg();
  
  /*
   * Home for the performance statistics.
   */
  
  /* DEBUG HACK */
! static void
  CheckDescriptors()
  {
  #ifndef AFS_NT40_ENV
--- 217,249 ----
  
  static void FlagMsg();
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * demand attach fs
+  * fileserver mode support
+  *
+  * during fileserver shutdown, we have to track the graceful shutdown of
+  * certain background threads before we are allowed to dump state to
+  * disk
+  */
+ struct fs_state fs_state = 
+     { FS_MODE_NORMAL, 
+       0, 
+       0, 
+       0, 
+       0,
+       { 1,1,1,1 },
+       PTHREAD_COND_INITIALIZER,
+       PTHREAD_RWLOCK_INITIALIZER
+     };
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  /*
   * Home for the performance statistics.
   */
  
  /* DEBUG HACK */
! static int
  CheckDescriptors()
  {
  #ifndef AFS_NT40_ENV
***************
*** 232,237 ****
--- 259,265 ----
      }
      fflush(stdout);
      ResetCheckDescriptors();
+     return 0;
  #endif
  }				/*CheckDescriptors */
  
***************
*** 336,343 ****
  	return 1;
      }
      code = afsconf_GetKey(confDir, akvno, tkey.key);
!     if (code)
  	return code;
      memcpy(akey, tkey.key, sizeof(tkey.key));
      return 0;
  
--- 364,373 ----
  	return 1;
      }
      code = afsconf_GetKey(confDir, akvno, tkey.key);
!     if (code) {
! 	ViceLog(0, ("afsconf_GetKey failure: kvno %d code %d\n", akvno, code));
  	return code;
+     }
      memcpy(akey, tkey.key, sizeof(tkey.key));
      return 0;
  
***************
*** 413,425 ****
--- 443,473 ----
  
      ViceLog(1, ("Starting five minute check process\n"));
      setThreadId("FiveMinuteCheckLWP");
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     FS_STATE_WRLOCK;
+     while (fs_state.mode == FS_MODE_NORMAL) {
+ 	fs_state.FiveMinuteLWP_tranquil = 1;
+ 	FS_STATE_UNLOCK;
+ #else
      while (1) {
+ #endif
+ 
  #ifdef AFS_PTHREAD_ENV
  	sleep(fiveminutes);
  #else /* AFS_PTHREAD_ENV */
  	IOMGR_Sleep(fiveminutes);
  #endif /* AFS_PTHREAD_ENV */
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	FS_STATE_WRLOCK;
+ 	if (fs_state.mode != FS_MODE_NORMAL) {
+ 	    break;
+ 	}
+ 	fs_state.FiveMinuteLWP_tranquil = 0;
+ 	FS_STATE_UNLOCK;
+ #endif
+ 
  	/* close the log so it can be removed */
  	ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);	/* don't trunc, just append */
  	ViceLog(2, ("Cleaning up timed out callbacks\n"));
***************
*** 445,451 ****
--- 493,509 ----
  			 afs_ctime(&amp;now, tbuffer, sizeof(tbuffer))));
  	    }
  	}
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	FS_STATE_WRLOCK;
+ #endif
      }
+ #ifdef AFS_DEMAND_ATTACH_FS
+     fs_state.FiveMinuteLWP_tranquil = 1;
+     FS_LOCK;
+     assert(pthread_cond_broadcast(&amp;fs_state.worker_done_cv)==0);
+     FS_UNLOCK;
+     FS_STATE_UNLOCK;
+ #endif
  }				/*FiveMinuteCheckLWP */
  
  
***************
*** 453,479 ****
   * other 5 minute activities because it may be delayed by timeouts when
   * it probes the workstations
   */
  static void
  HostCheckLWP()
  {
      ViceLog(1, ("Starting Host check process\n"));
      setThreadId("HostCheckLWP");
!     while (1) {
  #ifdef AFS_PTHREAD_ENV
  	sleep(fiveminutes);
  #else /* AFS_PTHREAD_ENV */
  	IOMGR_Sleep(fiveminutes);
  #endif /* AFS_PTHREAD_ENV */
  	ViceLog(2, ("Checking for dead venii &amp; clients\n"));
  	h_CheckHosts();
      }
  }				/*HostCheckLWP */
  
  /* This LWP does fsync checks every 5 minutes:  it should not be used for
   * other 5 minute activities because it may be delayed by timeouts when
   * it probes the workstations
   */
! static
  FsyncCheckLWP()
  {
      afs_int32 code;
--- 511,567 ----
   * other 5 minute activities because it may be delayed by timeouts when
   * it probes the workstations
   */
+ 
  static void
  HostCheckLWP()
  {
      ViceLog(1, ("Starting Host check process\n"));
      setThreadId("HostCheckLWP");
! #ifdef AFS_DEMAND_ATTACH_FS
!     FS_STATE_WRLOCK;
!     while (fs_state.mode == FS_MODE_NORMAL) {
! 	fs_state.HostCheckLWP_tranquil = 1;
! 	FS_STATE_UNLOCK;
! #else
!     while(1) {
! #endif
! 
  #ifdef AFS_PTHREAD_ENV
  	sleep(fiveminutes);
  #else /* AFS_PTHREAD_ENV */
  	IOMGR_Sleep(fiveminutes);
  #endif /* AFS_PTHREAD_ENV */
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	FS_STATE_WRLOCK;
+ 	if (fs_state.mode != FS_MODE_NORMAL) {
+ 	    break;
+ 	}
+ 	fs_state.HostCheckLWP_tranquil = 0;
+ 	FS_STATE_UNLOCK;
+ #endif
+ 
  	ViceLog(2, ("Checking for dead venii &amp; clients\n"));
  	h_CheckHosts();
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	FS_STATE_WRLOCK;
+ #endif
      }
+ #ifdef AFS_DEMAND_ATTACH_FS
+     fs_state.HostCheckLWP_tranquil = 1;
+     FS_LOCK;
+     assert(pthread_cond_broadcast(&amp;fs_state.worker_done_cv)==0);
+     FS_UNLOCK;
+     FS_STATE_UNLOCK;
+ #endif
  }				/*HostCheckLWP */
  
  /* This LWP does fsync checks every 5 minutes:  it should not be used for
   * other 5 minute activities because it may be delayed by timeouts when
   * it probes the workstations
   */
! static void
  FsyncCheckLWP()
  {
      afs_int32 code;
***************
*** 489,495 ****
      assert(pthread_mutex_init(&amp;fsync_glock_mutex, NULL) == 0);
  #endif
  
!     while (1) {
  	FSYNC_LOCK;
  #ifdef AFS_PTHREAD_ENV
  	/* rounding is fine */
--- 577,590 ----
      assert(pthread_mutex_init(&amp;fsync_glock_mutex, NULL) == 0);
  #endif
  
! #ifdef AFS_DEMAND_ATTACH_FS
!     FS_STATE_WRLOCK;
!     while (fs_state.mode == FS_MODE_NORMAL) {
! 	fs_state.FsyncCheckLWP_tranquil = 1;
! 	FS_STATE_UNLOCK;
! #else
!     while(1) {
! #endif
  	FSYNC_LOCK;
  #ifdef AFS_PTHREAD_ENV
  	/* rounding is fine */
***************
*** 506,516 ****
--- 601,631 ----
  	    ViceLog(0, ("LWP_WaitProcess returned %d\n", code));
  #endif /* AFS_PTHREAD_ENV */
  	FSYNC_UNLOCK;
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	FS_STATE_WRLOCK;
+ 	if (fs_state.mode != FS_MODE_NORMAL) {
+ 	    break;
+ 	}
+ 	fs_state.FsyncCheckLWP_tranquil = 0;
+ 	FS_STATE_UNLOCK;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  	ViceLog(2, ("Checking for fsync events\n"));
  	do {
  	    code = BreakLaterCallBacks();
  	} while (code != 0);
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	FS_STATE_WRLOCK;
+ #endif
      }
+ #ifdef AFS_DEMAND_ATTACH_FS
+     fs_state.FsyncCheckLWP_tranquil = 1;
+     FS_LOCK;
+     assert(pthread_cond_broadcast(&amp;fs_state.worker_done_cv)==0);
+     FS_UNLOCK;
+     FS_STATE_UNLOCK;
+ #endif /* AFS_DEMAND_ATTACH_FS */
  }
  
  /*------------------------------------------------------------------------
***************
*** 597,602 ****
--- 712,722 ----
  	    ("Vice was last started at %s\n",
  	     afs_ctime(&amp;StartTime, tbuffer, sizeof(tbuffer))));
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+     /* XXX perhaps set extended stats verbosity flags
+      * based upon LogLevel ?? */
+     VPrintExtendedCacheStats(VOL_STATS_PER_CHAIN2);
+ #endif
      VPrintCacheStats();
      VPrintDiskStats();
      DStat(&amp;dirbuff, &amp;dircall, &amp;dirio);
***************
*** 625,631 ****
  
  
  
! static void
  CheckSignal()
  {
      if (FS_registered &gt; 0) {
--- 745,751 ----
  
  
  
! static int
  CheckSignal()
  {
      if (FS_registered &gt; 0) {
***************
*** 640,646 ****
      DumpCallBackState();
      PrintCounters();
      ResetCheckSignal();
! 
  }				/*CheckSignal */
  
  void
--- 760,766 ----
      DumpCallBackState();
      PrintCounters();
      ResetCheckSignal();
!     return 0;
  }				/*CheckSignal */
  
  void
***************
*** 649,654 ****
--- 769,784 ----
      time_t now = time(0);
      char tbuffer[32];
  
+     /* do not allows new reqests to be served from now on, all new requests
+      * are returned with an error code of RX_RESTARTING ( transient failure ) */
+     rx_SetRxTranquil();		/* dhruba */
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     FS_STATE_WRLOCK;
+     fs_state.mode = FS_MODE_SHUTDOWN;
+     FS_STATE_UNLOCK;
+ #endif
+ 
      ViceLog(0,
  	    ("Shutting down file server at %s",
  	     afs_ctime(&amp;now, tbuffer, sizeof(tbuffer))));
***************
*** 664,674 ****
      if (!dopanic)
  	PrintCounters();
  
!     /* do not allows new reqests to be served from now on, all new requests
!      * are returned with an error code of RX_RESTARTING ( transient failure ) */
!     rx_SetRxTranquil();		/* dhruba */
      VShutdown();
  
      if (debugFile) {
  	rx_PrintStats(debugFile);
  	fflush(debugFile);
--- 794,827 ----
      if (!dopanic)
  	PrintCounters();
  
!     /* shut down volume package */
      VShutdown();
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+     if (fs_state.options.fs_state_save) {
+ 	/* 
+ 	 * demand attach fs
+ 	 * save fileserver state to disk */
+ 
+ 	/* make sure background threads have finished all of their asynchronous 
+ 	 * work on host and callback structures */
+ 	FS_STATE_RDLOCK;
+ 	while (!fs_state.FiveMinuteLWP_tranquil ||
+ 	       !fs_state.HostCheckLWP_tranquil ||
+ 	       !fs_state.FsyncCheckLWP_tranquil) {
+ 	    FS_LOCK;
+ 	    FS_STATE_UNLOCK;
+ 	    ViceLog(0, ("waiting for background host/callback threads to quiesce before saving fileserver state...\n"));
+ 	    assert(pthread_cond_wait(&amp;fs_state.worker_done_cv, &amp;fileproc_glock_mutex) == 0);
+ 	    FS_UNLOCK;
+ 	    FS_STATE_RDLOCK;
+ 	}
+ 
+ 	/* ok. it should now be fairly safe. let's do the state dump */
+ 	fs_stateSave();
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
      if (debugFile) {
  	rx_PrintStats(debugFile);
  	fflush(debugFile);
***************
*** 695,714 ****
      }
  
      exit(0);
  
! }				/*ShutDown */
! 
! void
  ShutDown(void)
  {				/* backward compatibility */
      ShutDownAndCore(DONTPANIC);
  }
  
  
  static void
  FlagMsg()
  {
!     char buffer[1024];
  
      /* default supports help flag */
  
--- 848,867 ----
      }
  
      exit(0);
+ }
  
! int
  ShutDown(void)
  {				/* backward compatibility */
      ShutDownAndCore(DONTPANIC);
+     return 0;
  }
  
  
  static void
  FlagMsg()
  {
!     char buffer[2048];
  
      /* default supports help flag */
  
***************
*** 735,742 ****
      strcat(buffer, "[-rxpck &lt;number of rx extra packets&gt;] ");
      strcat(buffer, "[-rxdbg (enable rx debugging)] ");
      strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
! #if AFS_PTHREAD_ENV
!     strcat(buffer, "[-vattachpar &lt;number of volume attach threads&gt;] ");
  #endif
  #ifdef	AFS_AIX32_ENV
      strcat(buffer, "[-m &lt;min percentage spare in partition&gt;] ");
--- 888,906 ----
      strcat(buffer, "[-rxpck &lt;number of rx extra packets&gt;] ");
      strcat(buffer, "[-rxdbg (enable rx debugging)] ");
      strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
!     strcat(buffer, "[-rxmaxmtu &lt;bytes&gt;] ");
! #ifdef AFS_DEMAND_ATTACH_FS
!     strcat(buffer, "[-fs-state-dont-save (disable state save during shutdown)] ");
!     strcat(buffer, "[-fs-state-dont-restore (disable state restore during startup)] ");
!     strcat(buffer, "[-fs-state-verify &lt;none|save|restore|both&gt; (default is both)] ");
!     strcat(buffer, "[-vattachpar &lt;max number of volume attach/shutdown threads&gt; (default is 1)] ");
!     strcat(buffer, "[-vhashsize &lt;log(2) of number of volume hash buckets&gt; (default is 8)] ");
!     strcat(buffer, "[-vlrudisable (disable VLRU functionality)] ");
!     strcat(buffer, "[-vlruthresh &lt;minutes before unused volumes become eligible for soft detach&gt; (default is 2 hours)] ");
!     strcat(buffer, "[-vlruinterval &lt;seconds between VLRU scans&gt; (default is 2 minutes)] ");
!     strcat(buffer, "[-vlrumax &lt;max volumes to soft detach in one VLRU scan&gt; (default is 8)] ");
! #elif AFS_PTHREAD_ENV
!     strcat(buffer, "[-vattachpar &lt;number of volume attach threads&gt; (default is 1)] ");
  #endif
  #ifdef	AFS_AIX32_ENV
      strcat(buffer, "[-m &lt;min percentage spare in partition&gt;] ");
***************
*** 937,947 ****
  #ifdef AFS_PTHREAD_ENV
  	} else if (!strcmp(argv[i], "-vattachpar")) {
              if ((i + 1) &gt;= argc) {
! 		fprintf(stderr, "missing argument for -vattachpar\n"); 
  		return -1; 
  	    }
  	    vol_attach_threads = atoi(argv[++i]);
  #endif /* AFS_PTHREAD_ENV */
  	} else if (!strcmp(argv[i], "-s")) {
  	    Sawsmall = 1;
              if ((i + 1) &gt;= argc) {
--- 1101,1162 ----
  #ifdef AFS_PTHREAD_ENV
  	} else if (!strcmp(argv[i], "-vattachpar")) {
              if ((i + 1) &gt;= argc) {
! 		fprintf(stderr, "missing argument for %s\n", argv[i]); 
  		return -1; 
  	    }
  	    vol_attach_threads = atoi(argv[++i]);
  #endif /* AFS_PTHREAD_ENV */
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	} else if (!strcmp(argv[i], "-fs-state-dont-save")) {
+ 	    fs_state.options.fs_state_save = 0;
+ 	} else if (!strcmp(argv[i], "-fs-state-dont-restore")) {
+ 	    fs_state.options.fs_state_restore = 0;
+ 	} else if (!strcmp(argv[i], "-fs-state-verify")) {
+             if ((i + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for %s\n", argv[i]); 
+ 		return -1; 
+ 	    }
+ 	    i++;
+ 	    if (!strcmp(argv[i], "none")) {
+ 		fs_state.options.fs_state_verify_before_save = 0;
+ 		fs_state.options.fs_state_verify_after_restore = 0;
+ 	    } else if (!strcmp(argv[i], "save")) {
+ 		fs_state.options.fs_state_verify_after_restore = 0;
+ 	    } else if (!strcmp(argv[i], "restore")) {
+ 		fs_state.options.fs_state_verify_before_save = 0;
+ 	    } else if (!strcmp(argv[i], "both")) {
+ 		/* default */
+ 	    } else {
+ 		fprintf(stderr, "invalid argument for %s\n", argv[i-1]);
+ 		return -1;
+ 	    }
+ 	} else if (!strcmp(argv[i], "-vhashsize")) {
+             if ((i + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for %s\n", argv[i]); 
+ 		return -1; 
+ 	    }
+ 	    VSetVolHashSize(atoi(argv[++i]));
+ 	} else if (!strcmp(argv[i], "-vlrudisable")) {
+ 	    VLRU_SetOptions(VLRU_SET_ENABLED, 0);
+ 	} else if (!strcmp(argv[i], "-vlruthresh")) {
+             if ((i + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for %s\n", argv[i]); 
+ 		return -1; 
+ 	    }
+ 	    VLRU_SetOptions(VLRU_SET_THRESH, 60*atoi(argv[++i]));
+ 	} else if (!strcmp(argv[i], "-vlruinterval")) {
+             if ((i + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for %s\n", argv[i]); 
+ 		return -1; 
+ 	    }
+ 	    VLRU_SetOptions(VLRU_SET_INTERVAL, atoi(argv[++i]));
+ 	} else if (!strcmp(argv[i], "-vlrumax")) {
+             if ((i + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for %s\n", argv[i]); 
+ 		return -1; 
+ 	    }
+ 	    VLRU_SetOptions(VLRU_SET_MAX, atoi(argv[++i]));
+ #endif /* AFS_DEMAND_ATTACH_FS */
  	} else if (!strcmp(argv[i], "-s")) {
  	    Sawsmall = 1;
              if ((i + 1) &gt;= argc) {
***************
*** 1051,1056 ****
--- 1266,1284 ----
  #endif
  	else if (!strcmp(argv[i], "-nojumbo")) {
  	    rxJumbograms = 0;
+ 	} else if (!strcmp(argv[i], "-rxmaxmtu")) {
+ 	    if ((i + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for -rxmaxmtu\n"); 
+ 		return -1; 
+ 	    }
+ 	    rxMaxMTU = atoi(argv[++i]);
+ 	    if ((rxMaxMTU &lt; RX_MIN_PACKET_SIZE) || 
+ 		(rxMaxMTU &gt; RX_MAX_PACKET_DATA_SIZE)) {
+ 		printf("rxMaxMTU %d%% invalid; must be between %d-%d\n",
+ 		       rxMaxMTU, RX_MIN_PACKET_SIZE, 
+ 		       RX_MAX_PACKET_DATA_SIZE);
+ 		return -1;
+ 	    }
  	} else if (!strcmp(argv[i], "-realm")) {
  	    extern char local_realms[AFS_NUM_LREALMS][AFS_REALM_SZ];
  	    extern int  num_lrealms;
***************
*** 1275,1281 ****
  afs_int32
  InitPR()
  {
!     register code;
  
      /*
       * If this fails, it's because something major is wrong, and is not
--- 1503,1509 ----
  afs_int32
  InitPR()
  {
!     int code;
  
      /*
       * If this fails, it's because something major is wrong, and is not
***************
*** 1323,1329 ****
  struct ubik_client *cstruct;
  
  afs_int32
! vl_Initialize(char *confDir)
  {
      afs_int32 code, scIndex = 0, i;
      struct afsconf_dir *tdir;
--- 1551,1557 ----
  struct ubik_client *cstruct;
  
  afs_int32
! vl_Initialize(const char *confDir)
  {
      afs_int32 code, scIndex = 0, i;
      struct afsconf_dir *tdir;
***************
*** 1551,1558 ****
  InitVL()
  {
      afs_int32 code;
-     extern int rxi_numNetAddrs;
-     extern afs_uint32 rxi_NetAddrs[];
  
      /*
       * If this fails, it's because something major is wrong, and is not
--- 1779,1784 ----
***************
*** 1801,1806 ****
--- 2027,2035 ----
  	/* Don't send and don't allow 3.4 clients to send jumbograms. */
  	rx_SetNoJumbo();
      }
+     if (rxMaxMTU != -1) {
+ 	rx_SetMaxMTU(rxMaxMTU);
+     }
      rx_GetIFInfo();
      rx_SetRxDeadTime(30);
      sc[0] = rxnull_NewServerSecurityObject();
***************
*** 1901,1906 ****
--- 2130,2144 ----
  	exit(1);
      }
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+     if (fs_state.options.fs_state_restore) {
+ 	/*
+ 	 * demand attach fs
+ 	 * restore fileserver state */
+ 	fs_stateRestore();
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
      /*
       * We are done calling fopen/fdopen. It is safe to use a large
       * of the file descriptor cache.
Index: openafs/src/viced/viced.h
diff -c openafs/src/viced/viced.h:1.7 openafs/src/viced/viced.h:1.8
*** openafs/src/viced/viced.h:1.7	Wed Feb  1 10:58:31 2006
--- openafs/src/viced/viced.h	Fri Mar 17 14:54:50 2006
***************
*** 5,10 ****
--- 5,12 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /*  file.h	- include file for the File Server			*/
***************
*** 20,25 ****
--- 22,30 ----
   * Start with clean version to sync test and dev trees.
   * */
  
+ #ifndef _AFS_VICED_VICED_H
+ #define _AFS_VICED_VICED_H
+ 
  #include &lt;afs/afssyscalls.h&gt;
  #include &lt;afs/afsutil.h&gt;
  #include "fs_stats.h"		/*Defs for xstat-based statistics */
***************
*** 46,63 ****
  } DirHandle;
  
  
- struct cbcounters {
-     int DeleteFiles;
-     int DeleteCallBacks;
-     int BreakCallBacks;
-     int AddCallBacks;
-     int GotSomeSpaces;
-     int DeleteAllCallBacks;
-     int nFEs, nCBs, nblks;
-     int CBsTimedOut;
-     int nbreakers;
-     int GSS1, GSS2, GSS3, GSS4, GSS5;
- };
  
  #define MAXCNTRS (AFS_HIGHEST_OPCODE+1)
  
--- 51,56 ----
***************
*** 219,221 ****
--- 212,257 ----
  #define FSYNC_LOCK
  #define FSYNC_UNLOCK
  #endif /* AFS_PTHREAD_ENV */
+ 
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * demand attach fs
+  * fileserver mode support
+  */
+ struct fs_state {
+     volatile int mode;
+     volatile byte FiveMinuteLWP_tranquil;      /* five minute check thread is shutdown or sleeping */
+     volatile byte HostCheckLWP_tranquil;       /* host check thread is shutdown or sleeping */
+     volatile byte FsyncCheckLWP_tranquil;      /* fsync check thread is shutdown or sleeping */
+     volatile byte salvsync_fatal_error;        /* fatal error with salvsync comm */
+ 
+     /* some command-line options we use in 
+      * various places
+      *
+      * these fields are immutable once we
+      * go multithreaded */
+     struct {
+ 	byte fs_state_save;
+ 	byte fs_state_restore;
+ 	byte fs_state_verify_before_save;
+ 	byte fs_state_verify_after_restore;
+     } options;
+ 
+     pthread_cond_t worker_done_cv;
+     pthread_rwlock_t state_lock;
+ };
+ 
+ extern struct fs_state fs_state;
+ 
+ /* this lock is defined to be directly above FS_LOCK in the locking hierarchy */
+ #define FS_STATE_RDLOCK  assert(pthread_rwlock_rdlock(&amp;fs_state.state_lock) == 0)
+ #define FS_STATE_WRLOCK  assert(pthread_rwlock_wrlock(&amp;fs_state.state_lock) == 0)
+ #define FS_STATE_UNLOCK  assert(pthread_rwlock_unlock(&amp;fs_state.state_lock) == 0)
+ 
+ #define FS_MODE_NORMAL    0
+ #define FS_MODE_SHUTDOWN  1
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ 
+ #endif /* _AFS_VICED_VICED_H */
Index: openafs/src/viced/viced_prototypes.h
diff -c openafs/src/viced/viced_prototypes.h:1.7 openafs/src/viced/viced_prototypes.h:1.8
*** openafs/src/viced/viced_prototypes.h:1.7	Sat Dec 17 17:17:30 2005
--- openafs/src/viced/viced_prototypes.h	Fri Mar 17 14:54:50 2006
***************
*** 1,4 ****
--- 1,27 ----
+ /*
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ #ifndef _AFS_VICED_VICED_PROTOTYPES_H
+ #define _AFS_VICED_VICED_PROTOTYPES_H
+ 
  extern int sendBufSize;
  afs_int32 sys_error_to_et(afs_int32 in);
  void init_sys_error_to_et(void);
+   
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * demand attach fs
+  * fileserver state serialization
+  */
+ extern int fs_stateSave(void);
+ extern int fs_stateRestore(void);
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  
+ #endif /* _AFS_VICED_VICED_PROTOTYPES_H */
Index: openafs/src/vlserver/vlclient.c
diff -c openafs/src/vlserver/vlclient.c:1.15 openafs/src/vlserver/vlclient.c:1.16
*** openafs/src/vlserver/vlclient.c:1.15	Sat Oct  9 21:39:15 2004
--- openafs/src/vlserver/vlclient.c	Tue Apr  4 16:51:20 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vlserver/vlclient.c,v 1.15 2004/10/10 01:39:15 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vlserver/vlclient.c,v 1.16 2006/04/04 20:51:20 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
***************
*** 1323,1330 ****
  {
      int i;
      char strg[30];
  
!     strncpy(strg, ctime((time_t *) &amp; stats-&gt;start_time), sizeof(strg));
      strg[strlen(strg) - 1] = 0;
      printf("Dynamic statistics stats (starting time: %s):\n", strg);
      printf("OpcodeName\t# Requests\t# Aborts\n");
--- 1323,1331 ----
  {
      int i;
      char strg[30];
+     time_t start_time = stats-&gt;start_time;
  
!     strncpy(strg, ctime(&amp;start_time), sizeof(strg));
      strg[strlen(strg) - 1] = 0;
      printf("Dynamic statistics stats (starting time: %s):\n", strg);
      printf("OpcodeName\t# Requests\t# Aborts\n");
Index: openafs/src/vlserver/vlserver.c
diff -c openafs/src/vlserver/vlserver.c:1.20 openafs/src/vlserver/vlserver.c:1.21
*** openafs/src/vlserver/vlserver.c:1.20	Wed Feb  1 11:09:20 2006
--- openafs/src/vlserver/vlserver.c	Tue Feb 21 23:07:40 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vlserver/vlserver.c,v 1.20 2006/02/01 16:09:20 shadow Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vlserver/vlserver.c,v 1.21 2006/02/22 04:07:40 jaltman Exp $");
  
  #include &lt;afs/stds.h&gt;
  #include &lt;sys/types.h&gt;
***************
*** 71,76 ****
--- 71,77 ----
  int LogLevel = 0;
  int smallMem = 0;
  int rxJumbograms = 1;		/* default is to send and receive jumbo grams */
+ int rxMaxMTU = -1;
  
  static void
  CheckSignal_Signal()
***************
*** 178,183 ****
--- 179,198 ----
  	} else if (strcmp(argv[index], "-nojumbo") == 0) {
  	    rxJumbograms = 0;
  
+ 	} else if (!strcmp(argv[i], "-rxmaxmtu")) {
+ 	    if ((i + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for -rxmaxmtu\n"); 
+ 		return -1; 
+ 	    }
+ 	    rxMaxMTU = atoi(argv[++i]);
+ 	    if ((rxMaxMTU &lt; RX_MIN_PACKET_SIZE) || 
+ 		(rxMaxMTU &gt; RX_MAX_PACKET_DATA_SIZE)) {
+ 		printf("rxMaxMTU %d% invalid; must be between %d-%d\n",
+ 		       rxMaxMTU, RX_MIN_PACKET_SIZE, 
+ 		       RX_MAX_PACKET_DATA_SIZE);
+ 		return -1;
+ 	    }
+ 
  	} else if (strcmp(argv[index], "-smallmem") == 0) {
  	    smallMem = 1;
  
***************
*** 230,241 ****
--- 245,258 ----
  	    /* support help flag */
  #ifndef AFS_NT40_ENV
  	    printf("Usage: vlserver [-p &lt;number of processes&gt;] [-nojumbo] "
+ 		   "[-rxmaxmtu &lt;bytes&gt;] "
  		   "[-auditlog &lt;log path&gt;] "
  		   "[-syslog[=FACILITY]] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-help]\n");
  #else
  	    printf("Usage: vlserver [-p &lt;number of processes&gt;] [-nojumbo] "
+ 		   "[-rxmaxmtu &lt;bytes&gt;] "
  		   "[-auditlog &lt;log path&gt;] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-help]\n");
***************
*** 323,328 ****
--- 340,348 ----
      if (!rxJumbograms) {
  	rx_SetNoJumbo();
      }
+     if (rxMaxMTU != -1) {
+ 	rx_SetMaxMTU(rxMaxMTU);
+     }
      rx_SetRxDeadTime(50);
  
      memset(HostAddress, 0, sizeof(HostAddress));
Index: openafs/src/vol/.cvsignore
diff -c openafs/src/vol/.cvsignore:1.2 openafs/src/vol/.cvsignore:1.3
*** openafs/src/vol/.cvsignore:1.2	Fri Oct  5 16:41:56 2001
--- openafs/src/vol/.cvsignore	Mon Mar 27 12:27:38 2006
***************
*** 4,6 ****
--- 4,7 ----
  volinfo
  gi
  fs_conv_sol26
+ fssync-debug
Index: openafs/src/vol/Makefile.in
diff -c openafs/src/vol/Makefile.in:1.20 openafs/src/vol/Makefile.in:1.22
*** openafs/src/vol/Makefile.in:1.20	Tue Nov  1 11:42:47 2005
--- openafs/src/vol/Makefile.in	Fri Mar 17 14:54:51 2006
***************
*** 16,37 ****
  	${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libdir.a \
  	${TOP_LIBDIR}/liblwp.a  ${TOP_LIBDIR}/libacl.a
  
! CFLAGS = ${COMMON_CFLAGS} -D${SYS_NAME} ${FSINCLUDES} ${XCFLAGS}
  
! PUBLICHEADERS=nfs.h vnode.h viceinode.h volume.h voldefs.h partition.h\
! 	fssync.h ihandle.h namei_ops.h
  
! VLIBOBJS=vnode.o volume.o vutil.o partition.o fssync.o purge.o \
! 	 clone.o nuke.o devname.o listinodes.o common.o ihandle.o \
! 	 namei_ops.o fstab.o
  
! OBJECTS=${VLIBOBJS} physio.o vol-salvage.o vol-info.o vol-dump.o vol-bless.o
  
  all: gi \
  	${TOP_LIBDIR}/vlib.a \
  	${TOP_LIBDIR}/libvlib.a \
  	salvager \
  	volinfo \
  	$(FS_CONV_OSF40D) \
  	$(XFS_SIZE_CHECK) \
  	$(FS_CONV_SOL26) \
--- 16,38 ----
  	${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libdir.a \
  	${TOP_LIBDIR}/liblwp.a  ${TOP_LIBDIR}/libacl.a
  
! CFLAGS = ${COMMON_CFLAGS} -D${SYS_NAME} ${FSINCLUDES} ${XCFLAGS} ${ARCHFLAGS} -DFSSYNC_BUILD_SERVER -DFSSYNC_BUILD_CLIENT
  
! PUBLICHEADERS=nfs.h vnode.h viceinode.h volume.h voldefs.h partition.h \
! 	fssync.h ihandle.h namei_ops.h salvsync.h daemon_com.h
  
! VLIBOBJS=vnode.o volume.o vutil.o partition.o fssync-server.o fssync-client.o \
! 	 clone.o nuke.o devname.o listinodes.o common.o ihandle.o purge.o \
! 	 namei_ops.o salvsync-server.o salvsync-client.o daemon_com.o
  
! OBJECTS=${VLIBOBJS} physio.o vol-salvage.o vol-info.o vol-dump.o vol-bless.o fssync-debug.o
  
  all: gi \
  	${TOP_LIBDIR}/vlib.a \
  	${TOP_LIBDIR}/libvlib.a \
  	salvager \
  	volinfo \
+ 	fssync-debug \
  	$(FS_CONV_OSF40D) \
  	$(XFS_SIZE_CHECK) \
  	$(FS_CONV_SOL26) \
***************
*** 42,47 ****
--- 43,50 ----
  	${TOP_INCDIR}/afs/voldefs.h \
  	${TOP_INCDIR}/afs/partition.h \
  	${TOP_INCDIR}/afs/fssync.h \
+ 	${TOP_INCDIR}/afs/salvsync.h \
+ 	${TOP_INCDIR}/afs/daemon_com.h \
  	${TOP_INCDIR}/afs/ihandle.h \
  	${TOP_INCDIR}/afs/namei_ops.h
  
***************
*** 53,58 ****
--- 56,62 ----
  	${DESTDIR}${libdir}/afs/libvlib.a \
  	${DESTDIR}${afssrvlibexecdir}/salvager \
  	${DESTDIR}${afssrvsbindir}/volinfo \
+ 	${DESTDIR}${afssrvsbindir}/fssync-debug \
  	$(install_FS_CONV_OSF40D) \
  	$(install_XFS_SIZE_CHECK) \
  	$(install_FS_CONV_SOL26) \
***************
*** 63,68 ****
--- 67,74 ----
  	${DESTDIR}${includedir}/afs/voldefs.h \
  	${DESTDIR}${includedir}/afs/partition.h \
  	${DESTDIR}${includedir}/afs/fssync.h \
+ 	${DESTDIR}${includedir}/afs/salvsync.h \
+ 	${DESTDIR}${includedir}/afs/daemon_com.h \
  	${DESTDIR}${includedir}/afs/ihandle.h \
  	${DESTDIR}${includedir}/afs/namei_ops.h
  
***************
*** 72,77 ****
--- 78,88 ----
  ${DEST}/root.server/usr/afs/bin/volinfo: volinfo
  	${INSTALL} -s $? $@
  
+ ${DEST}/root.server/usr/afs/bin/fssync-debug: fssync-debug
+ 	if test "@DEMAND_ATTACH@" = "no"; then \
+ 		${INSTALL} -s $? $@ ; \
+ 	fi
+ 
  ${DEST}/lib/afs/vlib.a: vlib.a
  	${INSTALL} $? $@
  
***************
*** 117,122 ****
--- 128,139 ----
  ${DEST}/include/afs/fssync.h: fssync.h
  	${INSTALL} $? $@
  
+ ${DEST}/include/afs/salvsync.h: salvsync.h
+ 	${INSTALL} $? $@
+ 
+ ${DEST}/include/afs/daemon_com.h: daemon_com.h
+ 	${INSTALL} $? $@
+ 
  ${DEST}/include/afs/ihandle.h: ihandle.h
  	${INSTALL} $? $@
  
***************
*** 129,134 ****
--- 146,153 ----
  ${OBJECTS}: ${PUBLICHEADERS} ${TOP_INCDIR}/lwp.h ${TOP_INCDIR}/lock.h ${TOP_INCDIR}/afs/afsint.h vutils.h salvage.h AFS_component_version_number.c
  
  vol-salvage.o vutil.o: volinodes.h
+ vol-salvage.o salvager.o: vol-salvage.h
+ vol-salvage.o: salvsync.h daemon_com.h
  
  vlib.a:	${VLIBOBJS} AFS_component_version_number.o
  	$(RM) -f $@
***************
*** 136,143 ****
  	$(RANLIB) $@
  
  # new salvager:  remove references to /vice by linking with novice.o
! salvager: vol-salvage.o physio.o vlib.a
! 	${CC} ${LDFLAGS} -o salvager vol-salvage.o physio.o ${LIBS} ${XLIBS}
  
  vol-salvage: vol-salvage.o
  vol-info: vol-info.o physio.o ihandle.o
--- 155,162 ----
  	$(RANLIB) $@
  
  # new salvager:  remove references to /vice by linking with novice.o
! salvager: vol-salvage.o physio.o vlib.a salvager.o ${LIBS}
! 	${CC} ${LDFLAGS} -o salvager vol-salvage.o physio.o salvager.o ${LIBS} ${XLIBS}
  
  vol-salvage: vol-salvage.o
  vol-info: vol-info.o physio.o ihandle.o
***************
*** 163,179 ****
  			${CC} ${LDFLAGS} -o gi gi.o ${TOP_LIBDIR}/libsys.a;; \
          esac
  
! volinfo: vol-info.o physio.o ihandle.o fstab.o ${LIBS}
  	${CC} ${CFLAGS} -o volinfo vol-info.o physio.o \
! 		ihandle.o fstab.o ${LIBS} ${XLIBS}
  
  vol-bless: vol-bless.o physio.o ihandle.o ${LIBS}
  	${CC} ${CFLAGS} -o vol-bless vol-bless.o physio.o ${LIBS} ${XLIBS}
  
! fs_conv_dux40D: fs_conv_411.o
  	${CC} ${CFLAGS} ${TOP_LIBDIR}/libcmd.a -o fs_conv_dux40D fs_conv_411.o  ${LIBS} ${XLIBS}
  
! fs_conv_sol26: fs_conv_411.o vlib.a 
  	${CC} ${CFLAGS} ${TOP_LIBDIR}/libcmd.a -o fs_conv_sol26 fs_conv_411.o  ${LIBS} ${XLIBS}
  
  fs_conv_411.o: fs_conv_411.c AFS_component_version_number.c
--- 182,201 ----
  			${CC} ${LDFLAGS} -o gi gi.o ${TOP_LIBDIR}/libsys.a;; \
          esac
  
! volinfo: vol-info.o physio.o ihandle.o ${LIBS}
  	${CC} ${CFLAGS} -o volinfo vol-info.o physio.o \
! 		ihandle.o ${LIBS} ${XLIBS}
! 
! fssync-debug: fssync-debug.o physio.o AFS_component_version_number.c ${LIBS}
! 	${CC} ${LDFLAGS} -o fssync-debug fssync-debug.o physio.o ${LIBS} ${XLIBS}
  
  vol-bless: vol-bless.o physio.o ihandle.o ${LIBS}
  	${CC} ${CFLAGS} -o vol-bless vol-bless.o physio.o ${LIBS} ${XLIBS}
  
! fs_conv_dux40D: fs_conv_411.o ${LIBS}
  	${CC} ${CFLAGS} ${TOP_LIBDIR}/libcmd.a -o fs_conv_dux40D fs_conv_411.o  ${LIBS} ${XLIBS}
  
! fs_conv_sol26: fs_conv_411.o ${LIBS}
  	${CC} ${CFLAGS} ${TOP_LIBDIR}/libcmd.a -o fs_conv_sol26 fs_conv_411.o  ${LIBS} ${XLIBS}
  
  fs_conv_411.o: fs_conv_411.c AFS_component_version_number.c
***************
*** 211,216 ****
--- 233,243 ----
  ${DESTDIR}${afssrvsbindir}/volinfo: volinfo
  	${INSTALL} -s $? $@
  
+ ${DESTDIR}${afssrvsbindir}/fssync-debug: fssync-debug
+ 	if test "@DEMAND_ATTACH@" = "no" ; then \
+ 		${INSTALL} -s $? $@ ; \
+ 	fi
+ 
  ${DESTDIR}${includedir}/afs/nfs.h: nfs.h
  	${INSTALL} $? $@
  
***************
*** 253,258 ****
--- 280,297 ----
  ${TOP_INCDIR}/afs/fssync.h: fssync.h
  	${INSTALL} $? $@
  
+ ${DESTDIR}${includedir}/afs/salvsync.h: salvsync.h
+ 	${INSTALL} $? $@
+ 
+ ${TOP_INCDIR}/afs/salvsync.h: salvsync.h
+ 	${INSTALL} $? $@
+ 
+ ${DESTDIR}${includedir}/afs/daemon_com.h: daemon_com.h
+ 	${INSTALL} $? $@
+ 
+ ${TOP_INCDIR}/afs/daemon_com.h: daemon_com.h
+ 	${INSTALL} $? $@
+ 
  ${DESTDIR}${includedir}/afs/ihandle.h: ihandle.h
  	${INSTALL} $? $@
  
***************
*** 265,275 ****
--- 304,327 ----
  ${TOP_INCDIR}/afs/namei_ops.h: namei_ops.h
  	${INSTALL} $? $@
  
+ ${DESTDIR}${includedir}/afs/salvage.h: salvage.h
+ 	${INSTALL} $? $@
+ 
+ ${TOP_INCDIR}/afs/salvage.h: salvage.h
+ 	${INSTALL} $? $@
+ 
+ ${DESTDIR}${includedir}/afs/vol-salvage.h: vol-salvage.h
+ 	${INSTALL} $? $@
+ 
+ ${TOP_INCDIR}/afs/vol-salvage.h: vol-salvage.h
+ 	${INSTALL} $? $@
+ 
  dest: \
  	${DEST}/lib/afs/vlib.a \
  	${DEST}/lib/afs/libvlib.a \
  	${DEST}/root.server/usr/afs/bin/salvager \
  	${DEST}/root.server/usr/afs/bin/volinfo \
+ 	${DEST}/root.server/usr/afs/bin/fssync-debug \
  	$(dest_FS_CONV_OSF40D) \
  	$(dest_XFS_SIZE_CHECK) \
  	$(dest_FS_CONV_SOL26) \
***************
*** 280,291 ****
  	${DEST}/include/afs/voldefs.h \
  	${DEST}/include/afs/partition.h \
  	${DEST}/include/afs/fssync.h \
  	${DEST}/include/afs/ihandle.h \
  	${DEST}/include/afs/namei_ops.h
  
  check-splint::
  	sh $(HELPER_SPLINT) $(CFLAGS) \
! 	    vnode.c volume.c vutil.c partition.c fssync.c purge.c \
  	    clone.c nuke.c devname.c listinodes.c common.c ihandle.c \
! 	    namei_ops.c \
! 	    physio.c vol-salvage.c vol-info.c vol-bless.c
--- 332,345 ----
  	${DEST}/include/afs/voldefs.h \
  	${DEST}/include/afs/partition.h \
  	${DEST}/include/afs/fssync.h \
+ 	${DEST}/include/afs/salvsync.h \
+ 	${DEST}/include/afs/daemon_com.h \
  	${DEST}/include/afs/ihandle.h \
  	${DEST}/include/afs/namei_ops.h
  
  check-splint::
  	sh $(HELPER_SPLINT) $(CFLAGS) \
! 	    vnode.c volume.c vutil.c partition.c fssync-server.c fssync-client.c \
  	    clone.c nuke.c devname.c listinodes.c common.c ihandle.c \
! 	    namei_ops.c salvsync-server.c salvsync-client.c daemon_com.c purge.c \
! 	    physio.c vol-salvage.c vol-info.c vol-bless.c fssync-debug.c
Index: openafs/src/vol/NTMakefile
diff -c openafs/src/vol/NTMakefile:1.7 openafs/src/vol/NTMakefile:1.9
*** openafs/src/vol/NTMakefile:1.7	Sun Nov 20 20:57:42 2005
--- openafs/src/vol/NTMakefile	Mon Mar 20 12:29:57 2006
***************
*** 5,10 ****
--- 5,12 ----
  # License.  For details, see the LICENSE file in the top-level source
  # directory or online at http://www.openafs.org/dl/license10.html
  
+ AFSDEV_AUXCDEFINES = -DFSSYNC_BUILD_SERVER -DFSSYNC_BUILD_CLIENT
+ 
  RELDIR=vol
  !INCLUDE ..\config\NTMakefile.$(SYS_NAME)
  !INCLUDE ..\config\NTMakefile.version
***************
*** 23,29 ****
  	$(INCFILEDIR)\afs\viceinode.h \
  	$(INCFILEDIR)\afs\vnode.h \
  	$(INCFILEDIR)\afs\volume.h \
! 	$(INCFILEDIR)\afs\voldefs.h
  
  
  
--- 25,32 ----
  	$(INCFILEDIR)\afs\viceinode.h \
  	$(INCFILEDIR)\afs\vnode.h \
  	$(INCFILEDIR)\afs\volume.h \
! 	$(INCFILEDIR)\afs\voldefs.h \
! 	$(INCFILEDIR)\afs\daemon_com.h
  
  
  
***************
*** 35,41 ****
  LIBOBJS =\
  	$(OUT)\common.obj \
  	$(OUT)\clone.obj \
! 	$(OUT)\fssync.obj \
  	$(OUT)\ntops.obj \
  	$(OUT)\nuke.obj \
  	$(OUT)\partition.obj \
--- 38,47 ----
  LIBOBJS =\
  	$(OUT)\common.obj \
  	$(OUT)\clone.obj \
! 	$(OUT)\fssync-client.obj \
! 	$(OUT)\fssync-server.obj \
! 	$(OUT)\fssync-debug.obj \
! 	$(OUT)\daemon_com.obj \
  	$(OUT)\ntops.obj \
  	$(OUT)\nuke.obj \
  	$(OUT)\partition.obj \
Index: openafs/src/vol/clone.c
diff -c openafs/src/vol/clone.c:1.18 openafs/src/vol/clone.c:1.19
*** openafs/src/vol/clone.c:1.18	Wed Aug 18 20:22:38 2004
--- openafs/src/vol/clone.c	Wed Apr 26 11:43:17 2006
***************
*** 19,25 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/clone.c,v 1.18 2004/08/19 00:22:38 kolya Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;stdio.h&gt;
--- 19,25 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/clone.c,v 1.19 2006/04/26 15:43:17 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;stdio.h&gt;
***************
*** 227,232 ****
--- 227,238 ----
      decRock.vol = V_parentId(rwvp);
  
      /* Read each vnode in the old volume's index file */
+     /* fsyncing the link count file for every inode has a severe 
+        performance penalty, therefore we turn it off temporarily.
+        This assumes we're the only one on that file/volume  -
+        in particular when we force the fsync later!
+     */
+     V_linkHandle(rwvp)-&gt;ih_flags|=IH_DELAY_SYNC;
      for (offset = vcp-&gt;diskSize;
  	 STREAM_READ(rwvnode, vcp-&gt;diskSize, 1, rwfile) == 1;
  	 offset += vcp-&gt;diskSize) {
***************
*** 345,350 ****
--- 351,362 ----
       * and shouldn't do the idecs.
       */
    error_exit:
+     /* Now take the fsync-bypass away again and force an fsync.
+        Again: assumes we're alone on this file, otherwise we need a lock!
+     */
+     V_linkHandle(rwvp)-&gt;ih_flags&amp;=~IH_DELAY_SYNC;
+     IH_CONDSYNC(V_linkHandle(rwvp));
+ 
      if (rwfile)
  	STREAM_CLOSE(rwfile);
      if (clfilein)
Index: openafs/src/vol/daemon_com.c
diff -c /dev/null openafs/src/vol/daemon_com.c:1.3
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/daemon_com.c	Tue Apr  4 20:34:17 2006
***************
*** 0 ****
--- 1,473 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  * localhost interprocess communication for servers
+  *
+  * currently handled by a localhost socket
+  * (yes, this needs to be replaced someday)
+  */
+ 
+ #ifndef _WIN32
+ #define FD_SETSIZE 65536
+ #endif
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/vol/daemon_com.c,v 1.3 2006/04/05 00:34:17 shadow Exp $");
+ 
+ #include &lt;sys/types.h&gt;
+ #include &lt;stdio.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;winsock2.h&gt;
+ #include &lt;time.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/socket.h&gt;
+ #include &lt;netinet/in.h&gt;
+ #include &lt;netdb.h&gt;
+ #include &lt;sys/time.h&gt;
+ #endif
+ #include &lt;errno.h&gt;
+ #include &lt;assert.h&gt;
+ #include &lt;signal.h&gt;
+ 
+ #ifdef HAVE_STRING_H
+ #include &lt;string.h&gt;
+ #else
+ #ifdef HAVE_STRINGS_H
+ #include &lt;strings.h&gt;
+ #endif
+ #endif
+ 
+ 
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include "nfs.h"
+ #include &lt;afs/errors.h&gt;
+ #include "daemon_com.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include &lt;afs/afssyscalls.h&gt;
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ #include &lt;rx/rx_queue.h&gt;
+ 
+ /*@printflike@*/ extern void Log(const char *format, ...);
+ 
+ #ifdef osi_Assert
+ #undef osi_Assert
+ #endif
+ #define osi_Assert(e) (void)(e)
+ 
+ int (*V_BreakVolumeCallbacks) ();
+ 
+ #define MAXHANDLERS	4	/* Up to 4 clients; must be at least 2, so that
+ 				 * move = dump+restore can run on single server */
+ 
+ #define MAX_BIND_TRIES	5	/* Number of times to retry socket bind */
+ 
+ static int getport(SYNC_client_state * state, struct sockaddr_in *addr);
+ static int SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response * res);
+ 
+ /* daemon com SYNC client interface */
+ 
+ int
+ SYNC_connect(SYNC_client_state * state)
+ {
+     struct sockaddr_in addr;
+     /* I can't believe the following is needed for localhost connections!! */
+     static time_t backoff[] =
+ 	{ 3, 3, 3, 5, 5, 5, 7, 15, 16, 24, 32, 40, 48, 0 };
+     time_t *timeout = &amp;backoff[0];
+ 
+     if (state-&gt;fd &gt;= 0) {
+ 	return 1;
+     }
+ 
+     for (;;) {
+ 	state-&gt;fd = getport(state, &amp;addr);
+ 	if (connect(state-&gt;fd, (struct sockaddr *)&amp;addr, sizeof(addr)) &gt;= 0)
+ 	    return 1;
+ 	if (!*timeout)
+ 	    break;
+ 	if (!(*timeout &amp; 1))
+ 	    Log("SYNC_connect temporary failure (will retry)\n");
+ 	SYNC_disconnect(state);
+ 	sleep(*timeout++);
+     }
+     perror("SYNC_connect failed (giving up!)");
+     return 0;
+ }
+ 
+ int
+ SYNC_disconnect(SYNC_client_state * state)
+ {
+ #ifdef AFS_NT40_ENV
+     closesocket(state-&gt;fd);
+ #else
+     close(state-&gt;fd);
+ #endif
+     state-&gt;fd = -1;
+     return 0;
+ }
+ 
+ afs_int32
+ SYNC_closeChannel(SYNC_client_state * state)
+ {
+     afs_int32 code;
+     SYNC_command com;
+     SYNC_response res;
+     SYNC_PROTO_BUF_DECL(ores);
+ 
+     if (state-&gt;fd == -1)
+ 	return SYNC_OK;
+ 
+     memset(&amp;com, 0, sizeof(com));
+     memset(&amp;res, 0, sizeof(res));
+ 
+     res.payload.len = SYNC_PROTO_MAX_LEN;
+     res.payload.buf = ores;
+ 
+     com.hdr.command = SYNC_COM_CHANNEL_CLOSE;
+     com.hdr.command_len = sizeof(SYNC_command_hdr);
+ 
+     /* in case the other end dropped, don't do any retries */
+     state-&gt;retry_limit = 0;
+     state-&gt;hard_timeout = 0;
+ 
+     code = SYNC_ask(state, &amp;com, &amp;res);
+ 
+     if (code == SYNC_OK) {
+ 	if (res.hdr.response != SYNC_OK) {
+ 	    Log("SYNC_closeChannel:  channel shutdown request denied; closing socket anyway\n");
+ 	} else if (!(res.hdr.flags &amp; SYNC_FLAG_CHANNEL_SHUTDOWN)) {
+ 	    Log("SYNC_closeChannel:  channel shutdown request mishandled by server\n");
+ 	}
+     } else {
+ 	Log("SYNC_closeChannel: channel communications problem");
+     }
+ 
+     SYNC_disconnect(state);
+ 
+     return code;
+ }
+ 
+ int
+ SYNC_reconnect(SYNC_client_state * state)
+ {
+     SYNC_disconnect(state);
+     return SYNC_connect(state);
+ }
+ 
+ /* private function to fill in the sockaddr struct for us */
+ static int
+ getport(SYNC_client_state * state, struct sockaddr_in *addr)
+ {
+     int sd;
+ 
+     memset(addr, 0, sizeof(*addr));
+     assert((sd = socket(AF_INET, SOCK_STREAM, 0)) &gt;= 0);
+ #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
+     addr-&gt;sin_len = sizeof(struct sockaddr_in);
+ #endif
+     addr-&gt;sin_addr.s_addr = htonl(0x7f000001);
+     addr-&gt;sin_family = AF_INET;	/* was localhost-&gt;h_addrtype */
+     addr-&gt;sin_port = htons(state-&gt;port);	/* XXXX htons not _really_ neccessary */
+ 
+     return sd;
+ }
+ 
+ afs_int32
+ SYNC_ask(SYNC_client_state * state, SYNC_command * com, SYNC_response * res)
+ {
+     int tries;
+     afs_uint32 now, timeout, code=SYNC_OK;
+ 
+     if (state-&gt;fatal_error) {
+ 	return SYNC_COM_ERROR;
+     }
+ 
+     if (state-&gt;fd == -1) {
+ 	SYNC_connect(state);
+     }
+ 
+     if (state-&gt;fd == -1) {
+ 	state-&gt;fatal_error = 1;
+ 	return SYNC_COM_ERROR;
+     }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     com-&gt;hdr.flags |= SYNC_FLAG_DAFS_EXTENSIONS;
+ #endif
+ 
+     now = FT_ApproxTime();
+     timeout = now + state-&gt;hard_timeout;
+     for (tries = 0; 
+ 	 (tries &lt;= state-&gt;retry_limit) &amp;&amp; (now &lt;= timeout);
+ 	 tries++, now = FT_ApproxTime()) {
+ 	code = SYNC_ask_internal(state, com, res);
+ 	if (code == SYNC_OK) {
+ 	    break;
+ 	} else if (code == SYNC_BAD_COMMAND) {
+ 	    Log("SYNC_ask: protocol mismatch; make sure fileserver, volserver, salvageserver and salvager are same version\n");
+ 	    break;
+ 	} else if (code == SYNC_COM_ERROR) {
+ 	    Log("SYNC_ask: protocol communications failure; attempting reconnect to server\n");
+ 	    SYNC_reconnect(state);
+ 	    /* try again */
+ 	} else {
+ 	    /* unknown (probably protocol-specific) response code, pass it up to the caller, and let them deal with it */
+ 	    break;
+ 	}
+     }
+ 
+     if (code == SYNC_COM_ERROR) {
+ 	Log("SYNC_ask: fatal protocol error; disabling sync protocol to server running on port %d until next server restart\n", 
+ 	    state-&gt;port);
+ 	state-&gt;fatal_error = 1;
+     }
+ 
+     return code;
+ }
+ 
+ static afs_int32
+ SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response * res)
+ {
+     int n;
+     SYNC_PROTO_BUF_DECL(buf);
+ #ifndef AFS_NT40_ENV
+     int iovcnt;
+     struct iovec iov[2];
+ #endif
+ 
+     if (state-&gt;fd == -1) {
+ 	Log("SYNC_ask:  invalid sync file descriptor\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ 
+     if (com-&gt;hdr.command_len &gt; SYNC_PROTO_MAX_LEN) {
+ 	Log("SYNC_ask:  internal SYNC buffer too small; please file a bug\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ 
+     com-&gt;hdr.proto_version = state-&gt;proto_version;
+ 
+     memcpy(buf, &amp;com-&gt;hdr, sizeof(com-&gt;hdr));
+     if (com-&gt;payload.len) {
+ 	memcpy(buf + sizeof(com-&gt;hdr), com-&gt;payload.buf, 
+ 	       com-&gt;hdr.command_len - sizeof(com-&gt;hdr));
+     }
+ 
+ #ifdef AFS_NT40_ENV
+     n = send(state-&gt;fd, buf, com-&gt;hdr.command_len, 0);
+     if (n != com-&gt;hdr.command_len) {
+ 	Log("SYNC_ask:  write failed\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ 
+     n = recv(state-&gt;fd, buf, SYNC_PROTO_MAX_LEN, 0);
+     if (n == 0 || (n &lt; 0 &amp;&amp; WSAEINTR != WSAGetLastError())) {
+ 	Log("SYNC_ask:  No response\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ #else /* !AFS_NT40_ENV */
+     n = write(state-&gt;fd, buf, com-&gt;hdr.command_len);
+     if (com-&gt;hdr.command_len != n) {
+ 	Log("SYNC_ask: write failed\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ 
+     /* receive the response */
+     iov[0].iov_base = (char *)&amp;res-&gt;hdr;
+     iov[0].iov_len = sizeof(res-&gt;hdr);
+     if (res-&gt;payload.len) {
+ 	iov[1].iov_base = (char *)res-&gt;payload.buf;
+ 	iov[1].iov_len = res-&gt;payload.len;
+ 	iovcnt = 2;
+     } else {
+ 	iovcnt = 1;
+     }
+     n = readv(state-&gt;fd, iov, iovcnt);
+     if (n == 0 || (n &lt; 0 &amp;&amp; errno != EINTR)) {
+ 	Log("SYNC_ask: No response\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ #endif /* !AFS_NT40_ENV */
+ 
+     res-&gt;recv_len = n;
+ 
+     if (n &lt; sizeof(res-&gt;hdr)) {
+ 	Log("SYNC_ask:  response too short\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ #ifdef AFS_NT40_ENV
+     memcpy(&amp;res-&gt;hdr, buf, sizeof(res-&gt;hdr));
+ #endif
+ 
+     if ((n - sizeof(res-&gt;hdr)) &gt; res-&gt;payload.len) {
+ 	Log("SYNC_ask:  response too long\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ #ifdef AFS_NT40_ENV
+     memcpy(res-&gt;payload.buf, buf + sizeof(res-&gt;hdr), n - sizeof(res-&gt;hdr));
+ #endif
+ 
+     if (res-&gt;hdr.response_len != n) {
+ 	Log("SYNC_ask:  length field in response inconsistent\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+     if (res-&gt;hdr.response == SYNC_DENIED) {
+ 	Log("SYNC_ask: negative response\n");
+     }
+ 
+   done:
+     return res-&gt;hdr.response;
+ }
+ 
+ 
+ /* 
+  * daemon com SYNC server-side interfaces 
+  */
+ 
+ /* get a command */
+ afs_int32
+ SYNC_getCom(int fd, SYNC_command * com)
+ {
+     int n;
+     afs_int32 code = SYNC_OK;
+ #ifdef AFS_NT40_ENV
+     SYNC_PROTO_BUF_DECL(buf);
+ #else
+     struct iovec iov[2];
+     int iovcnt;
+ #endif
+ 
+ #ifdef AFS_NT40_ENV
+     n = recv(fd, buf, SYNC_PROTO_MAX_LEN, 0);
+ 
+     if (n == 0 || (n &lt; 0 &amp;&amp; WSAEINTR != WSAGetLastError())) {
+ 	Log("SYNC_getCom:  error receiving command\n");
+ 	code = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ #else /* !AFS_NT40_ENV */
+     iov[0].iov_base = (char *)&amp;com-&gt;hdr;
+     iov[0].iov_len = sizeof(com-&gt;hdr);
+     if (com-&gt;payload.len) {
+ 	iov[1].iov_base = (char *)com-&gt;payload.buf;
+ 	iov[1].iov_len = com-&gt;payload.len;
+ 	iovcnt = 2;
+     } else {
+ 	iovcnt = 1;
+     }
+ 
+     n = readv(fd, iov, iovcnt);
+     if (n == 0 || (n &lt; 0 &amp;&amp; errno != EINTR)) {
+ 	Log("SYNC_getCom:  error receiving command\n");
+ 	code = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ #endif /* !AFS_NT40_ENV */
+ 
+     com-&gt;recv_len = n;
+ 
+     if (n &lt; sizeof(com-&gt;hdr)) {
+ 	Log("SYNC_getCom:  command too short\n");
+ 	code = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ #ifdef AFS_NT40_ENV
+     memcpy(&amp;com-&gt;hdr, buf, sizeof(com-&gt;hdr));
+ #endif
+ 
+     if ((n - sizeof(com-&gt;hdr)) &gt; com-&gt;payload.len) {
+ 	Log("SYNC_getCom:  command too long\n");
+ 	code = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ #ifdef AFS_NT40_ENV
+     memcpy(com-&gt;payload.buf, buf + sizeof(com-&gt;hdr), n - sizeof(com-&gt;hdr));
+ #endif
+ 
+  done:
+     return code;
+ }
+ 
+ /* put a response */
+ afs_int32
+ SYNC_putRes(int fd, SYNC_response * res)
+ {
+     int n;
+     afs_int32 code = SYNC_OK;
+     SYNC_PROTO_BUF_DECL(buf);
+ 
+     if (res-&gt;hdr.response_len &gt; (sizeof(res-&gt;hdr) + res-&gt;payload.len)) {
+ 	Log("SYNC_putRes:  response_len field in response header inconsistent\n");
+ 	code = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ 
+     if (res-&gt;hdr.response_len &gt; SYNC_PROTO_MAX_LEN) {
+ 	Log("SYNC_putRes:  internal SYNC buffer too small; please file a bug\n");
+ 	code = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     res-&gt;hdr.flags |= SYNC_FLAG_DAFS_EXTENSIONS;
+ #endif
+ 
+     memcpy(buf, &amp;res-&gt;hdr, sizeof(res-&gt;hdr));
+     if (res-&gt;payload.len) {
+ 	memcpy(buf + sizeof(res-&gt;hdr), res-&gt;payload.buf, 
+ 	       res-&gt;hdr.response_len - sizeof(res-&gt;hdr));
+     }
+ 
+ #ifdef AFS_NT40_ENV
+     n = send(fd, buf, res-&gt;hdr.response_len, 0);
+ #else /* !AFS_NT40_ENV */
+     n = write(fd, buf, res-&gt;hdr.response_len);
+ #endif /* !AFS_NT40_ENV */
+ 
+     if (res-&gt;hdr.response_len != n) {
+ 	Log("SYNC_putRes: write failed\n");
+ 	res-&gt;hdr.response = SYNC_COM_ERROR;
+ 	goto done;
+     }
+ 
+  done:
+     return code;
+ }
+ 
+ /* return 0 for legal (null-terminated) string,
+  * 1 for illegal (unterminated) string */
+ int
+ SYNC_verifyProtocolString(char * buf, size_t len)
+ {
+     int ret = 0;
+     size_t s_len;
+ 
+     s_len = afs_strnlen(buf, len);
+ 
+     return (s_len == len) ? 1 : 0;
+ }
Index: openafs/src/vol/daemon_com.h
diff -c /dev/null openafs/src/vol/daemon_com.h:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/daemon_com.h	Fri Mar 17 23:20:18 2006
***************
*** 0 ****
--- 1,141 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ #ifndef _AFS_VOL_DAEMON_COM_H
+ #define _AFS_VOL_DAEMON_COM_H
+ 
+ /* 
+  * SYNC protocol constants
+  */
+ 
+ /* SYNC protocol command codes
+  *
+  * command codes 0-65535 are reserved for
+  * global SYNC package command codes
+  */
+ #define SYNC_COM_CODE_USER_BASE 65536
+ #define SYNC_COM_CODE_DECL(code) (SYNC_COM_CODE_USER_BASE+(code))
+ 
+ /* general command codes */
+ #define SYNC_COM_CHANNEL_CLOSE 0
+ 
+ 
+ /* SYNC protocol response codes
+  *
+  * response codes 0-65535 are reserved for 
+  * global SYNC package response codes
+  */
+ #define SYNC_RES_CODE_USER_BASE 65536
+ #define SYNC_RES_CODE_DECL(code) (SYNC_RES_CODE_USER_BASE+(code))
+ 
+ /* general response codes */
+ #define SYNC_OK                0   /* sync call returned ok */
+ #define SYNC_DENIED            1   /* sync request denied by server */
+ #define SYNC_COM_ERROR         2   /* sync protocol communicaions error */
+ #define SYNC_BAD_COMMAND       3   /* sync command code not implemented by server */
+ #define SYNC_FAILED            4   /* sync server-side procedure failed */
+ 
+ 
+ /* SYNC protocol reason codes
+  *
+  * reason codes 0-65535 are reserved for
+  * global SYNC package reason codes
+  */
+ #define SYNC_REASON_CODE_USER_BASE 65536
+ #define SYNC_REASON_CODE_DECL(code) (SYNC_REASON_CODE_USER_BASE+(code))
+ 
+ /* general reason codes */
+ #define SYNC_REASON_NONE                 0
+ #define SYNC_REASON_MALFORMED_PACKET     1
+ 
+ 
+ /* SYNC protocol flags
+  *
+  * flag bits 0-7 are reserved for
+  * global SYNC package flags
+  */
+ #define SYNC_FLAG_CODE_USER_BASE 8
+ #define SYNC_FLAG_CODE_DECL(code) (1 &lt;&lt; (SYNC_FLAG_CODE_USER_BASE+(code)))
+ 
+ /* general flag codes */
+ #define SYNC_FLAG_CHANNEL_SHUTDOWN   0x1
+ #define SYNC_FLAG_DAFS_EXTENSIONS    0x2   /* signal that other end of socket is compiled
+ 					    * with demand attach extensions */
+ 
+ /* SYNC protocol response buffers */
+ #define SYNC_PROTO_MAX_LEN     768  /* maximum size of sync protocol message */
+ 
+ /* use a large type to get proper buffer alignment so we can safely cast the pointer */
+ #define SYNC_PROTO_BUF_DECL(buf) \
+     afs_int64 _##buf##_l[SYNC_PROTO_MAX_LEN/sizeof(afs_int64)]; \
+     char * buf = (char *)(_##buf##_l)
+ 
+ 
+ /* client-side state object */
+ typedef struct SYNC_client_state {
+     int fd;
+     afs_uint16 port;
+     afs_uint32 proto_version;
+     int retry_limit;            /* max number of times for SYNC_ask to retry */
+     afs_int32 hard_timeout;     /* upper limit on time to keep trying */
+     byte fatal_error;           /* fatal error on this client conn */
+ } SYNC_client_state;
+ 
+ /* wire types */
+ typedef struct SYNC_command_hdr {
+     afs_uint32 proto_version;   /* sync protocol version */
+     afs_int32 programType;      /* type of program issuing the request */
+     afs_int32 command;          /* request type */
+     afs_int32 reason;           /* reason for request */
+     afs_uint32 command_len;     /* entire length of command */
+     afs_uint32 flags;
+ } SYNC_command_hdr;
+ 
+ typedef struct SYNC_response_hdr {
+     afs_uint32 proto_version;    /* sync protocol version */
+     afs_uint32 response_len;    /* entire length of response */
+     afs_int32 response;         /* response code */
+     afs_int32 reason;           /* reason for response */
+     afs_uint32 flags;
+ } SYNC_response_hdr;
+ 
+ 
+ /* user-visible types */
+ typedef struct SYNC_command {
+     SYNC_command_hdr hdr;
+     struct {
+ 	afs_uint32 len;
+ 	void * buf;
+     } payload;
+     afs_int32 recv_len;
+ } SYNC_command;
+ 
+ typedef struct SYNC_response {
+     SYNC_response_hdr hdr;
+     struct {
+ 	afs_uint32 len;
+ 	void * buf;
+     } payload;
+     afs_int32 recv_len;
+ } SYNC_response;
+ 
+ 
+ /* client-side prototypes */
+ extern afs_int32 SYNC_ask(SYNC_client_state *, SYNC_command * com, SYNC_response * res);
+ extern int SYNC_connect(SYNC_client_state *);             /* setup the channel */
+ extern int SYNC_disconnect(SYNC_client_state *);          /* just close the socket */
+ extern afs_int32 SYNC_closeChannel(SYNC_client_state *);  /* do a graceful channel close */
+ extern int SYNC_reconnect(SYNC_client_state *);           /* do a reconnect after a protocol error, or from a forked child */
+ 
+ /* server-side prototypes */
+ extern int SYNC_getCom(int fd, SYNC_command * com);
+ extern int SYNC_putRes(int fd, SYNC_response * res);
+ extern int SYNC_verifyProtocolString(char * buf, size_t len);
+ 
+ #endif /* _AFS_VOL_DAEMON_COM_H */
Index: openafs/src/vol/fssync-client.c
diff -c /dev/null openafs/src/vol/fssync-client.c:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/fssync-client.c	Fri Mar 17 23:20:18 2006
***************
*** 0 ****
--- 1,222 ----
+ /*
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
+  */
+ 
+ /*
+ 	System:		VICE-TWO
+ 	Module:		fssync.c
+ 	Institution:	The Information Technology Center, Carnegie-Mellon University
+ 
+  */
+ #ifdef notdef
+ 
+ /* All this is going away in early 1989 */
+ int newVLDB;			/* Compatibility flag */
+ 
+ #endif
+ static int newVLDB = 1;
+ 
+ 
+ #ifndef AFS_PTHREAD_ENV
+ #define USUAL_PRIORITY (LWP_MAX_PRIORITY - 2)
+ 
+ /*
+  * stack size increased from 8K because the HP machine seemed to have trouble
+  * with the smaller stack
+  */
+ #define USUAL_STACK_SIZE	(24 * 1024)
+ #endif /* !AFS_PTHREAD_ENV */
+ 
+ /*
+    fssync-client.c
+    File server synchronization with external volume utilities.
+    client-side implementation
+  */
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/vol/fssync-client.c,v 1.1 2006/03/18 04:20:18 shadow Exp $");
+ 
+ #include &lt;sys/types.h&gt;
+ #include &lt;stdio.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;winsock2.h&gt;
+ #include &lt;time.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/socket.h&gt;
+ #include &lt;netinet/in.h&gt;
+ #include &lt;netdb.h&gt;
+ #include &lt;sys/time.h&gt;
+ #endif
+ #include &lt;errno.h&gt;
+ #ifdef AFS_PTHREAD_ENV
+ #include &lt;assert.h&gt;
+ #else /* AFS_PTHREAD_ENV */
+ #include &lt;afs/assert.h&gt;
+ #endif /* AFS_PTHREAD_ENV */
+ #include &lt;signal.h&gt;
+ 
+ #ifdef HAVE_STRING_H
+ #include &lt;string.h&gt;
+ #else
+ #ifdef HAVE_STRINGS_H
+ #include &lt;strings.h&gt;
+ #endif
+ #endif
+ 
+ 
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include "nfs.h"
+ #include &lt;afs/errors.h&gt;
+ #include "daemon_com.h"
+ #include "fssync.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include &lt;afs/afssyscalls.h&gt;
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ 
+ #ifdef FSSYNC_BUILD_CLIENT
+ 
+ /*@printflike@*/ extern void Log(const char *format, ...);
+ 
+ #ifdef osi_Assert
+ #undef osi_Assert
+ #endif
+ #define osi_Assert(e) (void)(e)
+ 
+ extern int LogLevel;
+ 
+ static SYNC_client_state fssync_state = { -1, 2040, FSYNC_PROTO_VERSION, 5, 120 };
+ 
+ #ifdef AFS_PTHREAD_ENV
+ static pthread_mutex_t vol_fsync_mutex;
+ static volatile vol_fsync_mutex_init = 0;
+ #define VFSYNC_LOCK \
+     assert(pthread_mutex_lock(&amp;vol_fsync_mutex) == 0)
+ #define VFSYNC_UNLOCK \
+     assert(pthread_mutex_unlock(&amp;vol_fsync_mutex) == 0)
+ #else
+ #define VFSYNC_LOCK
+ #define VFSYNC_UNLOCK
+ #endif
+ 
+ int
+ FSYNC_clientInit(void)
+ {
+ #ifdef AFS_PTHREAD_ENV
+     /* this is safe since it gets called with VOL_LOCK held, or before we go multithreaded */
+     if (!vol_fsync_mutex_init) {
+ 	assert(pthread_mutex_init(&amp;vol_fsync_mutex, NULL) == 0);
+ 	vol_fsync_mutex_init = 1;
+     }
+ #endif
+     return SYNC_connect(&amp;fssync_state);
+ }
+ 
+ void
+ FSYNC_clientFinis(void)
+ {
+     SYNC_closeChannel(&amp;fssync_state);
+ }
+ 
+ int
+ FSYNC_clientChildProcReconnect(void)
+ {
+     return SYNC_reconnect(&amp;fssync_state);
+ }
+ 
+ /* fsync client interface */
+ afs_int32
+ FSYNC_askfs(SYNC_command * com, SYNC_response * res)
+ {
+     afs_int32 code;
+ 
+     VFSYNC_LOCK;
+     code = SYNC_ask(&amp;fssync_state, com, res);
+     VFSYNC_UNLOCK;
+ 
+     switch (code) {
+     case SYNC_OK:
+     case SYNC_FAILED:
+ 	break;
+     case SYNC_COM_ERROR:
+     case SYNC_BAD_COMMAND:
+ 	Log("FSYNC_askfs: fatal FSSYNC protocol error; volume management functionality disabled until next fileserver restart\n");
+ 	break;
+     case SYNC_DENIED:
+ 	Log("FSYNC_askfs: FSSYNC request denied for reason=%d\n", res-&gt;hdr.reason);
+ 	break;
+     default:
+ 	Log("FSYNC_askfs: unknown protocol response %d\n", code);
+ 	break;
+     }
+     return code;
+ }
+ 
+ afs_int32
+ FSYNC_GenericOp(void * ext_hdr, size_t ext_len,
+ 	      int command, int reason,
+ 	      SYNC_response * res_in)
+ {
+     SYNC_response res_l, *res;
+     SYNC_command com;
+ 
+     if (res_in) {
+ 	res = res_in;
+     } else {
+ 	res = &amp;res_l;
+ 	res_l.payload.buf = NULL;
+ 	res_l.payload.len = 0;
+     }
+ 
+     memset(&amp;com, 0, sizeof(com));
+ 
+     com.hdr.programType = programType;
+     com.hdr.command = command;
+     com.hdr.reason = reason;
+     com.hdr.command_len = sizeof(com.hdr) + ext_len;
+     com.payload.buf = ext_hdr;
+     com.payload.len = ext_len;
+ 
+     return FSYNC_askfs(&amp;com, res);
+ }
+ 
+ afs_int32
+ FSYNC_VolOp(VolumeId volume, char * partition, 
+ 	    int command, int reason,
+ 	    SYNC_response * res)
+ {
+     FSSYNC_VolOp_hdr vcom;
+ 
+     memset(&amp;vcom, 0, sizeof(vcom));
+ 
+     vcom.volume = volume;
+     if (partition)
+ 	strlcpy(vcom.partName, partition, sizeof(vcom.partName));
+ 
+     return FSYNC_GenericOp(&amp;vcom, sizeof(vcom), command, reason, res);
+ }
+ 
+ afs_int32
+ FSYNC_StatsOp(FSSYNC_StatsOp_hdr * scom, int command, int reason,
+ 	      SYNC_response * res)
+ {
+     return FSYNC_GenericOp(scom, sizeof(*scom), command, reason, res);
+ }
+ 
+ 
+ #endif /* FSSYNC_BUILD_CLIENT */
Index: openafs/src/vol/fssync-debug.c
diff -c /dev/null openafs/src/vol/fssync-debug.c:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/fssync-debug.c	Fri Mar 17 23:20:19 2006
***************
*** 0 ****
--- 1,1148 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /* Main program file. Define globals. */
+ #define MAIN 1
+ 
+ /*
+  * fssync administration tool
+  */
+ 
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/vol/fssync-debug.c,v 1.1 2006/03/18 04:20:19 shadow Exp $");
+ 
+ #include &lt;stdlib.h&gt;
+ #include &lt;stdio.h&gt;
+ #include &lt;string.h&gt;
+ #include &lt;dirent.h&gt;
+ #include &lt;sys/stat.h&gt;
+ #include &lt;time.h&gt;
+ #include &lt;errno.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;io.h&gt;
+ #include &lt;WINNT/afsevent.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/file.h&gt;
+ #ifndef ITIMER_REAL
+ #include &lt;sys/time.h&gt;
+ #endif /* ITIMER_REAL */
+ #endif
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include &lt;afs/assert.h&gt;
+ 
+ 
+ #include &lt;fcntl.h&gt;
+ 
+ #ifndef AFS_NT40_ENV
+ #include &lt;afs/osi_inode.h&gt;
+ #endif
+ 
+ #include &lt;afs/cmd.h&gt;
+ #include &lt;afs/afsutil.h&gt;
+ #include &lt;afs/fileutil.h&gt;
+ 
+ #include "nfs.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ #include "daemon_com.h"
+ #include "fssync.h"
+ #ifdef AFS_NT40_ENV
+ #include &lt;pthread.h&gt;
+ #endif
+ 
+ int VolumeChanged; /* hack to make dir package happy */
+ 
+ 
+ struct volop_state {
+     afs_uint32 volume;
+     char partName[16];
+ };
+ 
+ struct state {
+     afs_int32 reason;
+     struct volop_state * vop;
+ };
+ 
+ static int common_prolog(struct cmd_syndesc *, struct state *);
+ static int common_volop_prolog(struct cmd_syndesc *, struct state *);
+ 
+ static int do_volop(struct state *, afs_int32 command, SYNC_response * res);
+ 
+ static char * response_code_to_string(afs_int32);
+ static char * command_code_to_string(afs_int32);
+ static char * reason_code_to_string(afs_int32);
+ static char * program_type_to_string(afs_int32);
+ 
+ static int VolOnline(struct cmd_syndesc * as, char * rock);
+ static int VolOffline(struct cmd_syndesc * as, char * rock);
+ static int VolMode(struct cmd_syndesc * as, char * rock);
+ static int VolDetach(struct cmd_syndesc * as, char * rock);
+ static int VolBreakCBKs(struct cmd_syndesc * as, char * rock);
+ static int VolMove(struct cmd_syndesc * as, char * rock);
+ static int VolList(struct cmd_syndesc * as, char * rock);
+ static int VolQuery(struct cmd_syndesc * as, char * rock);
+ static int VolHdrQuery(struct cmd_syndesc * as, char * rock);
+ static int VolOpQuery(struct cmd_syndesc * as, char * rock);
+ static int StatsQuery(struct cmd_syndesc * as, char * rock);
+ 
+ 
+ static void print_vol_stats_general(VolPkgStats * stats);
+ static void print_vol_stats_viceP(struct DiskPartitionStats * stats);
+ static void print_vol_stats_hash(struct VolumeHashChainStats * stats);
+ #ifdef AFS_DEMAND_ATTACH_FS
+ static void print_vol_stats_hdr(struct volume_hdr_LRU_stats * stats);
+ #endif
+ 
+ #ifndef AFS_NT40_ENV
+ #include "AFS_component_version_number.c"
+ #endif
+ #define MAX_ARGS 128
+ 
+ #define COMMON_PARMS_OFFSET    12
+ #define COMMON_PARMS(ts) \
+     cmd_Seek(ts, COMMON_PARMS_OFFSET); \
+     cmd_AddParm(ts, "-reason", CMD_SINGLE, CMD_OPTIONAL, "sync protocol reason code"); \
+     cmd_AddParm(ts, "-programtype", CMD_SINGLE, CMD_OPTIONAL, "program type code")
+ 
+ #define COMMON_VOLOP_PARMS_OFFSET    10
+ #define COMMON_VOLOP_PARMS(ts) \
+     cmd_Seek(ts, COMMON_VOLOP_PARMS_OFFSET); \
+     cmd_AddParm(ts, "-volumeid", CMD_SINGLE, 0, "volume id"); \
+     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name")
+ 
+ #define CUSTOM_PARMS_OFFSET 1
+ 
+ 
+ #define VOLOP_PARMS_DECL(ts) \
+     COMMON_VOLOP_PARMS(ts); \
+     COMMON_PARMS(ts)
+ #define COMMON_PARMS_DECL(ts) \
+     COMMON_PARMS(ts)
+ 
+ int
+ main(int argc, char **argv)
+ {
+     struct cmd_syndesc *ts;
+     int err = 0;
+     int i;
+     extern char cml_version_number[];
+ 
+     /* Initialize directory paths */
+     if (!(initAFSDirPath() &amp; AFSDIR_SERVER_PATHS_OK)) {
+ #ifdef AFS_NT40_ENV
+ 	ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
+ #endif
+ 	fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
+ 		argv[0]);
+ 	exit(2);
+     }
+ 
+     
+     ts = cmd_CreateSyntax("online", VolOnline, 0, "bring a volume online (FSYNC_VOL_ON opcode)");
+     VOLOP_PARMS_DECL(ts);
+ 
+     ts = cmd_CreateSyntax("offline", VolOffline, 0, "take a volume offline (FSYNC_VOL_OFF opcode)");
+     VOLOP_PARMS_DECL(ts);
+ 
+     ts = cmd_CreateSyntax("mode", VolMode, 0, "change volume attach mode (FSYNC_VOL_NEEDVOLUME opcode)");
+     VOLOP_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "needvolume");
+ 
+     ts = cmd_CreateSyntax("detach", VolDetach, 0, "detach a volume (FSYNC_VOL_DONE opcode)");
+     VOLOP_PARMS_DECL(ts);
+ 
+     ts = cmd_CreateSyntax("callback", VolBreakCBKs, 0, "break callbacks for volume (FSYNC_VOL_BREAKCBKS opcode)");
+     VOLOP_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "cbk");
+ 
+     ts = cmd_CreateSyntax("move", VolMove, 0, "set volume moved flag (FSYNC_VOL_MOVE opcode)");
+     VOLOP_PARMS_DECL(ts);
+ 
+     ts = cmd_CreateSyntax("list", VolList, 0, "sync local volume list (FSYNC_VOL_LISTVOLUMES opcode)");
+     VOLOP_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "ls");
+ 
+     ts = cmd_CreateSyntax("query", VolQuery, 0, "get volume structure (FSYNC_VOL_QUERY opcode)");
+     VOLOP_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "qry");
+ 
+     ts = cmd_CreateSyntax("header", VolHdrQuery, 0, "get volume disk data structure (FSYNC_VOL_QUERY_HDR opcode)");
+     VOLOP_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "hdr");
+ 
+     ts = cmd_CreateSyntax("volop", VolOpQuery, 0, "get pending volume operation info (FSYNC_VOL_QUERY_VOP opcode)");
+     VOLOP_PARMS_DECL(ts);
+     cmd_CreateAlias(ts, "vop");
+ 
+     ts = cmd_CreateSyntax("stats", StatsQuery, 0, "see 'stats help' for more information");
+     cmd_Seek(ts, CUSTOM_PARMS_OFFSET);
+     cmd_AddParm(ts, "-cmd", CMD_SINGLE, 0, "subcommand");
+     cmd_AddParm(ts, "-arg1", CMD_SINGLE, CMD_OPTIONAL, "arg1");
+     cmd_AddParm(ts, "-arg2", CMD_SINGLE, CMD_OPTIONAL, "arg2");
+     COMMON_PARMS_DECL(ts);
+ 
+     err = cmd_Dispatch(argc, argv);
+     exit(err);
+ }
+ 
+ static int
+ common_prolog(struct cmd_syndesc * as, struct state * state)
+ {
+     register struct cmd_item *ti;
+ 
+ #ifdef AFS_NT40_ENV
+     if (afs_winsockInit() &lt; 0) {
+ 	Exit(1);
+     }
+ #endif
+ 
+     VInitVolumePackage(debugUtility, 1, 1,
+ 		       DONT_CONNECT_FS, 0);
+     DInit(1);
+ 
+     if ((ti = as-&gt;parms[COMMON_PARMS_OFFSET].items)) {	/* -reason */
+ 	state-&gt;reason = atoi(ti-&gt;data);
+     }
+     if ((ti = as-&gt;parms[COMMON_PARMS_OFFSET+1].items)) {	/* -programtype */
+ 	if (!strcmp(ti-&gt;data, "fileServer")) {
+ 	    programType = fileServer;
+ 	} else if (!strcmp(ti-&gt;data, "volumeUtility")) {
+ 	    programType = volumeUtility;
+ 	} else if (!strcmp(ti-&gt;data, "salvager")) {
+ 	    programType = salvager;
+ 	} else if (!strcmp(ti-&gt;data, "salvageServer")) {
+ 	    programType = salvageServer;
+ 	} else {
+ 	    programType = (ProgramType) atoi(ti-&gt;data);
+ 	}
+     }
+ 
+     VConnectFS();
+ 
+     return 0;
+ }
+ 
+ static int
+ common_volop_prolog(struct cmd_syndesc * as, struct state * state)
+ {
+     register struct cmd_item *ti;
+     char pname[100], *temp;
+ 
+     state-&gt;vop = (struct volop_state *) calloc(1, sizeof(struct volop_state));
+     assert(state-&gt;vop != NULL);
+ 
+     if ((ti = as-&gt;parms[COMMON_VOLOP_PARMS_OFFSET].items)) {	/* -volumeid */
+ 	state-&gt;vop-&gt;volume = atoi(ti-&gt;data);
+     } else {
+ 	fprintf(stderr, "required argument -volumeid not given\n");
+     }
+ 
+     if ((ti = as-&gt;parms[COMMON_VOLOP_PARMS_OFFSET+1].items)) {	/* -partition */
+ 	strlcpy(state-&gt;vop-&gt;partName, ti-&gt;data, sizeof(state-&gt;vop-&gt;partName));
+     } else {
+ 	memset(state-&gt;vop-&gt;partName, 0, sizeof(state-&gt;vop-&gt;partName));
+     }
+ 
+     return 0;
+ }
+ 
+ static int
+ do_volop(struct state * state, afs_int32 command, SYNC_response * res)
+ {
+     afs_int32 code;
+     SYNC_PROTO_BUF_DECL(res_buf);
+     SYNC_response res_l;
+ 
+     if (!res) {
+ 	res = &amp;res_l;
+ 	res-&gt;payload.len = SYNC_PROTO_MAX_LEN;
+ 	res-&gt;payload.buf = res_buf;
+     }
+ 
+     fprintf(stderr, "calling FSYNC_VolOp with command code %d (%s)\n", 
+ 	    command, command_code_to_string(command));
+ 
+     code = FSYNC_VolOp(state-&gt;vop-&gt;volume,
+ 		       state-&gt;vop-&gt;partName,
+ 		       command,
+ 		       state-&gt;reason,
+ 		       res);
+ 
+     switch (code) {
+     case SYNC_OK:
+     case SYNC_DENIED:
+ 	break;
+     default:
+ 	fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
+     }
+ 
+     fprintf(stderr, "FSYNC_VolOp returned %d (%s)\n", code, response_code_to_string(code));
+     fprintf(stderr, "protocol response code was %d (%s)\n", 
+ 	    res-&gt;hdr.response, response_code_to_string(res-&gt;hdr.response));
+     fprintf(stderr, "protocol reason code was %d (%s)\n", 
+ 	    res-&gt;hdr.reason, reason_code_to_string(res-&gt;hdr.reason));
+ 
+     VDisconnectFS();
+ }
+ 
+ static char *
+ response_code_to_string(afs_int32 response)
+ {
+     switch (response) {
+     case SYNC_OK:
+ 	return "SYNC_OK";
+     case SYNC_DENIED:
+ 	return "SYNC_DENIED";
+     case SYNC_COM_ERROR:
+ 	return "SYNC_COM_ERROR";
+     case SYNC_BAD_COMMAND:
+ 	return "SYNC_BAD_COMMAND";
+     case SYNC_FAILED:
+ 	return "SYNC_FAILED";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static char *
+ command_code_to_string(afs_int32 command)
+ {
+     switch (command) {
+     case SYNC_COM_CHANNEL_CLOSE:
+ 	return "SYNC_COM_CHANNEL_CLOSE";
+     case FSYNC_VOL_ON:
+ 	return "FSYNC_VOL_ON";
+     case FSYNC_VOL_OFF:
+ 	return "FSYNC_VOL_OFF";
+     case FSYNC_VOL_LISTVOLUMES:
+ 	return "FSYNC_VOL_LISTVOLUMES";
+     case FSYNC_VOL_NEEDVOLUME:
+ 	return "FSYNC_VOL_NEEDVOLUME";
+     case FSYNC_VOL_MOVE:
+ 	return "FSYNC_VOL_MOVE";
+     case FSYNC_VOL_BREAKCBKS:
+ 	return "FSYNC_VOL_BREAKCBKS";
+     case FSYNC_VOL_DONE:
+ 	return "FSYNC_VOL_DONE";
+     case FSYNC_VOL_QUERY:
+ 	return "FSYNC_VOL_QUERY";
+     case FSYNC_VOL_QUERY_HDR:
+ 	return "FSYNC_VOL_QUERY_HDR";
+     case FSYNC_VOL_QUERY_VOP:
+ 	return "FSYNC_VOL_QUERY_VOP";
+     case FSYNC_VOL_STATS_GENERAL:
+ 	return "FSYNC_VOL_STATS_GENERAL";
+     case FSYNC_VOL_STATS_VICEP:
+ 	return "FSYNC_VOL_STATS_VICEP";
+     case FSYNC_VOL_STATS_HASH:
+ 	return "FSYNC_VOL_STATS_HASH";
+     case FSYNC_VOL_STATS_HDR:
+ 	return "FSYNC_VOL_STATS_HDR";
+     case FSYNC_VOL_STATS_VLRU:
+ 	return "FSYNC_VOL_STATS_VLRU";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static char *
+ reason_code_to_string(afs_int32 reason)
+ {
+     switch (reason) {
+     case SYNC_REASON_NONE:
+ 	return "SYNC_REASON_NONE";
+     case SYNC_REASON_MALFORMED_PACKET:
+ 	return "SYNC_REASON_MALFORMED_PACKET";
+     case FSYNC_WHATEVER:
+ 	return "FSYNC_WHATEVER";
+     case FSYNC_SALVAGE:
+ 	return "FSYNC_SALVAGE";
+     case FSYNC_MOVE:
+ 	return "FSYNC_MOVE";
+     case FSYNC_OPERATOR:
+ 	return "FSYNC_OPERATOR";
+     case FSYNC_EXCLUSIVE:
+ 	return "FSYNC_EXCLUSIVE";
+     case FSYNC_UNKNOWN_VOLID:
+ 	return "FSYNC_UNKNOWN_VOLID";
+     case FSYNC_HDR_NOT_ATTACHED:
+ 	return "FSYNC_HDR_NOT_ATTACHED";
+     case FSYNC_NO_PENDING_VOL_OP:
+ 	return "FSYNC_NO_PENDING_VOL_OP";
+     case FSYNC_VOL_PKG_ERROR:
+ 	return "FSYNC_VOL_PKG_ERROR";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static char *
+ program_type_to_string(afs_int32 type)
+ {
+     switch ((ProgramType)type) {
+     case fileServer:
+ 	return "fileServer";
+     case volumeUtility:
+ 	return "volumeUtility";
+     case salvager:
+ 	return "salvager";
+     case salvageServer:
+ 	return "salvageServer";
+     case debugUtility:
+       return "debugUtility";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static int 
+ VolOnline(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_ON, NULL);
+ 
+     return 0;
+ }
+ 
+ static int 
+ VolOffline(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_OFF, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ VolMode(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_NEEDVOLUME, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ VolDetach(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_DONE, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ VolBreakCBKs(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_BREAKCBKS, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ VolMove(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_MOVE, NULL);
+ 
+     return 0;
+ }
+ 
+ static int
+ VolList(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_LISTVOLUMES, NULL);
+ 
+     return 0;
+ }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ static char *
+ vol_state_to_string(VolState state)
+ {
+     switch (state) {
+     case VOL_STATE_UNATTACHED:
+ 	return "VOL_STATE_UNATTACHED";
+     case VOL_STATE_PREATTACHED:
+ 	return "VOL_STATE_PREATTACHED";
+     case VOL_STATE_ATTACHING:
+ 	return "VOL_STATE_ATTACHING";
+     case VOL_STATE_ATTACHED:
+ 	return "VOL_STATE_ATTACHED";
+     case VOL_STATE_UPDATING:
+ 	return "VOL_STATE_UPDATING";
+     case VOL_STATE_GET_BITMAP:
+ 	return "VOL_STATE_GET_BITMAP";
+     case VOL_STATE_HDR_LOADING:
+ 	return "VOL_STATE_HDR_LOADING";
+     case VOL_STATE_HDR_ATTACHING:
+ 	return "VOL_STATE_HDR_ATTACHING";
+     case VOL_STATE_SHUTTING_DOWN:
+ 	return "VOL_STATE_SHUTTING_DOWN";
+     case VOL_STATE_GOING_OFFLINE:
+ 	return "VOL_STATE_GOING_OFFLINE";
+     case VOL_STATE_OFFLINING:
+ 	return "VOL_STATE_OFFLINING";
+     case VOL_STATE_DETACHING:
+ 	return "VOL_STATE_DETACHING";
+     case VOL_STATE_SALVSYNC_REQ:
+       return "VOL_STATE_SALVSYNC_REQ";
+     case VOL_STATE_SALVAGING:
+ 	return "VOL_STATE_SALVAGING";
+     case VOL_STATE_ERROR:
+ 	return "VOL_STATE_ERROR";
+     case VOL_STATE_FREED:
+ 	return "VOL_STATE_FREED";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ 
+ static char *
+ vol_flags_to_string(afs_uint16 flags)
+ {
+     static char str[128];
+     int count = 0;
+     str[0]='\0';
+ 
+     if (flags &amp; VOL_HDR_ATTACHED) {
+ 	strlcat(str, "VOL_HDR_ATTACHED", sizeof(str));
+ 	count++;
+     }
+ 
+     if (flags &amp; VOL_HDR_LOADED) {
+ 	if (count) {
+ 	    strlcat(str, " | ", sizeof(str));
+ 	}
+ 	strlcat(str, "VOL_HDR_LOADED", sizeof(str));
+ 	count++;
+     }
+ 
+     if (flags &amp; VOL_HDR_IN_LRU) {
+ 	if (count) {
+ 	    strlcat(str, " | ", sizeof(str));
+ 	}
+ 	strlcat(str, "VOL_HDR_IN_LRU", sizeof(str));
+ 	count++;
+     }
+ 
+     if (flags &amp; VOL_IN_HASH) {
+ 	if (count) {
+ 	    strlcat(str, " | ", sizeof(str));
+ 	}
+ 	strlcat(str, "VOL_IN_HASH", sizeof(str));
+ 	count++;
+     }
+ 
+     if (flags &amp; VOL_ON_VBYP_LIST) {
+ 	if (count) {
+ 	    strlcat(str, " | ", sizeof(str));
+ 	}
+ 	strlcat(str, "VOL_ON_VBYP_LIST", sizeof(str));
+ 	count++;
+     }
+ 
+     if (flags &amp; VOL_IS_BUSY) {
+ 	if (count) {
+ 	    strlcat(str, " | ", sizeof(str));
+ 	}
+ 	strlcat(str, "VOL_IS_BUSY", sizeof(str));
+ 	count++;
+     }
+ 
+     if (flags &amp; VOL_ON_VLRU) {
+ 	if (count) {
+ 	    strlcat(str, " | ", sizeof(str));
+ 	}
+ 	strlcat(str, "VOL_ON_VLRU", sizeof(str));
+     }
+ 
+     if (flags &amp; VOL_HDR_DONTSALV) {
+ 	if (count) {
+ 	    strlcat(str, " | ", sizeof(str));
+ 	}
+ 	strlcat(str, "VOL_HDR_DONTSALV", sizeof(str));
+     }
+ 
+     return str;
+ }
+ 
+ static char *
+ vlru_idx_to_string(int idx)
+ {
+     switch (idx) {
+     case VLRU_QUEUE_NEW:
+ 	return "VLRU_QUEUE_NEW";
+     case VLRU_QUEUE_MID:
+ 	return "VLRU_QUEUE_MID";
+     case VLRU_QUEUE_OLD:
+ 	return "VLRU_QUEUE_OLD";
+     case VLRU_QUEUE_CANDIDATE:
+ 	return "VLRU_QUEUE_CANDIDATE";
+     case VLRU_QUEUE_HELD:
+ 	return "VLRU_QUEUE_HELD";
+     case VLRU_QUEUE_INVALID:
+ 	return "VLRU_QUEUE_INVALID";
+     default:
+ 	return "**UNKNOWN**";
+     }
+ }
+ #endif
+ 
+ static int
+ VolQuery(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+     SYNC_PROTO_BUF_DECL(res_buf);
+     SYNC_response res;
+     Volume v;
+     int hi, lo;
+ 
+     res.hdr.response_len = sizeof(res.hdr);
+     res.payload.buf = res_buf;
+     res.payload.len = SYNC_PROTO_MAX_LEN;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_QUERY, &amp;res);
+ 
+     if (res.hdr.response == SYNC_OK) {
+ 	memcpy(&amp;v, res.payload.buf, sizeof(Volume));
+ 
+ 	printf("volume = {\n");
+ 	printf("\thashid          = %u\n", v.hashid);
+ 	printf("\theader          = 0x%x\n", v.header);
+ 	printf("\tdevice          = %d\n", v.device);
+ 	printf("\tpartition       = 0x%x\n", v.partition);
+ 	printf("\tlinkHandle      = 0x%x\n", v.linkHandle);
+ 	printf("\tnextVnodeUnique = %u\n", v.nextVnodeUnique);
+ 	printf("\tdiskDataHandle  = 0x%x\n", v.diskDataHandle);
+ 	printf("\tvnodeHashOffset = %u\n", v.vnodeHashOffset);
+ 	printf("\tshuttingDown    = %d\n", v.shuttingDown);
+ 	printf("\tgoingOffline    = %d\n", v.goingOffline);
+ 	printf("\tcacheCheck      = %u\n", v.cacheCheck);
+ 	printf("\tnUsers          = %d\n", v.nUsers);
+ 	printf("\tneedsPutBack    = %d\n", v.needsPutBack);
+ 	printf("\tspecialStatus   = %d\n", v.specialStatus);
+ 	printf("\tupdateTime      = %u\n", v.updateTime);
+ 	
+ 	printf("\tvnodeIndex[vSmall] = {\n");
+         printf("\t\thandle       = 0x%x\n", v.vnodeIndex[vSmall].handle);
+         printf("\t\tbitmap       = 0x%x\n", v.vnodeIndex[vSmall].bitmap);
+ 	printf("\t\tbitmapSize   = %u\n", v.vnodeIndex[vSmall].bitmapSize);
+ 	printf("\t\tbitmapOffset = %u\n", v.vnodeIndex[vSmall].bitmapOffset);
+ 	printf("\t}\n");
+ 	printf("\tvnodeIndex[vLarge] = {\n");
+         printf("\t\thandle       = 0x%x\n", v.vnodeIndex[vLarge].handle);
+         printf("\t\tbitmap       = 0x%x\n", v.vnodeIndex[vLarge].bitmap);
+ 	printf("\t\tbitmapSize   = %u\n", v.vnodeIndex[vLarge].bitmapSize);
+ 	printf("\t\tbitmapOffset = %u\n", v.vnodeIndex[vLarge].bitmapOffset);
+ 	printf("\t}\n");
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	if (res.hdr.flags &amp; SYNC_FLAG_DAFS_EXTENSIONS) {
+ 	    printf("\tupdateTime      = %u\n", v.updateTime);
+ 	    printf("\tattach_state    = %s\n", vol_state_to_string(v.attach_state));
+ 	    printf("\tattach_flags    = %s\n", vol_flags_to_string(v.attach_flags));
+ 	    printf("\tnWaiters        = %d\n", v.nWaiters);
+ 	    printf("\tchainCacheCheck = %d\n", v.chainCacheCheck);
+ 	    
+ 	    /* online salvage structure */
+ 	    printf("\tsalvage = {\n");
+ 	    printf("\t\tprio      = %u\n", v.salvage.prio);
+ 	    printf("\t\treason    = %d\n", v.salvage.reason);
+ 	    printf("\t\trequested = %d\n", v.salvage.requested);
+ 	    printf("\t\tscheduled = %d\n", v.salvage.scheduled);
+ 	    printf("\t}\n");
+ 	    
+ 	    /* statistics structure */
+ 	    printf("\tstats = {\n");
+ 
+ 	    printf("\t\thash_lookups = {\n");
+ 	    SplitInt64(v.stats.hash_lookups,hi,lo);
+ 	    printf("\t\t\thi = %u\n", hi);
+ 	    printf("\t\t\tlo = %u\n", lo);
+ 	    printf("\t\t}\n");
+ 
+ 	    printf("\t\thash_short_circuits = {\n");
+ 	    SplitInt64(v.stats.hash_short_circuits,hi,lo);
+ 	    printf("\t\t\thi = %u\n", hi);
+ 	    printf("\t\t\tlo = %u\n", lo);
+ 	    printf("\t\t}\n");
+ 
+ 	    printf("\t\thdr_loads = {\n");
+ 	    SplitInt64(v.stats.hdr_loads,hi,lo);
+ 	    printf("\t\t\thi = %u\n", hi);
+ 	    printf("\t\t\tlo = %u\n", lo);
+ 	    printf("\t\t}\n");
+ 
+ 	    printf("\t\thdr_gets = {\n");
+ 	    SplitInt64(v.stats.hdr_gets,hi,lo);
+ 	    printf("\t\t\thi = %u\n", hi);
+ 	    printf("\t\t\tlo = %u\n", lo);
+ 	    printf("\t\t}\n");
+ 	    
+ 	    printf("\t\tattaches         = %u\n", v.stats.attaches);
+ 	    printf("\t\tsoft_detaches    = %u\n", v.stats.soft_detaches);
+ 	    printf("\t\tsalvages         = %u\n", v.stats.salvages);
+ 	    printf("\t\tvol_ops          = %u\n", v.stats.vol_ops);
+ 	    
+ 	    printf("\t\tlast_attach      = %u\n", v.stats.last_attach);
+ 	    printf("\t\tlast_get         = %u\n", v.stats.last_get);
+ 	    printf("\t\tlast_promote     = %u\n", v.stats.last_promote);
+ 	    printf("\t\tlast_hdr_get     = %u\n", v.stats.last_hdr_get);
+ 	    printf("\t\tlast_salvage     = %u\n", v.stats.last_salvage);
+ 	    printf("\t\tlast_salvage_req = %u\n", v.stats.last_salvage_req);
+ 	    printf("\t\tlast_vol_op      = %u\n", v.stats.last_vol_op);
+ 	    printf("\t}\n");
+ 	    
+ 	    /* VLRU state */
+ 	    printf("\tvlru = {\n");
+ 	    printf("\t\tidx = %d (%s)\n", 
+ 		   v.vlru.idx, vlru_idx_to_string(v.vlru.idx));
+ 	    printf("\t}\n");
+ 
+ 	    /* volume op state */
+ 	    printf("\tpending_vol_op  = 0x%x\n", v.pending_vol_op);
+ 	}
+ #else /* !AFS_DEMAND_ATTACH_FS */
+ 	if (res.hdr.flags &amp; SYNC_FLAG_DAFS_EXTENSIONS) {
+ 	    printf("*** server asserted demand attach extensions. fssync-debug not built to\n");
+ 	    printf("*** recognize those extensions. please recompile fssync-debug if you need\n");
+ 	    printf("*** to dump dafs extended state\n");
+ 	}
+ #endif /* !AFS_DEMAND_ATTACH_FS */
+ 	printf("}\n");
+     }
+ 
+     return 0;
+ }
+ 
+ static int
+ VolHdrQuery(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+     SYNC_PROTO_BUF_DECL(res_buf);
+     SYNC_response res;
+     VolumeDiskData v;
+     int i;
+ 
+     res.hdr.response_len = sizeof(res.hdr);
+     res.payload.buf = res_buf;
+     res.payload.len = SYNC_PROTO_MAX_LEN;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_QUERY_HDR, &amp;res);
+ 
+     if (res.hdr.response == SYNC_OK) {
+ 	memcpy(&amp;v, res.payload.buf, sizeof(VolumeDiskData));
+ 
+ 	printf("VolumeDiskData = {\n");
+ 	printf("\tstamp = {\n");
+ 	printf("\t\tmagic   = 0x%x\n", v.stamp.magic);
+ 	printf("\t\tversion = %u\n", v.stamp.version);
+ 	printf("\t}\n");
+ 	
+ 	printf("\tid               = %u\n", v.id);
+ 	printf("\tname             = '%s'\n", v.name);
+ 	printf("\tinUse            = %d\n", v.inUse);
+ 	printf("\tinService        = %d\n", v.inService);
+ 	printf("\tblessed          = %d\n", v.blessed);
+ 	printf("\tneedsSalvaged    = %d\n", v.needsSalvaged);
+ 	printf("\tuniquifier       = %u\n", v.uniquifier);
+ 	printf("\ttype             = %d\n", v.type);
+ 	printf("\tparentId         = %u\n", v.parentId);
+ 	printf("\tcloneId          = %u\n", v.cloneId);
+ 	printf("\tbackupId         = %u\n", v.backupId);
+ 	printf("\trestoredFromId   = %u\n", v.restoredFromId);
+ 	printf("\tneedsCallback    = %d\n", v.needsCallback);
+ 	printf("\tdestroyMe        = %d\n", v.destroyMe);
+ 	printf("\tdontSalvage      = %d\n", v.dontSalvage);
+ 	printf("\tmaxquota         = %d\n", v.maxquota);
+ 	printf("\tminquota         = %d\n", v.minquota);
+ 	printf("\tmaxfiles         = %d\n", v.maxfiles);
+ 	printf("\taccountNumber    = %u\n", v.accountNumber);
+ 	printf("\towner            = %u\n", v.owner);
+ 	printf("\tfilecount        = %d\n", v.filecount);
+ 	printf("\tdiskused         = %d\n", v.diskused);
+ 	printf("\tdayUse           = %d\n", v.dayUse);
+ 	for (i = 0; i &lt; 7; i++) {
+ 	    printf("\tweekUse[%d]       = %d\n", i, v.weekUse[i]);
+ 	}
+ 	printf("\tdayUseDate       = %u\n", v.dayUseDate);
+ 	printf("\tcreationDate     = %u\n", v.creationDate);
+ 	printf("\taccessDate       = %u\n", v.accessDate);
+ 	printf("\tupdateDate       = %u\n", v.updateDate);
+ 	printf("\texpirationDate   = %u\n", v.expirationDate);
+ 	printf("\tbackupDate       = %u\n", v.backupDate);
+ 	printf("\tcopyDate         = %u\n", v.copyDate);
+ #ifdef OPENAFS_VOL_STATS
+ 	printf("\tstat_initialized = %d\n", v.stat_initialized);
+ #else
+         printf("\tmtd              = '%s'\n", v.motd);
+ #endif
+ 	printf("}\n");
+     }
+ 
+     return 0;
+ }
+ 
+ static int
+ VolOpQuery(struct cmd_syndesc * as, char * rock)
+ {
+     struct state state;
+     SYNC_PROTO_BUF_DECL(res_buf);
+     SYNC_response res;
+     FSSYNC_VolOp_info vop;
+     int i;
+ 
+     res.hdr.response_len = sizeof(res.hdr);
+     res.payload.buf = res_buf;
+     res.payload.len = SYNC_PROTO_MAX_LEN;
+ 
+     common_prolog(as, &amp;state);
+     common_volop_prolog(as, &amp;state);
+ 
+     do_volop(&amp;state, FSYNC_VOL_QUERY_VOP, &amp;res);
+ 
+     if (!(res.hdr.flags &amp; SYNC_FLAG_DAFS_EXTENSIONS)) {
+ 	printf("*** file server not compiled with demand attach extensions.\n");
+ 	printf("*** pending volume operation metadata not available.\n");
+     }
+ 
+     if (res.hdr.response == SYNC_OK) {
+ 	memcpy(&amp;vop, res.payload.buf, sizeof(FSSYNC_VolOp_info));
+ 
+ 	printf("pending_vol_op = {\n");
+ 
+ 	printf("\tcom = {\n");
+ 	printf("\t\tproto_version  = %u\n", vop.com.proto_version);
+ 	printf("\t\tprogramType    = %d (%s)\n", 
+ 	       vop.com.programType, program_type_to_string(vop.com.programType));
+ 	printf("\t\tcommand        = %d (%s)\n", 
+ 	       vop.com.command, command_code_to_string(vop.com.command));
+ 	printf("\t\treason         = %d (%s)\n", 
+ 	       vop.com.reason, reason_code_to_string(vop.com.reason));
+ 	printf("\t\tcommand_len    = %u\n", vop.com.command_len);
+ 	printf("\t\tflags          = 0x%x\n", vop.com.flags);
+ 	printf("\t}\n");
+ 
+ 	printf("\tvop = {\n");
+ 	printf("\t\tvolume         = %u\n", vop.vop.volume);
+ 	if (afs_strnlen(vop.vop.partName, sizeof(vop.vop.partName)) &lt;
+ 	    sizeof(vop.vop.partName)) {
+ 	    printf("\t\tpartName       = '%s'\n", vop.vop.partName);
+ 	} else {
+ 	    printf("\t\tpartName       = (illegal string)\n");
+ 	}
+ 	printf("\t}\n");
+ 
+ 	printf("}\n");
+     }
+ 
+     return 0;
+ }
+ 
+ static int
+ StatsQuery(struct cmd_syndesc * as, char * rock)
+ {
+     afs_int32 code;
+     int command;
+     struct cmd_item *ti;
+     struct state state;
+     SYNC_PROTO_BUF_DECL(res_buf);
+     SYNC_response res;
+     FSSYNC_StatsOp_hdr scom;
+     union {
+ 	void * ptr;
+ 	struct VolPkgStats * vol_stats;
+ 	struct VolumeHashChainStats * hash_stats;
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	struct volume_hdr_LRU_stats * hdr_stats;
+ #endif
+ 	struct DiskPartitionStats * vicep_stats;
+     } sres;
+ 
+     sres.ptr = res_buf;
+     res.hdr.response_len = sizeof(res.hdr);
+     res.payload.buf = res_buf;
+     res.payload.len = SYNC_PROTO_MAX_LEN;
+ 
+     if ((ti = as-&gt;parms[CUSTOM_PARMS_OFFSET].items)) {	/* -subcommand */
+ 	if (!strcasecmp(ti-&gt;data, "vicep")) {
+ 	    command = FSYNC_VOL_STATS_VICEP;
+ 	} else if (!strcasecmp(ti-&gt;data, "hash")) {
+ 	    command = FSYNC_VOL_STATS_HASH;
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	} else if (!strcasecmp(ti-&gt;data, "hdr")) {
+ 	    command = FSYNC_VOL_STATS_HDR;
+ 	} else if (!strcasecmp(ti-&gt;data, "vlru")) {
+ 	    command = FSYNC_VOL_STATS_VLRU;
+ #endif
+ 	} else if (!strcasecmp(ti-&gt;data, "pkg")) {
+ 	    command = FSYNC_VOL_STATS_GENERAL;
+ 	} else if (!strcasecmp(ti-&gt;data, "help")) {
+ 	    fprintf(stderr, "fssync-debug stats subcommands:\n");
+ 	    fprintf(stderr, "\tpkg\tgeneral volume package stats\n");
+ 	    fprintf(stderr, "\tvicep\tvice partition stats\n");
+ 	    fprintf(stderr, "\thash\tvolume hash chain stats\n");
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	    fprintf(stderr, "\thdr\tvolume header cache stats\n");
+ 	    fprintf(stderr, "\tvlru\tvlru generation stats\n");
+ #endif
+ 	    exit(0);
+ 	} else {
+ 	    fprintf(stderr, "invalid stats subcommand");
+ 	    exit(1);
+ 	}
+     } else {
+ 	command = FSYNC_VOL_STATS_GENERAL;
+     }
+ 
+     if ((ti = as-&gt;parms[CUSTOM_PARMS_OFFSET+1].items)) {	/* -arg1 */
+ 	switch (command) {
+ 	case FSYNC_VOL_STATS_VICEP:
+ 	    strlcpy(scom.args.partName, ti-&gt;data, sizeof(state.vop-&gt;partName));
+ 	    break;
+ 	case FSYNC_VOL_STATS_HASH:
+ 	    scom.args.hash_bucket = atoi(ti-&gt;data);
+ 	    break;
+ 	case FSYNC_VOL_STATS_VLRU:
+ 	    scom.args.vlru_generation = atoi(ti-&gt;data);
+ 	    break;
+ 	default:
+ 	    fprintf(stderr, "unrecognized arguments\n");
+ 	    exit(1);
+ 	}
+     } else {
+ 	switch (command) {
+ 	case FSYNC_VOL_STATS_VICEP:
+ 	case FSYNC_VOL_STATS_HASH:
+ 	case FSYNC_VOL_STATS_VLRU:
+ 	    fprintf(stderr, "this subcommand requires more parameters\n");
+ 	    exit(1);
+ 	}
+     }
+ 
+     common_prolog(as, &amp;state);
+ 
+     fprintf(stderr, "calling FSYNC_askfs with command code %d (%s)\n", 
+ 	    command, command_code_to_string(command));
+ 
+     code = FSYNC_StatsOp(&amp;scom, command, FSYNC_WHATEVER, &amp;res);
+ 
+     switch (code) {
+     case SYNC_OK:
+     case SYNC_DENIED:
+ 	break;
+     default:
+ 	fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
+     }
+ 
+     fprintf(stderr, "FSYNC_VolOp returned %d (%s)\n", code, response_code_to_string(code));
+     fprintf(stderr, "protocol response code was %d (%s)\n", 
+ 	    res.hdr.response, response_code_to_string(res.hdr.response));
+     fprintf(stderr, "protocol reason code was %d (%s)\n", 
+ 	    res.hdr.reason, reason_code_to_string(res.hdr.reason));
+ 
+     VDisconnectFS();
+ 
+     if (res.hdr.response == SYNC_OK) {
+ 	switch (command) {
+ 	case FSYNC_VOL_STATS_GENERAL:
+ 	    print_vol_stats_general(sres.vol_stats);
+ 	    break;
+ 	case FSYNC_VOL_STATS_VICEP:
+ 	    print_vol_stats_viceP(sres.vicep_stats);
+ 	    break;
+ 	case FSYNC_VOL_STATS_HASH:
+ 	    print_vol_stats_hash(sres.hash_stats);
+ 	    break;
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	case FSYNC_VOL_STATS_HDR:
+ 	    print_vol_stats_hdr(sres.hdr_stats);
+ 	    break;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 	}
+     }
+ 
+     return 0;
+ }
+ 
+ static void
+ print_vol_stats_general(VolPkgStats * stats)
+ {
+     int i;
+     afs_uint32 hi, lo;
+ 
+     printf("VolPkgStats = {\n");
+ #ifdef AFS_DEMAND_ATTACH_FS
+     for (i = 0; i &lt; VOL_STATE_COUNT; i++) {
+ 	printf("\tvol_state_count[%s] = %d\n", 
+ 	       vol_state_to_string(i),
+ 	       stats-&gt;state_levels[i]);
+     }
+ 
+     SplitInt64(stats-&gt;hash_looks, hi, lo);
+     printf("\thash_looks = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     SplitInt64(stats-&gt;hash_reorders, hi, lo);
+     printf("\thash_reorders = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     SplitInt64(stats-&gt;salvages, hi, lo);
+     printf("\tsalvages = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     SplitInt64(stats-&gt;vol_ops, hi, lo);
+     printf("\tvol_ops = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ #endif
+     SplitInt64(stats-&gt;hdr_loads, hi, lo);
+     printf("\thdr_loads = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     SplitInt64(stats-&gt;hdr_gets, hi, lo);
+     printf("\thdr_gets = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     SplitInt64(stats-&gt;attaches, hi, lo);
+     printf("\tattaches = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     SplitInt64(stats-&gt;soft_detaches, hi, lo);
+     printf("\tsoft_detaches = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     printf("\thdr_cache_size = %d\n", stats-&gt;hdr_cache_size);
+ 	    
+     printf("}\n");
+ }
+ 
+ static void
+ print_vol_stats_viceP(struct DiskPartitionStats * stats)
+ {
+     printf("DiskPartitionStats = {\n");
+     printf("\tfree = %d\n", stats-&gt;free);
+     printf("\tminFree = %d\n", stats-&gt;minFree);
+     printf("\ttotalUsable = %d\n", stats-&gt;totalUsable);
+     printf("\tf_files = %d\n", stats-&gt;f_files);
+ #ifdef AFS_DEMAND_ATTACH_FS
+     printf("\tvol_list_len = %d\n", stats-&gt;vol_list_len);
+ #endif
+     printf("}\n");
+ }
+ 
+ static void
+ print_vol_stats_hash(struct VolumeHashChainStats * stats)
+ {
+     afs_uint32 hi, lo;
+ 
+     printf("DiskPartitionStats = {\n");
+     printf("\ttable_size = %d\n", stats-&gt;table_size);
+     printf("\tchain_len = %d\n", stats-&gt;chain_len);
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     printf("\tchain_cacheCheck = %d\n", stats-&gt;chain_cacheCheck);
+     printf("\tchain_busy = %d\n", stats-&gt;chain_busy);
+ 
+     SplitInt64(stats-&gt;chain_looks, hi, lo);
+     printf("\tchain_looks = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     SplitInt64(stats-&gt;chain_gets, hi, lo);
+     printf("\tchain_gets = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ 
+     SplitInt64(stats-&gt;chain_reorders, hi, lo);
+     printf("\tchain_reorders = {\n");
+     printf("\t\thi = %u\n", hi);
+     printf("\t\tlo = %u\n", lo);
+     printf("\t}\n");
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+     printf("}\n");
+ }
+ 
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ static void
+ print_vol_stats_hdr(struct volume_hdr_LRU_stats * stats)
+ {
+     printf("volume_hdr_LRU_stats = {\n");
+     printf("\tfree = %d\n", stats-&gt;free);
+     printf("\tused = %d\n", stats-&gt;used);
+     printf("\tattached = %d\n", stats-&gt;attached);
+     printf("}\n");
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
Index: openafs/src/vol/fssync-server.c
diff -c /dev/null openafs/src/vol/fssync-server.c:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/fssync-server.c	Fri Mar 17 23:20:19 2006
***************
*** 0 ****
--- 1,1179 ----
+ /*
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
+  */
+ 
+ /*
+ 	System:		VICE-TWO
+ 	Module:		fssync.c
+ 	Institution:	The Information Technology Center, Carnegie-Mellon University
+ 
+  */
+ #ifdef notdef
+ 
+ /* All this is going away in early 1989 */
+ int newVLDB;			/* Compatibility flag */
+ 
+ #endif
+ static int newVLDB = 1;
+ 
+ 
+ #ifndef AFS_PTHREAD_ENV
+ #define USUAL_PRIORITY (LWP_MAX_PRIORITY - 2)
+ 
+ /*
+  * stack size increased from 8K because the HP machine seemed to have trouble
+  * with the smaller stack
+  */
+ #define USUAL_STACK_SIZE	(24 * 1024)
+ #endif /* !AFS_PTHREAD_ENV */
+ 
+ /*
+    fssync-server.c
+    File server synchronization with external volume utilities.
+    server-side implementation
+  */
+ 
+ /* This controls the size of an fd_set; it must be defined early before
+  * the system headers define that type and the macros that operate on it.
+  * Its value should be as large as the maximum file descriptor limit we
+  * are likely to run into on any platform.  Right now, that is 65536
+  * which is the default hard fd limit on Solaris 9 */
+ #ifndef _WIN32
+ #define FD_SETSIZE 65536
+ #endif
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/vol/fssync-server.c,v 1.1 2006/03/18 04:20:19 shadow Exp $");
+ 
+ #include &lt;sys/types.h&gt;
+ #include &lt;stdio.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;winsock2.h&gt;
+ #include &lt;time.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/socket.h&gt;
+ #include &lt;netinet/in.h&gt;
+ #include &lt;netdb.h&gt;
+ #include &lt;sys/time.h&gt;
+ #endif
+ #include &lt;errno.h&gt;
+ #ifdef AFS_PTHREAD_ENV
+ #include &lt;assert.h&gt;
+ #else /* AFS_PTHREAD_ENV */
+ #include &lt;afs/assert.h&gt;
+ #endif /* AFS_PTHREAD_ENV */
+ #include &lt;signal.h&gt;
+ 
+ #ifdef HAVE_STRING_H
+ #include &lt;string.h&gt;
+ #else
+ #ifdef HAVE_STRINGS_H
+ #include &lt;strings.h&gt;
+ #endif
+ #endif
+ 
+ 
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include "nfs.h"
+ #include &lt;afs/errors.h&gt;
+ #include "daemon_com.h"
+ #include "fssync.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include &lt;afs/afssyscalls.h&gt;
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ 
+ 
+ #ifdef FSSYNC_BUILD_SERVER
+ 
+ /*@printflike@*/ extern void Log(const char *format, ...);
+ 
+ #ifdef osi_Assert
+ #undef osi_Assert
+ #endif
+ #define osi_Assert(e) (void)(e)
+ 
+ int (*V_BreakVolumeCallbacks) ();
+ 
+ #define MAXHANDLERS	4	/* Up to 4 clients; must be at least 2, so that
+ 				 * move = dump+restore can run on single server */
+ #define MAXOFFLINEVOLUMES 128	/* This needs to be as big as the maximum
+ 				 * number that would be offline for 1 operation.
+ 				 * Current winner is salvage, which needs all
+ 				 * cloned read-only copies offline when salvaging
+ 				 * a single read-write volume */
+ 
+ #define MAX_BIND_TRIES	5	/* Number of times to retry socket bind */
+ 
+ 
+ 
+ static struct offlineInfo OfflineVolumes[MAXHANDLERS][MAXOFFLINEVOLUMES];
+ 
+ static int AcceptSd = -1;	/* Socket used by server for accepting connections */
+ 
+ static int getport();
+ 
+ /* Forward declarations */
+ static void FSYNC_sync();
+ static void FSYNC_newconnection();
+ static void FSYNC_com();
+ static void FSYNC_Drop();
+ static void AcceptOn();
+ static void AcceptOff();
+ static void InitHandler();
+ static void CallHandler(fd_set * fdsetp);
+ static int AddHandler();
+ static int FindHandler();
+ static int FindHandler_r();
+ static int RemoveHandler();
+ static void GetHandler(fd_set * fdsetp, int *maxfdp);
+ 
+ extern int LogLevel;
+ 
+ static afs_int32 FSYNC_com_VolOp(int fd, SYNC_command * com, SYNC_response * res);
+ 
+ static afs_int32 FSYNC_com_VolOn(FSSYNC_VolOp_command * com, SYNC_response * res);
+ static afs_int32 FSYNC_com_VolOff(FSSYNC_VolOp_command * com, SYNC_response * res);
+ static afs_int32 FSYNC_com_VolMove(FSSYNC_VolOp_command * com, SYNC_response * res);
+ static afs_int32 FSYNC_com_VolBreakCBKs(FSSYNC_VolOp_command * com, SYNC_response * res);
+ static afs_int32 FSYNC_com_VolDone(FSSYNC_VolOp_command * com, SYNC_response * res);
+ static afs_int32 FSYNC_com_VolQuery(FSSYNC_VolOp_command * com, SYNC_response * res);
+ static afs_int32 FSYNC_com_VolHdrQuery(FSSYNC_VolOp_command * com, SYNC_response * res);
+ #ifdef AFS_DEMAND_ATTACH_FS
+ static afs_int32 FSYNC_com_VolOpQuery(FSSYNC_VolOp_command * com, SYNC_response * res);
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ static afs_int32 FSYNC_com_StatsOp(int fd, SYNC_command * com, SYNC_response * res);
+ 
+ static afs_int32 FSYNC_com_StatsOpGeneral(FSSYNC_StatsOp_command * scom, SYNC_response * res);
+ static afs_int32 FSYNC_com_StatsOpViceP(FSSYNC_StatsOp_command * scom, SYNC_response * res);
+ static afs_int32 FSYNC_com_StatsOpHash(FSSYNC_StatsOp_command * scom, SYNC_response * res);
+ static afs_int32 FSYNC_com_StatsOpHdr(FSSYNC_StatsOp_command * scom, SYNC_response * res);
+ static afs_int32 FSYNC_com_StatsOpVLRU(FSSYNC_StatsOp_command * scom, SYNC_response * res);
+ 
+ 
+ static void FSYNC_com_to_info(FSSYNC_VolOp_command * vcom, FSSYNC_VolOp_info * info);
+ 
+ 
+ /*
+  * This lock controls access to the handler array. The overhead
+  * is minimal in non-preemptive environments.
+  */
+ struct Lock FSYNC_handler_lock;
+ 
+ void
+ FSYNC_fsInit(void)
+ {
+ #ifdef AFS_PTHREAD_ENV
+     pthread_t tid;
+     pthread_attr_t tattr;
+ #else /* AFS_PTHREAD_ENV */
+     PROCESS pid;
+ #endif /* AFS_PTHREAD_ENV */
+ 
+     Lock_Init(&amp;FSYNC_handler_lock);
+ 
+ #ifdef AFS_PTHREAD_ENV
+     assert(pthread_attr_init(&amp;tattr) == 0);
+     assert(pthread_attr_setdetachstate(&amp;tattr, PTHREAD_CREATE_DETACHED) == 0);
+     assert(pthread_create(&amp;tid, &amp;tattr, FSYNC_sync, NULL) == 0);
+ #else /* AFS_PTHREAD_ENV */
+     assert(LWP_CreateProcess
+ 	   (FSYNC_sync, USUAL_STACK_SIZE, USUAL_PRIORITY, (void *)0,
+ 	    "FSYNC_sync", &amp;pid) == LWP_SUCCESS);
+ #endif /* AFS_PTHREAD_ENV */
+ }
+ 
+ static fd_set FSYNC_readfds;
+ 
+ static int
+ getport(struct sockaddr_in *addr)
+ {
+     int sd;
+ 
+     memset(addr, 0, sizeof(*addr));
+     assert((sd = socket(AF_INET, SOCK_STREAM, 0)) &gt;= 0);
+ #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
+     addr-&gt;sin_len = sizeof(struct sockaddr_in);
+ #endif
+     addr-&gt;sin_addr.s_addr = htonl(0x7f000001);
+     addr-&gt;sin_family = AF_INET;	/* was localhost-&gt;h_addrtype */
+     addr-&gt;sin_port = htons(2040);	/* XXXX htons not _really_ neccessary */
+ 
+     return sd;
+ }
+ 
+ 
+ static void
+ FSYNC_sync()
+ {
+     struct sockaddr_in addr;
+     int on = 1;
+     extern int VInit;
+     int code;
+     int numTries;
+ #ifdef AFS_PTHREAD_ENV
+     int tid;
+ #endif
+ 
+ #ifndef AFS_NT40_ENV
+     (void)signal(SIGPIPE, SIG_IGN);
+ #endif
+ 
+ #ifdef AFS_PTHREAD_ENV
+     /* set our 'thread-id' so that the host hold table works */
+     MUTEX_ENTER(&amp;rx_stats_mutex);	/* protects rxi_pthread_hinum */
+     tid = ++rxi_pthread_hinum;
+     MUTEX_EXIT(&amp;rx_stats_mutex);
+     pthread_setspecific(rx_thread_id_key, (void *)tid);
+     Log("Set thread id %d for FSYNC_sync\n", tid);
+ #endif /* AFS_PTHREAD_ENV */
+ 
+     while (!VInit) {
+ 	/* Let somebody else run until level &gt; 0.  That doesn't mean that 
+ 	 * all volumes have been attached. */
+ #ifdef AFS_PTHREAD_ENV
+ 	pthread_yield();
+ #else /* AFS_PTHREAD_ENV */
+ 	LWP_DispatchProcess();
+ #endif /* AFS_PTHREAD_ENV */
+     }
+     AcceptSd = getport(&amp;addr);
+     /* Reuseaddr needed because system inexplicably leaves crud lying around */
+     code =
+ 	setsockopt(AcceptSd, SOL_SOCKET, SO_REUSEADDR, (char *)&amp;on,
+ 		   sizeof(on));
+     if (code)
+ 	Log("FSYNC_sync: setsockopt failed with (%d)\n", errno);
+ 
+     for (numTries = 0; numTries &lt; MAX_BIND_TRIES; numTries++) {
+ 	if ((code =
+ 	     bind(AcceptSd, (struct sockaddr *)&amp;addr, sizeof(addr))) == 0)
+ 	    break;
+ 	Log("FSYNC_sync: bind failed with (%d), will sleep and retry\n",
+ 	    errno);
+ 	sleep(5);
+     }
+     assert(!code);
+     listen(AcceptSd, 100);
+     InitHandler();
+     AcceptOn();
+     for (;;) {
+ 	int maxfd;
+ 	GetHandler(&amp;FSYNC_readfds, &amp;maxfd);
+ 	/* Note: check for &gt;= 1 below is essential since IOMGR_select
+ 	 * doesn't have exactly same semantics as select.
+ 	 */
+ #ifdef AFS_PTHREAD_ENV
+ 	if (select(maxfd + 1, &amp;FSYNC_readfds, NULL, NULL, NULL) &gt;= 1)
+ #else /* AFS_PTHREAD_ENV */
+ 	if (IOMGR_Select(maxfd + 1, &amp;FSYNC_readfds, NULL, NULL, NULL) &gt;= 1)
+ #endif /* AFS_PTHREAD_ENV */
+ 	    CallHandler(&amp;FSYNC_readfds);
+     }
+ }
+ 
+ static void
+ FSYNC_newconnection(int afd)
+ {
+     struct sockaddr_in other;
+     int junk, fd;
+     junk = sizeof(other);
+     fd = accept(afd, (struct sockaddr *)&amp;other, &amp;junk);
+     if (fd == -1) {
+ 	Log("FSYNC_newconnection:  accept failed, errno==%d\n", errno);
+ 	assert(1 == 2);
+     } else if (!AddHandler(fd, FSYNC_com)) {
+ 	AcceptOff();
+ 	assert(AddHandler(fd, FSYNC_com));
+     }
+ }
+ 
+ /* this function processes commands from an fssync file descriptor (fd) */
+ afs_int32 FS_cnt = 0;
+ static void
+ FSYNC_com(int fd)
+ {
+     SYNC_command com;
+     SYNC_response res;
+     SYNC_PROTO_BUF_DECL(com_buf);
+     SYNC_PROTO_BUF_DECL(res_buf);
+ 
+     memset(&amp;res.hdr, 0, sizeof(res.hdr));
+ 
+     com.payload.buf = (void *)com_buf;
+     com.payload.len = SYNC_PROTO_MAX_LEN;
+     res.hdr.response_len = sizeof(res.hdr);
+     res.hdr.proto_version = FSYNC_PROTO_VERSION;
+     res.payload.len = SYNC_PROTO_MAX_LEN;
+     res.payload.buf = (void *)res_buf;
+ 
+     FS_cnt++;
+     if (SYNC_getCom(fd, &amp;com)) {
+ 	Log("FSYNC_com:  read failed; dropping connection (cnt=%d)\n", FS_cnt);
+ 	FSYNC_Drop(fd);
+ 	return;
+     }
+ 
+     if (com.hdr.proto_version != FSYNC_PROTO_VERSION) {
+ 	Log("FSYNC_com:  invalid protocol version (%u)\n", com.hdr.proto_version);
+ 	res.hdr.response = SYNC_COM_ERROR;
+ 	res.hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;
+ 	goto respond;
+     }
+ 
+     VOL_LOCK;
+     switch (com.hdr.command) {
+     case FSYNC_VOL_ON:
+     case FSYNC_VOL_OFF:
+     case FSYNC_VOL_LISTVOLUMES:
+     case FSYNC_VOL_NEEDVOLUME:
+     case FSYNC_VOL_MOVE:
+     case FSYNC_VOL_BREAKCBKS:
+     case FSYNC_VOL_DONE:
+     case FSYNC_VOL_QUERY:
+     case FSYNC_VOL_QUERY_HDR:
+     case FSYNC_VOL_QUERY_VOP:
+ 	res.hdr.response = FSYNC_com_VolOp(fd, &amp;com, &amp;res);
+ 	break;
+     case FSYNC_VOL_STATS_GENERAL:
+     case FSYNC_VOL_STATS_VICEP:
+     case FSYNC_VOL_STATS_HASH:
+     case FSYNC_VOL_STATS_HDR:
+     case FSYNC_VOL_STATS_VLRU:
+ 	res.hdr.response = FSYNC_com_StatsOp(fd, &amp;com, &amp;res);
+ 	break;
+     case SYNC_COM_CHANNEL_CLOSE:
+ 	res.hdr.response = SYNC_OK;
+ 	res.hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;
+ 	break;
+     default:
+ 	res.hdr.response = SYNC_BAD_COMMAND;
+ 	break;
+     }
+     VOL_UNLOCK;
+ 
+  respond:
+     SYNC_putRes(fd, &amp;res);
+     if (res.hdr.flags &amp; SYNC_FLAG_CHANNEL_SHUTDOWN) {
+ 	FSYNC_Drop(fd);
+     }
+ }
+ 
+ static afs_int32
+ FSYNC_com_VolOp(int fd, SYNC_command * com, SYNC_response * res)
+ {
+     int i;
+     afs_int32 code = SYNC_OK;
+     FSSYNC_VolOp_command vcom;
+ 
+     if (com-&gt;recv_len != (sizeof(com-&gt;hdr) + sizeof(FSSYNC_VolOp_hdr))) {
+ 	res-&gt;hdr.reason = SYNC_REASON_MALFORMED_PACKET;
+ 	res-&gt;hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;
+ 	return SYNC_COM_ERROR;
+     }
+ 
+     vcom.hdr = &amp;com-&gt;hdr;
+     vcom.vop = (FSSYNC_VolOp_hdr *) com-&gt;payload.buf;
+     vcom.com = com;
+ 
+     vcom.volumes = OfflineVolumes[FindHandler(fd)];
+     for (vcom.v = NULL, i = 0; i &lt; MAXOFFLINEVOLUMES; i++) {
+ 	if ((vcom.volumes[i].volumeID == vcom.vop-&gt;volume) &amp;&amp;
+ 	    (strncmp(vcom.volumes[i].partName, vcom.vop-&gt;partName,
+ 		     sizeof(vcom.volumes[i].partName)) == 0)) {
+ 	    vcom.v = &amp;vcom.volumes[i];
+ 	    break;
+ 	}
+     }
+ 
+     switch (com-&gt;hdr.command) {
+     case FSYNC_VOL_ON:
+ 	code = FSYNC_com_VolOn(&amp;vcom, res);
+ 	break;
+     case FSYNC_VOL_OFF:
+     case FSYNC_VOL_NEEDVOLUME:
+ 	code = FSYNC_com_VolOff(&amp;vcom, res);
+ 	break;
+     case FSYNC_VOL_LISTVOLUMES:
+ 	code = SYNC_OK;
+ 	break;
+     case FSYNC_VOL_MOVE:
+ 	code = FSYNC_com_VolMove(&amp;vcom, res);
+ 	break;
+     case FSYNC_VOL_BREAKCBKS:
+ 	code = FSYNC_com_VolBreakCBKs(&amp;vcom, res);
+ 	break;
+     case FSYNC_VOL_DONE:
+ 	code = FSYNC_com_VolDone(&amp;vcom, res);
+ 	break;
+     case FSYNC_VOL_QUERY:
+ 	code = FSYNC_com_VolQuery(&amp;vcom, res);
+ 	break;
+     case FSYNC_VOL_QUERY_HDR:
+ 	code = FSYNC_com_VolHdrQuery(&amp;vcom, res);
+ 	break;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     case FSYNC_VOL_QUERY_VOP:
+ 	code = FSYNC_com_VolOpQuery(&amp;vcom, res);
+ 	break;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+     default:
+ 	code = SYNC_BAD_COMMAND;
+     }
+ 
+     return code;
+ }
+ 
+ static afs_int32
+ FSYNC_com_VolOn(FSSYNC_VolOp_command * vcom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     char tvolName[VMAXPATHLEN];
+     Volume * vp;
+     Error error;
+ 
+     if (SYNC_verifyProtocolString(vcom-&gt;vop-&gt;partName, sizeof(vcom-&gt;vop-&gt;partName))) {
+ 	res-&gt;hdr.reason = SYNC_REASON_MALFORMED_PACKET;
+ 	code = SYNC_FAILED;
+ 	goto done;
+     }
+ 
+     /*
+       This is where a detatched volume gets reattached. However in the
+       special case where the volume is merely busy, it is already
+       attatched and it is only necessary to clear the busy flag. See
+       defect #2080 for details.
+     */
+ 
+     /* is the volume already attatched? */
+ #ifdef	notdef
+     /*
+      * XXX With the following enabled we had bizarre problems where the backup id would
+      * be reset to 0; that was due to the interaction between fileserver/volserver in that they
+      * both keep volumes in memory and the changes wouldn't be made to the fileserver. Some of
+      * the problems were due to refcnt changes as result of VGetVolume/VPutVolume which would call
+      * VOffline, etc. when we don't want to; someday the whole #2080 issue should be revisited to
+      * be done right XXX
+      */
+     vp = VGetVolume_r(&amp;error, vcom-&gt;vop-&gt;volume);
+     if (vp) {
+ 	/* yep, is the BUSY flag set? */
+ 	if (vp-&gt;specialStatus == VBUSY) {
+ 
+ 	    /* yep, clear BUSY flag */
+ 
+ 	    vp-&gt;specialStatus = 0;
+ 	    /* make sure vol is online */
+ 	    if (vcom-&gt;v) {
+ 		vcom-&gt;v-&gt;volumeID = 0;
+ 		V_inUse(vp) = 1;	/* online */
+ 	    }
+ 	    VPutVolume_r(vp);
+ 	    break;
+ 	}
+ 	VPutVolume_r(vp);
+     }
+ #endif /* notdef */
+ 
+     /* so, we need to attach the volume */
+ 
+     if (vcom-&gt;v)
+ 	vcom-&gt;v-&gt;volumeID = 0;
+     tvolName[0] = '/';
+     snprintf(&amp;tvolName[1], sizeof(tvolName)-1, VFORMAT, vcom-&gt;vop-&gt;volume);
+     tvolName[sizeof(tvolName)-1] = '\0';
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     vp = VPreAttachVolumeByName_r(&amp;error, vcom-&gt;vop-&gt;partName, tvolName,
+ 				  V_VOLUPD);
+     if (vp &amp;&amp; vp-&gt;pending_vol_op) {
+ 	VDeregisterVolOp_r(vp, vp-&gt;pending_vol_op);
+     }
+ #else /* AFS_DEMAND_ATTACH_FS */
+     vp = VAttachVolumeByName_r(&amp;error, vcom-&gt;vop-&gt;partName, tvolName,
+ 			       V_VOLUPD);
+     if (vp)
+ 	VPutVolume_r(vp);
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+     if (error) {
+ 	code = SYNC_DENIED;
+ 	res-&gt;hdr.reason = error;
+     }
+ 
+  done:
+     return code;
+ }
+ 
+ static afs_int32
+ FSYNC_com_VolOff(FSSYNC_VolOp_command * vcom, SYNC_response * res)
+ {
+     FSSYNC_VolOp_info info;
+     afs_int32 code = SYNC_OK;
+     int i;
+     Volume * vp, * nvp;
+     Error error;
+ 
+     if (SYNC_verifyProtocolString(vcom-&gt;vop-&gt;partName, sizeof(vcom-&gt;vop-&gt;partName))) {
+ 	res-&gt;hdr.reason = SYNC_REASON_MALFORMED_PACKET;
+ 	code = SYNC_FAILED;
+ 	goto done;
+     }
+ 
+     /* not already offline, we need to find a slot for newly offline volume */
+     if (vcom-&gt;hdr-&gt;programType == debugUtility) {
+ 	/* debug utilities do not have their operations tracked */
+ 	vcom-&gt;v = NULL;
+     } else {
+ 	if (!vcom-&gt;v) {
+ 	    for (i = 0; i &lt; MAXOFFLINEVOLUMES; i++) {
+ 		if (vcom-&gt;volumes[i].volumeID == 0) {
+ 		    vcom-&gt;v = &amp;vcom-&gt;volumes[i];
+ 		    break;
+ 		}
+ 	    }
+ 	}
+ 	if (!vcom-&gt;v) {
+ 	    goto deny;
+ 	}
+     }
+ 
+     FSYNC_com_to_info(vcom, &amp;info);
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     vp = VLookupVolume_r(&amp;error, vcom-&gt;vop-&gt;volume, NULL);
+ #else
+     vp = VGetVolume_r(&amp;error, vcom-&gt;vop-&gt;volume);
+ #endif
+ 
+     if (vp) {
+ 	if ((vcom-&gt;vop-&gt;partName[0] != 0) &amp;&amp;
+ 	    (strncmp(vcom-&gt;vop-&gt;partName, vp-&gt;partition-&gt;name, 
+ 		    sizeof(vcom-&gt;vop-&gt;partName)) != 0)) {
+ 	    /* volume on desired partition is not online, so we
+ 	     * should treat this as an offline volume.
+ 	     */
+ #ifndef AFS_DEMAND_ATTACH_FS
+ 	    VPutVolume_r(vp);
+ #endif
+ 	    vp = NULL;
+ 	    goto done;
+ 	}
+     }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     if (vp) {
+ 	ProgramType type = (ProgramType) vcom-&gt;hdr-&gt;programType;
+ 
+ 	/* do initial filtering of requests */
+ 
+ 	/* enforce mutual exclusion for volume ops */
+ 	if (vp-&gt;pending_vol_op) {
+ 	    if (vp-&gt;pending_vol_op-&gt;com.programType != type) {
+ 		Log("volume %u already checked out\n", vp-&gt;hashid);
+ 		/* XXX debug */
+ 		Log("vp-&gt;vop = { com = { ver=%u, prog=%d, com=%d, reason=%d, len=%u, flags=0x%x }, vop = { vol=%u, part='%s' } }\n",
+ 		    vp-&gt;pending_vol_op-&gt;com.proto_version, 
+ 		    vp-&gt;pending_vol_op-&gt;com.programType,
+ 		    vp-&gt;pending_vol_op-&gt;com.command,
+ 		    vp-&gt;pending_vol_op-&gt;com.reason,
+ 		    vp-&gt;pending_vol_op-&gt;com.command_len,
+ 		    vp-&gt;pending_vol_op-&gt;com.flags,
+ 		    vp-&gt;pending_vol_op-&gt;vop.volume,
+ 		    vp-&gt;pending_vol_op-&gt;vop.partName );
+ 		Log("vcom = { com = { ver=%u, prog=%d, com=%d, reason=%d, len=%u, flags=0x%x } , vop = { vol=%u, part='%s' } }\n",
+ 		    vcom-&gt;hdr-&gt;proto_version,
+ 		    vcom-&gt;hdr-&gt;programType,
+ 		    vcom-&gt;hdr-&gt;command,
+ 		    vcom-&gt;hdr-&gt;reason,
+ 		    vcom-&gt;hdr-&gt;command_len,
+ 		    vcom-&gt;hdr-&gt;flags,
+ 		    vcom-&gt;vop-&gt;volume,
+ 		    vcom-&gt;vop-&gt;partName);
+ 		res-&gt;hdr.reason = FSYNC_EXCLUSIVE;
+ 		goto deny;
+ 	    } else {
+ 		Log("warning: volume %u recursively checked out by programType id %d\n",
+ 		    vp-&gt;hashid, vcom-&gt;hdr-&gt;programType);
+ 	    }
+ 	}
+ 
+ 	/* filter based upon requestor
+ 	 *
+ 	 * volume utilities are not allowed to check out volumes
+ 	 * which are in an error state
+ 	 *
+ 	 * unknown utility programs will be denied on principal
+ 	 */
+ 	switch (type) {
+ 	case salvageServer:
+ 	case debugUtility:
+ 	    /* give the salvageserver lots of liberty */
+ 	    break;
+ 	case volumeUtility:
+ 	    if ((V_attachState(vp) == VOL_STATE_ERROR) ||
+ 		(V_attachState(vp) == VOL_STATE_SALVAGING)) {
+ 		goto deny;
+ 	    }
+ 	    break;
+ 	default:
+ 	    Log("bad program type passed to FSSYNC\n");
+ 	    goto deny;
+ 	}
+ 
+ 	/* short circuit for offline volume states
+ 	 * so we can avoid I/O penalty of attachment */
+ 	switch (V_attachState(vp)) {
+ 	case VOL_STATE_UNATTACHED:
+ 	case VOL_STATE_PREATTACHED:
+ 	case VOL_STATE_SALVAGING:
+ 	case VOL_STATE_ERROR:
+ 	    /* register the volume operation metadata with the volume
+ 	     *
+ 	     * if the volume is currently pre-attached, attach2()
+ 	     * will evaluate the vol op metadata to determine whether
+ 	     * attaching the volume would be safe */
+ 	    VRegisterVolOp_r(vp, &amp;info);
+ 	    goto done;
+ 	default:
+ 	    break;
+ 	}
+ 
+ 	/* convert to heavyweight ref */
+ 	nvp = VGetVolumeByVp_r(&amp;error, vp);
+ 
+ 	/* register the volume operation metadata with the volume */
+ 	VRegisterVolOp_r(vp, &amp;info);
+ 
+ 	if (!nvp) {
+ 	    Log("FSYNC_com_VolOff: failed to get heavyweight reference to volume %u\n",
+ 		vcom-&gt;vop-&gt;volume);
+ 	    res-&gt;hdr.reason = FSYNC_VOL_PKG_ERROR;
+ 	    goto deny;
+ 	}
+ 	vp = nvp;
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+     if (vp) {
+ 	if (VVolOpLeaveOnline_r(vp, &amp;info)) {
+ 	    VUpdateVolume_r(&amp;error, vp, VOL_UPDATE_WAIT);	/* At least get volume stats right */
+ 	    if (LogLevel) {
+ 		Log("FSYNC: Volume %u (%s) was left on line for an external %s request\n", 
+ 		    V_id(vp), V_name(vp), 
+ 		    vcom-&gt;hdr-&gt;reason == V_CLONE ? "clone" : 
+ 		    vcom-&gt;hdr-&gt;reason == V_READONLY ? "readonly" : 
+ 		    vcom-&gt;hdr-&gt;reason == V_DUMP ? "dump" : 
+ 		    "UNKNOWN");
+ 	    }
+ 	    VPutVolume_r(vp);
+ 	} else {
+ 	    if (VVolOpSetVBusy_r(vp, &amp;info)) {
+ 		vp-&gt;specialStatus = VBUSY;
+ 	    }
+ 
+ 	    /* remember what volume we got, so we can keep track of how
+ 	     * many volumes the volserver or whatever is using.  Note that
+ 	     * vp is valid since leaveonline is only set when vp is valid.
+ 	     */
+ 	    if (vcom-&gt;v) {
+ 		vcom-&gt;v-&gt;volumeID = vcom-&gt;vop-&gt;volume;
+ 		strlcpy(vcom-&gt;v-&gt;partName, vp-&gt;partition-&gt;name, sizeof(vcom-&gt;v-&gt;partName));
+ 	    }
+ 
+ 	    VOffline_r(vp, "A volume utility is running.");
+ 	    vp = NULL;
+ 	}
+     }
+ 
+  done:
+     return code;
+ 
+  deny:
+     return SYNC_DENIED;
+ }
+ 
+ static afs_int32
+ FSYNC_com_VolMove(FSSYNC_VolOp_command * vcom, SYNC_response * res)
+ {
+     Error error;
+     Volume * vp;
+ 
+     /* Yuch:  the "reason" for the move is the site it got moved to... */
+     /* still set specialStatus so we stop sending back VBUSY.
+      * also should still break callbacks.  Note that I don't know
+      * how to tell if we should break all or not, so we just do it
+      * since it doesn't matter much if we do an extra break
+      * volume callbacks on a volume move within the same server */
+ #ifdef AFS_DEMAND_ATTACH_FS
+     vp = VLookupVolume_r(&amp;error, vcom-&gt;vop-&gt;volume, NULL);
+ #else
+     vp = VGetVolume_r(&amp;error, vcom-&gt;vop-&gt;volume);
+ #endif
+     if (vp) {
+ 	vp-&gt;specialStatus = VMOVED;
+ #ifndef AFS_DEMAND_ATTACH_FS
+ 	VPutVolume_r(vp);
+ #endif
+     }
+ 
+     if (V_BreakVolumeCallbacks) {
+ 	Log("fssync: volume %u moved to %x; breaking all call backs\n",
+ 	    vcom-&gt;vop-&gt;volume, vcom-&gt;hdr-&gt;reason);
+ 	VOL_UNLOCK;
+ 	(*V_BreakVolumeCallbacks) (vcom-&gt;vop-&gt;volume);
+ 	VOL_LOCK;
+     }
+ 
+     return SYNC_OK;
+ }
+ 
+ static afs_int32
+ FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res)
+ {
+ #ifdef AFS_DEMAND_ATTACH_FS
+     Error error;
+     Volume * vp;
+ #endif
+ 
+     /* don't try to put online, this call is made only after deleting
+      * a volume, in which case we want to remove the vol # from the
+      * OfflineVolumes array only */
+     if (vcom-&gt;v)
+ 	vcom-&gt;v-&gt;volumeID = 0;
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     vp = VLookupVolume_r(&amp;error, vcom-&gt;vop-&gt;volume, NULL);
+     if (vp &amp;&amp; vp-&gt;pending_vol_op) {
+ 	VDeregisterVolOp_r(vp, vp-&gt;pending_vol_op);
+     }
+ #endif
+ 
+     return SYNC_OK;
+ }
+ 
+ static afs_int32
+ FSYNC_com_VolBreakCBKs(FSSYNC_VolOp_command * vcom, SYNC_response * res)
+ {
+     /* if the volume is being restored, break all callbacks on it */
+     if (V_BreakVolumeCallbacks) {
+ 	Log("fssync: breaking all call backs for volume %u\n",
+ 	    vcom-&gt;vop-&gt;volume);
+ 	VOL_UNLOCK;
+ 	(*V_BreakVolumeCallbacks) (vcom-&gt;vop-&gt;volume);
+ 	VOL_LOCK;
+     }
+     return SYNC_OK;
+ }
+ 
+ static afs_int32
+ FSYNC_com_VolQuery(FSSYNC_VolOp_command * vcom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     Error error;
+     Volume * vp;
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     vp = VLookupVolume_r(&amp;error, vcom-&gt;vop-&gt;volume, NULL);
+ #else /* !AFS_DEMAND_ATTACH_FS */
+     vp = VGetVolume_r(&amp;error, vcom-&gt;vop-&gt;volume);
+ #endif /* !AFS_DEMAND_ATTACH_FS */
+ 
+     if (vp) {
+ 	assert(sizeof(Volume) &lt;= res-&gt;payload.len);
+ 	memcpy(res-&gt;payload.buf, vp, sizeof(Volume));
+ 	res-&gt;hdr.response_len += sizeof(Volume);
+ #ifndef AFS_DEMAND_ATTACH_FS
+ 	VPutVolume_r(vp);
+ #endif
+     } else {
+ 	res-&gt;hdr.reason = FSYNC_UNKNOWN_VOLID;
+ 	code = SYNC_FAILED;
+     }
+     return code;
+ }
+ 
+ static afs_int32
+ FSYNC_com_VolHdrQuery(FSSYNC_VolOp_command * vcom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     Error error;
+     Volume * vp;
+     int hdr_ok = 0;
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     vp = VLookupVolume_r(&amp;error, vcom-&gt;vop-&gt;volume, NULL);
+     if (vp &amp;&amp;
+ 	(vp-&gt;header != NULL) &amp;&amp;
+ 	(V_attachFlags(vp) &amp; VOL_HDR_ATTACHED) &amp;&amp;
+ 	(V_attachFlags(vp) &amp; VOL_HDR_LOADED)) {
+ 	hdr_ok = 1;
+     }
+ #else /* !AFS_DEMAND_ATTACH_FS */
+     vp = VGetVolume_r(&amp;error, vcom-&gt;vop-&gt;volume);
+     if (vp &amp;&amp; vp-&gt;header) {
+ 	hdr_ok = 1;
+     }
+ #endif /* !AFS_DEMAND_ATTACH_FS */
+ 
+  load_done:
+     if (hdr_ok) {
+ 	assert(sizeof(VolumeDiskData) &lt;= res-&gt;payload.len);
+ 	memcpy(res-&gt;payload.buf, &amp;V_disk(vp), sizeof(VolumeDiskData));
+ 	res-&gt;hdr.response_len += sizeof(VolumeDiskData);
+ #ifndef AFS_DEMAND_ATTACH_FS
+ 	VPutVolume_r(vp);
+ #endif
+     } else {
+ 	if (vp) {
+ 	    res-&gt;hdr.reason = FSYNC_HDR_NOT_ATTACHED;
+ 	} else {
+ 	    res-&gt;hdr.reason = FSYNC_UNKNOWN_VOLID;
+ 	}
+ 	code = SYNC_FAILED;
+     }
+     return code;
+ }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ static afs_int32
+ FSYNC_com_VolOpQuery(FSSYNC_VolOp_command * vcom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     Error error;
+     Volume * vp;
+ 
+     vp = VLookupVolume_r(&amp;error, vcom-&gt;vop-&gt;volume, NULL);
+ 
+     if (vp &amp;&amp; vp-&gt;pending_vol_op) {
+ 	assert(sizeof(FSSYNC_VolOp_info) &lt;= res-&gt;payload.len);
+ 	memcpy(res-&gt;payload.buf, vp-&gt;pending_vol_op, sizeof(FSSYNC_VolOp_info));
+ 	res-&gt;hdr.response_len += sizeof(FSSYNC_VolOp_info);
+     } else {
+ 	if (vp) {
+ 	    res-&gt;hdr.reason = FSYNC_NO_PENDING_VOL_OP;
+ 	} else {
+ 	    res-&gt;hdr.reason = FSYNC_UNKNOWN_VOLID;
+ 	}
+ 	code = SYNC_FAILED;
+     }
+     return code;
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ static afs_int32
+ FSYNC_com_StatsOp(int fd, SYNC_command * com, SYNC_response * res)
+ {
+     int i;
+     afs_int32 code = SYNC_OK;
+     FSSYNC_StatsOp_command scom;
+ 
+     if (com-&gt;recv_len != (sizeof(com-&gt;hdr) + sizeof(FSSYNC_StatsOp_hdr))) {
+ 	res-&gt;hdr.reason = SYNC_REASON_MALFORMED_PACKET;
+ 	res-&gt;hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;
+ 	return SYNC_COM_ERROR;
+     }
+ 
+     scom.hdr = &amp;com-&gt;hdr;
+     scom.sop = (FSSYNC_StatsOp_hdr *) com-&gt;payload.buf;
+     scom.com = com;
+ 
+     switch (com-&gt;hdr.command) {
+     case FSYNC_VOL_STATS_GENERAL:
+ 	code = FSYNC_com_StatsOpGeneral(&amp;scom, res);
+ 	break;
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	/* statistics for the following subsystems are only tracked
+ 	 * for demand attach fileservers */
+     case FSYNC_VOL_STATS_VICEP:
+ 	code = FSYNC_com_StatsOpViceP(&amp;scom, res);
+ 	break;
+     case FSYNC_VOL_STATS_HASH:
+ 	code = FSYNC_com_StatsOpHash(&amp;scom, res);
+ 	break;
+     case FSYNC_VOL_STATS_HDR:
+ 	code = FSYNC_com_StatsOpHdr(&amp;scom, res);
+ 	break;
+     case FSYNC_VOL_STATS_VLRU:
+ 	code = FSYNC_com_StatsOpVLRU(&amp;scom, res);
+ 	break;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+     default:
+ 	code = SYNC_BAD_COMMAND;
+     }
+ 
+     return code;
+ }
+ 
+ static afs_int32
+ FSYNC_com_StatsOpGeneral(FSSYNC_StatsOp_command * scom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+ 
+     memcpy(res-&gt;payload.buf, &amp;VStats, sizeof(VStats));
+     res-&gt;hdr.response_len += sizeof(VStats);
+ 
+     return code;
+ }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ static afs_int32
+ FSYNC_com_StatsOpViceP(FSSYNC_StatsOp_command * scom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     struct DiskPartition * dp;
+     struct DiskPartitionStats * stats;
+ 
+     if (SYNC_verifyProtocolString(scom-&gt;sop-&gt;args.partName, sizeof(scom-&gt;sop-&gt;args.partName))) {
+ 	res-&gt;hdr.reason = SYNC_REASON_MALFORMED_PACKET;
+ 	code = SYNC_FAILED;
+ 	goto done;
+     }
+ 
+     dp = VGetPartition_r(scom-&gt;sop-&gt;args.partName, 0);
+     if (!dp) {
+ 	code = SYNC_FAILED;
+     } else {
+ 	stats = (struct DiskPartitionStats *) res-&gt;payload.buf;
+ 	stats-&gt;free = dp-&gt;free;
+ 	stats-&gt;totalUsable = dp-&gt;totalUsable;
+ 	stats-&gt;minFree = dp-&gt;minFree;
+ 	stats-&gt;f_files = dp-&gt;f_files;
+ 	stats-&gt;vol_list_len = dp-&gt;vol_list.len;
+ 	
+ 	res-&gt;hdr.response_len += sizeof(struct DiskPartitionStats);
+     }
+ 
+  done:
+     return code;
+ }
+ 
+ static afs_int32
+ FSYNC_com_StatsOpHash(FSSYNC_StatsOp_command * scom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     struct VolumeHashChainStats * stats;
+     struct VolumeHashChainHead * head;
+ 
+     if (scom-&gt;sop-&gt;args.hash_bucket &gt;= VolumeHashTable.Size) {
+ 	return SYNC_FAILED;
+     }
+ 
+     head = &amp;VolumeHashTable.Table[scom-&gt;sop-&gt;args.hash_bucket];
+     stats = (struct VolumeHashChainStats *) res-&gt;payload.buf;
+     stats-&gt;table_size = VolumeHashTable.Size;
+     stats-&gt;chain_len = head-&gt;len;
+     stats-&gt;chain_cacheCheck = head-&gt;cacheCheck;
+     stats-&gt;chain_busy = head-&gt;busy;
+     AssignInt64(head-&gt;looks, &amp;stats-&gt;chain_looks);
+     AssignInt64(head-&gt;gets, &amp;stats-&gt;chain_gets);
+     AssignInt64(head-&gt;reorders, &amp;stats-&gt;chain_reorders);
+ 
+     res-&gt;hdr.response_len += sizeof(struct VolumeHashChainStats);
+     
+     return code;
+ }
+ 
+ static afs_int32
+ FSYNC_com_StatsOpHdr(FSSYNC_StatsOp_command * scom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+ 
+     memcpy(res-&gt;payload.buf, &amp;volume_hdr_LRU.stats, sizeof(volume_hdr_LRU.stats));
+     res-&gt;hdr.response_len += sizeof(volume_hdr_LRU.stats);
+ 
+     return code;
+ }
+ 
+ static afs_int32
+ FSYNC_com_StatsOpVLRU(FSSYNC_StatsOp_command * scom, SYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+ 
+     code = SYNC_BAD_COMMAND;
+ 
+     return code;
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ static void
+ FSYNC_com_to_info(FSSYNC_VolOp_command * vcom, FSSYNC_VolOp_info * info)
+ {
+     memcpy(&amp;info-&gt;com, vcom-&gt;hdr, sizeof(SYNC_command_hdr));
+     memcpy(&amp;info-&gt;vop, vcom-&gt;vop, sizeof(FSSYNC_VolOp_hdr));
+ }
+ 
+ static void
+ FSYNC_Drop(int fd)
+ {
+     struct offlineInfo *p;
+     int i;
+     Error error;
+     char tvolName[VMAXPATHLEN];
+ 
+     VOL_LOCK;
+     p = OfflineVolumes[FindHandler(fd)];
+     for (i = 0; i &lt; MAXOFFLINEVOLUMES; i++) {
+ 	if (p[i].volumeID) {
+ 
+ 	    Volume *vp;
+ 
+ 	    tvolName[0] = '/';
+ 	    sprintf(&amp;tvolName[1], VFORMAT, p[i].volumeID);
+ 	    vp = VAttachVolumeByName_r(&amp;error, p[i].partName, tvolName,
+ 				       V_VOLUPD);
+ 	    if (vp)
+ 		VPutVolume_r(vp);
+ 	    p[i].volumeID = 0;
+ 	}
+     }
+     VOL_UNLOCK;
+     RemoveHandler(fd);
+ #ifdef AFS_NT40_ENV
+     closesocket(fd);
+ #else
+     close(fd);
+ #endif
+     AcceptOn();
+ }
+ 
+ static int AcceptHandler = -1;	/* handler id for accept, if turned on */
+ 
+ static void
+ AcceptOn()
+ {
+     if (AcceptHandler == -1) {
+ 	assert(AddHandler(AcceptSd, FSYNC_newconnection));
+ 	AcceptHandler = FindHandler(AcceptSd);
+     }
+ }
+ 
+ static void
+ AcceptOff()
+ {
+     if (AcceptHandler != -1) {
+ 	assert(RemoveHandler(AcceptSd));
+ 	AcceptHandler = -1;
+     }
+ }
+ 
+ /* The multiple FD handling code. */
+ 
+ static int HandlerFD[MAXHANDLERS];
+ static int (*HandlerProc[MAXHANDLERS]) ();
+ 
+ static void
+ InitHandler()
+ {
+     register int i;
+     ObtainWriteLock(&amp;FSYNC_handler_lock);
+     for (i = 0; i &lt; MAXHANDLERS; i++) {
+ 	HandlerFD[i] = -1;
+ 	HandlerProc[i] = 0;
+     }
+     ReleaseWriteLock(&amp;FSYNC_handler_lock);
+ }
+ 
+ static void
+ CallHandler(fd_set * fdsetp)
+ {
+     register int i;
+     ObtainReadLock(&amp;FSYNC_handler_lock);
+     for (i = 0; i &lt; MAXHANDLERS; i++) {
+ 	if (HandlerFD[i] &gt;= 0 &amp;&amp; FD_ISSET(HandlerFD[i], fdsetp)) {
+ 	    ReleaseReadLock(&amp;FSYNC_handler_lock);
+ 	    (*HandlerProc[i]) (HandlerFD[i]);
+ 	    ObtainReadLock(&amp;FSYNC_handler_lock);
+ 	}
+     }
+     ReleaseReadLock(&amp;FSYNC_handler_lock);
+ }
+ 
+ static int
+ AddHandler(int afd, int (*aproc) ())
+ {
+     register int i;
+     ObtainWriteLock(&amp;FSYNC_handler_lock);
+     for (i = 0; i &lt; MAXHANDLERS; i++)
+ 	if (HandlerFD[i] == -1)
+ 	    break;
+     if (i &gt;= MAXHANDLERS) {
+ 	ReleaseWriteLock(&amp;FSYNC_handler_lock);
+ 	return 0;
+     }
+     HandlerFD[i] = afd;
+     HandlerProc[i] = aproc;
+     ReleaseWriteLock(&amp;FSYNC_handler_lock);
+     return 1;
+ }
+ 
+ static int
+ FindHandler(register int afd)
+ {
+     register int i;
+     ObtainReadLock(&amp;FSYNC_handler_lock);
+     for (i = 0; i &lt; MAXHANDLERS; i++)
+ 	if (HandlerFD[i] == afd) {
+ 	    ReleaseReadLock(&amp;FSYNC_handler_lock);
+ 	    return i;
+ 	}
+     ReleaseReadLock(&amp;FSYNC_handler_lock);	/* just in case */
+     assert(1 == 2);
+     return -1;			/* satisfy compiler */
+ }
+ 
+ static int
+ FindHandler_r(register int afd)
+ {
+     register int i;
+     for (i = 0; i &lt; MAXHANDLERS; i++)
+ 	if (HandlerFD[i] == afd) {
+ 	    return i;
+ 	}
+     assert(1 == 2);
+     return -1;			/* satisfy compiler */
+ }
+ 
+ static int
+ RemoveHandler(register int afd)
+ {
+     ObtainWriteLock(&amp;FSYNC_handler_lock);
+     HandlerFD[FindHandler_r(afd)] = -1;
+     ReleaseWriteLock(&amp;FSYNC_handler_lock);
+     return 1;
+ }
+ 
+ static void
+ GetHandler(fd_set * fdsetp, int *maxfdp)
+ {
+     register int i;
+     register int maxfd = -1;
+     FD_ZERO(fdsetp);
+     ObtainReadLock(&amp;FSYNC_handler_lock);	/* just in case */
+     for (i = 0; i &lt; MAXHANDLERS; i++)
+ 	if (HandlerFD[i] != -1) {
+ 	    FD_SET(HandlerFD[i], fdsetp);
+ 	    if (maxfd &lt; HandlerFD[i])
+ 		maxfd = HandlerFD[i];
+ 	}
+     *maxfdp = maxfd;
+     ReleaseReadLock(&amp;FSYNC_handler_lock);	/* just in case */
+ }
+ 
+ #endif /* FSSYNC_BUILD_SERVER */
Index: openafs/src/vol/fssync.c
diff -c openafs/src/vol/fssync.c:1.30 openafs/src/vol/fssync.c:removed
*** openafs/src/vol/fssync.c:1.30	Thu Jul 21 01:06:27 2005
--- openafs/src/vol/fssync.c	Thu Apr 27 12:42:32 2006
***************
*** 1,751 ****
- /*
-  * Copyright 2000, International Business Machines Corporation and others.
-  * All Rights Reserved.
-  * 
-  * This software has been released under the terms of the IBM Public
-  * License.  For details, see the LICENSE file in the top-level source
-  * directory or online at http://www.openafs.org/dl/license10.html
-  */
- 
- /*
- 	System:		VICE-TWO
- 	Module:		fssync.c
- 	Institution:	The Information Technology Center, Carnegie-Mellon University
- 
-  */
- #ifdef notdef
- 
- /* All this is going away in early 1989 */
- int newVLDB;			/* Compatibility flag */
- 
- #endif
- static int newVLDB = 1;
- 
- 
- #ifndef AFS_PTHREAD_ENV
- #define USUAL_PRIORITY (LWP_MAX_PRIORITY - 2)
- 
- /*
-  * stack size increased from 8K because the HP machine seemed to have trouble
-  * with the smaller stack
-  */
- #define USUAL_STACK_SIZE	(24 * 1024)
- #endif /* !AFS_PTHREAD_ENV */
- 
- /*
-    fsync.c
-    File server synchronization with external volume utilities.
-  */
- 
- /* This controls the size of an fd_set; it must be defined early before
-  * the system headers define that type and the macros that operate on it.
-  * Its value should be as large as the maximum file descriptor limit we
-  * are likely to run into on any platform.  Right now, that is 65536
-  * which is the default hard fd limit on Solaris 9 */
- #ifndef _WIN32
- #define FD_SETSIZE 65536
- #endif
- 
- #include &lt;afsconfig.h&gt;
- #include &lt;afs/param.h&gt;
- 
- RCSID
-     ("$Header: /cvs/openafs/src/vol/Attic/fssync.c,v 1.30 2005/07/21 05:06:27 shadow Exp $");
- 
- #include &lt;sys/types.h&gt;
- #include &lt;stdio.h&gt;
- #ifdef AFS_NT40_ENV
- #include &lt;winsock2.h&gt;
- #include &lt;time.h&gt;
- #else
- #include &lt;sys/param.h&gt;
- #include &lt;sys/socket.h&gt;
- #include &lt;netinet/in.h&gt;
- #include &lt;netdb.h&gt;
- #include &lt;sys/time.h&gt;
- #endif
- #include &lt;errno.h&gt;
- #ifdef AFS_PTHREAD_ENV
- #include &lt;assert.h&gt;
- #else /* AFS_PTHREAD_ENV */
- #include &lt;afs/assert.h&gt;
- #endif /* AFS_PTHREAD_ENV */
- #include &lt;signal.h&gt;
- 
- #ifdef HAVE_STRING_H
- #include &lt;string.h&gt;
- #else
- #ifdef HAVE_STRINGS_H
- #include &lt;strings.h&gt;
- #endif
- #endif
- 
- 
- #include &lt;rx/xdr.h&gt;
- #include &lt;afs/afsint.h&gt;
- #include "nfs.h"
- #include &lt;afs/errors.h&gt;
- #include "fssync.h"
- #include "lwp.h"
- #include "lock.h"
- #include &lt;afs/afssyscalls.h&gt;
- #include "ihandle.h"
- #include "vnode.h"
- #include "volume.h"
- #include "partition.h"
- 
- /*@printflike@*/ extern void Log(const char *format, ...);
- 
- #ifdef osi_Assert
- #undef osi_Assert
- #endif
- #define osi_Assert(e) (void)(e)
- 
- int (*V_BreakVolumeCallbacks) ();
- 
- #define MAXHANDLERS	4	/* Up to 4 clients; must be at least 2, so that
- 				 * move = dump+restore can run on single server */
- #define MAXOFFLINEVOLUMES 128	/* This needs to be as big as the maximum
- 				 * number that would be offline for 1 operation.
- 				 * Current winner is salvage, which needs all
- 				 * cloned read-only copies offline when salvaging
- 				 * a single read-write volume */
- 
- #define MAX_BIND_TRIES	5	/* Number of times to retry socket bind */
- 
- 
- struct offlineInfo {
-     VolumeId volumeID;
-     char partName[16];
- };
- 
- static struct offlineInfo OfflineVolumes[MAXHANDLERS][MAXOFFLINEVOLUMES];
- 
- static FS_sd = -1;		/* Client socket for talking to file server */
- static AcceptSd = -1;		/* Socket used by server for accepting connections */
- 
- static int getport();
- 
- struct command {
-     bit32 command;
-     bit32 reason;
-     VolumeId volume;
-     char partName[16];		/* partition name, e.g. /vicepa */
- };
- 
- /* Forward declarations */
- static void FSYNC_sync();
- static void FSYNC_newconnection();
- static void FSYNC_com();
- static void FSYNC_Drop();
- static void AcceptOn();
- static void AcceptOff();
- static void InitHandler();
- static void CallHandler(fd_set * fdsetp);
- static int AddHandler();
- static int FindHandler();
- static int FindHandler_r();
- static int RemoveHandler();
- static void GetHandler(fd_set * fdsetp, int *maxfdp);
- 
- extern int LogLevel;
- 
- /*
-  * This lock controls access to the handler array. The overhead
-  * is minimal in non-preemptive environments.
-  */
- struct Lock FSYNC_handler_lock;
- 
- int
- FSYNC_clientInit(void)
- {
-     struct sockaddr_in addr;
-     /* I can't believe the following is needed for localhost connections!! */
-     static time_t backoff[] =
- 	{ 3, 3, 3, 5, 5, 5, 7, 15, 16, 24, 32, 40, 48, 0 };
-     time_t *timeout = &amp;backoff[0];
- 
-     for (;;) {
- 	FS_sd = getport(&amp;addr);
- 	if (connect(FS_sd, (struct sockaddr *)&amp;addr, sizeof(addr)) &gt;= 0)
- 	    return 1;
- 	if (!*timeout)
- 	    break;
- 	if (!(*timeout &amp; 1))
- 	    Log("FSYNC_clientInit temporary failure (will retry)");
- 	FSYNC_clientFinis();
- 	sleep(*timeout++);
-     }
-     perror("FSYNC_clientInit failed (giving up!)");
-     return 0;
- }
- 
- void
- FSYNC_clientFinis(void)
- {
- #ifdef AFS_NT40_ENV
-     closesocket(FS_sd);
- #else
-     close(FS_sd);
- #endif
-     FS_sd = -1;
- }
- 
- int
- FSYNC_askfs(VolumeId volume, char *partName, int com, int reason)
- {
-     byte response;
-     struct command command;
-     int n;
-     command.volume = volume;
-     command.command = com;
-     command.reason = reason;
-     if (partName)
- 	strcpy(command.partName, partName);
-     else
- 	command.partName[0] = 0;
-     assert(FS_sd != -1);
-     VFSYNC_LOCK;
- #ifdef AFS_NT40_ENV
-     if (send(FS_sd, (char *)&amp;command, sizeof(command), 0) != sizeof(command)) {
- 	printf("FSYNC_askfs: write to file server failed\n");
- 	response = FSYNC_DENIED;
- 	goto done;
-     }
-     while ((n = recv(FS_sd, &amp;response, 1, 0)) != 1) {
- 	if (n == 0 || WSAEINTR != WSAGetLastError()) {
- 	    printf("FSYNC_askfs: No response from file server\n");
- 	    response = FSYNC_DENIED;
- 	    goto done;
- 	}
-     }
- #else
-     if (write(FS_sd, &amp;command, sizeof(command)) != sizeof(command)) {
- 	printf("FSYNC_askfs: write to file server failed\n");
- 	response = FSYNC_DENIED;
- 	goto done;
-     }
-     while ((n = read(FS_sd, &amp;response, 1)) != 1) {
- 	if (n == 0 || errno != EINTR) {
- 	    printf("FSYNC_askfs: No response from file server\n");
- 	    response = FSYNC_DENIED;
- 	    goto done;
- 	}
-     }
- #endif
-     if (response == 0) {
- 	printf
- 	    ("FSYNC_askfs: negative response from file server; volume %u, command %d\n",
- 	     command.volume, (int)command.command);
-     }
-   done:
-     VFSYNC_UNLOCK;
-     return response;
- }
- 
- void
- FSYNC_fsInit(void)
- {
- #ifdef AFS_PTHREAD_ENV
-     pthread_t tid;
-     pthread_attr_t tattr;
-     assert(pthread_attr_init(&amp;tattr) == 0);
-     assert(pthread_attr_setdetachstate(&amp;tattr, PTHREAD_CREATE_DETACHED) == 0);
-     assert(pthread_create(&amp;tid, &amp;tattr, FSYNC_sync, NULL) == 0);
- #else /* AFS_PTHREAD_ENV */
-     PROCESS pid;
-     assert(LWP_CreateProcess
- 	   (FSYNC_sync, USUAL_STACK_SIZE, USUAL_PRIORITY, (void *)0,
- 	    "FSYNC_sync", &amp;pid) == LWP_SUCCESS);
- #endif /* AFS_PTHREAD_ENV */
- }
- 
- static int
- getport(struct sockaddr_in *addr)
- {
-     int sd;
- 
-     memset(addr, 0, sizeof(*addr));
-     assert((sd = socket(AF_INET, SOCK_STREAM, 0)) &gt;= 0);
- #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
-     addr-&gt;sin_len = sizeof(struct sockaddr_in);
- #endif
-     addr-&gt;sin_addr.s_addr = htonl(0x7f000001);
-     addr-&gt;sin_family = AF_INET;	/* was localhost-&gt;h_addrtype */
-     addr-&gt;sin_port = htons(2040);	/* XXXX htons not _really_ neccessary */
- 
-     return sd;
- }
- 
- static fd_set FSYNC_readfds;
- 
- static void
- FSYNC_sync()
- {
-     struct sockaddr_in addr;
-     int on = 1;
-     extern VInit;
-     int code;
-     int numTries;
- #ifdef AFS_PTHREAD_ENV
-     int tid;
- #endif
- 
- #ifndef AFS_NT40_ENV
-     (void)signal(SIGPIPE, SIG_IGN);
- #endif
- 
- #ifdef AFS_PTHREAD_ENV
-     /* set our 'thread-id' so that the host hold table works */
-     MUTEX_ENTER(&amp;rx_stats_mutex);	/* protects rxi_pthread_hinum */
-     tid = ++rxi_pthread_hinum;
-     MUTEX_EXIT(&amp;rx_stats_mutex);
-     pthread_setspecific(rx_thread_id_key, (void *)tid);
-     Log("Set thread id %d for FSYNC_sync\n", tid);
- #endif /* AFS_PTHREAD_ENV */
- 
-     while (!VInit) {
- 	/* Let somebody else run until level &gt; 0.  That doesn't mean that 
- 	 * all volumes have been attached. */
- #ifdef AFS_PTHREAD_ENV
- 	pthread_yield();
- #else /* AFS_PTHREAD_ENV */
- 	LWP_DispatchProcess();
- #endif /* AFS_PTHREAD_ENV */
-     }
-     AcceptSd = getport(&amp;addr);
-     /* Reuseaddr needed because system inexplicably leaves crud lying around */
-     code =
- 	setsockopt(AcceptSd, SOL_SOCKET, SO_REUSEADDR, (char *)&amp;on,
- 		   sizeof(on));
-     if (code)
- 	Log("FSYNC_sync: setsockopt failed with (%d)\n", errno);
- 
-     for (numTries = 0; numTries &lt; MAX_BIND_TRIES; numTries++) {
- 	if ((code =
- 	     bind(AcceptSd, (struct sockaddr *)&amp;addr, sizeof(addr))) == 0)
- 	    break;
- 	Log("FSYNC_sync: bind failed with (%d), will sleep and retry\n",
- 	    errno);
- 	sleep(5);
-     }
-     assert(!code);
-     listen(AcceptSd, 100);
-     InitHandler();
-     AcceptOn();
-     for (;;) {
- 	int maxfd;
- 	GetHandler(&amp;FSYNC_readfds, &amp;maxfd);
- 	/* Note: check for &gt;= 1 below is essential since IOMGR_select
- 	 * doesn't have exactly same semantics as select.
- 	 */
- #ifdef AFS_PTHREAD_ENV
- 	if (select(maxfd + 1, &amp;FSYNC_readfds, NULL, NULL, NULL) &gt;= 1)
- #else /* AFS_PTHREAD_ENV */
- 	if (IOMGR_Select(maxfd + 1, &amp;FSYNC_readfds, NULL, NULL, NULL) &gt;= 1)
- #endif /* AFS_PTHREAD_ENV */
- 	    CallHandler(&amp;FSYNC_readfds);
-     }
- }
- 
- static void
- FSYNC_newconnection(int afd)
- {
-     struct sockaddr_in other;
-     int junk, fd;
-     junk = sizeof(other);
-     fd = accept(afd, (struct sockaddr *)&amp;other, &amp;junk);
-     if (fd == -1) {
- 	Log("FSYNC_newconnection:  accept failed, errno==%d\n", errno);
- 	assert(1 == 2);
-     } else if (!AddHandler(fd, FSYNC_com)) {
- 	AcceptOff();
- 	assert(AddHandler(fd, FSYNC_com));
-     }
- }
- 
- /*
- #define TEST2081
- */
- 
- afs_int32 FS_cnt = 0;
- static void
- FSYNC_com(int fd)
- {
-     byte rc = FSYNC_OK;
-     int n, i;
-     Error error;
-     struct command command;
-     int leaveonline;
-     register struct offlineInfo *volumes, *v;
-     Volume *vp;
-     char tvolName[VMAXPATHLEN];
- 
-     FS_cnt++;
- #ifdef AFS_NT40_ENV
-     n = recv(fd, &amp;command, sizeof(command), 0);
- #else
-     n = read(fd, &amp;command, sizeof(command));
- #endif
-     if (n &lt;= 0) {
- 	FSYNC_Drop(fd);
- 	return;
-     }
-     if (n &lt; sizeof(command)) {
- 	Log("FSYNC_com:  partial read (%d instead of %d); dropping connection (cnt=%d)\n", n, sizeof(command), FS_cnt);
- 	FSYNC_Drop(fd);
- 	return;
-     }
-     VATTACH_LOCK;
-     VOL_LOCK;
-     volumes = OfflineVolumes[FindHandler(fd)];
-     for (v = 0, i = 0; i &lt; MAXOFFLINEVOLUMES; i++) {
- 	if (volumes[i].volumeID == command.volume
- 	    &amp;&amp; strcmp(volumes[i].partName, command.partName) == 0) {
- 	    v = &amp;volumes[i];
- 	    break;
- 	}
-     }
-     switch (command.command) {
-     case FSYNC_DONE:
- 	/* don't try to put online, this call is made only after deleting
- 	 * a volume, in which case we want to remove the vol # from the
- 	 * OfflineVolumes array only */
- 	if (v)
- 	    v-&gt;volumeID = 0;
- 	break;
-     case FSYNC_ON:
- 
- /*
- This is where a detatched volume gets reattached. However in the
- special case where the volume is merely busy, it is already
- attatched and it is only necessary to clear the busy flag. See
- defect #2080 for details.
- */
- 
- 	/* is the volume already attatched? */
- #ifdef	notdef
- /*
-  * XXX With the following enabled we had bizarre problems where the backup id would
-  * be reset to 0; that was due to the interaction between fileserver/volserver in that they
-  * both keep volumes in memory and the changes wouldn't be made to the fileserver. Some of
-  * the problems were due to refcnt changes as result of VGetVolume/VPutVolume which would call
-  * VOffline, etc. when we don't want to; someday the whole #2080 issue should be revisited to
-  * be done right XXX
-  */
- 	vp = VGetVolume_r(&amp;error, command.volume);
- 	if (vp) {
- 	    /* yep, is the BUSY flag set? */
- 	    if (vp-&gt;specialStatus == VBUSY) {
- /* test harness for defect #2081 */
- 
- #ifdef TEST2081
- 		/*
- 		 * test #2081 by releasing TEST.2081,
- 		 * so leave it alone here, zap it after
- 		 */
- 
- 		if (strcmp(vp-&gt;header-&gt;diskstuff.name, "TEST.2081") == 0)
- 		    break;
- #endif
- 		/* yep, clear BUSY flag */
- 
- 		vp-&gt;specialStatus = 0;
- 		/* make sure vol is online */
- 		if (v) {
- 		    v-&gt;volumeID = 0;
- 		    V_inUse(vp) = 1;	/* online */
- 		}
- 		VPutVolume_r(vp);
- 		break;
- 	    }
- 	    VPutVolume_r(vp);
- 	}
- #endif
- 
- 	/* so, we need to attach the volume */
- 
- 	if (v)
- 	    v-&gt;volumeID = 0;
- 	tvolName[0] = '/';
- 	sprintf(&amp;tvolName[1], VFORMAT, command.volume);
- 
- 	vp = VAttachVolumeByName_r(&amp;error, command.partName, tvolName,
- 				   V_VOLUPD);
- 	if (vp)
- 	    VPutVolume_r(vp);
- 	break;
-     case FSYNC_OFF:
-     case FSYNC_NEEDVOLUME:{
- 	    leaveonline = 0;
- 	    /* not already offline, we need to find a slot for newly offline volume */
- 	    if (!v) {
- 		for (i = 0; i &lt; MAXOFFLINEVOLUMES; i++) {
- 		    if (volumes[i].volumeID == 0) {
- 			v = &amp;volumes[i];
- 			break;
- 		    }
- 		}
- 	    }
- 	    if (!v) {
- 		rc = FSYNC_DENIED;
- 		break;
- 	    }
- 	    vp = VGetVolume_r(&amp;error, command.volume);
- 	    if (vp) {
- 		if (command.partName[0] != 0
- 		    &amp;&amp; strcmp(command.partName, vp-&gt;partition-&gt;name) != 0) {
- 		    /* volume on desired partition is not online, so we
- 		     * should treat this as an offline volume.
- 		     */
- 		    VPutVolume_r(vp);
- 		    vp = (Volume *) 0;
- 		}
- 	    }
- 	    if (vp) {
- 		leaveonline = (command.command == FSYNC_NEEDVOLUME
- 			       &amp;&amp; (command.reason == V_READONLY
- 				   || (!VolumeWriteable(vp)
- 				       &amp;&amp; (command.reason == V_CLONE
- 					   || command.reason == V_DUMP))
- 			       )
- 		    );
- 		if (!leaveonline) {
- 		    if (command.command == FSYNC_NEEDVOLUME
- 			&amp;&amp; (command.reason == V_CLONE
- 			    || command.reason == V_DUMP)) {
- 			vp-&gt;specialStatus = VBUSY;
- 		    }
- 		    /* remember what volume we got, so we can keep track of how
- 		     * many volumes the volserver or whatever is using.  Note that
- 		     * vp is valid since leaveonline is only set when vp is valid.
- 		     */
- 		    v-&gt;volumeID = command.volume;
- 		    strcpy(v-&gt;partName, vp-&gt;partition-&gt;name);
- 		    if (!V_inUse(vp)) {
- 			/* in this case, VOffline just returns sans decrementing
- 			 * ref count.  We could try to fix it, but it has lots of
- 			 * weird callers.
- 			 */
- 			VPutVolume_r(vp);
- 		    } else {
- 			VOffline_r(vp, "A volume utility is running.");
- 		    }
- 		    vp = 0;
- 		} else {
- 		    VUpdateVolume_r(&amp;error, vp);	/* At least get volume stats right */
- 		    if (LogLevel) {
- 			Log("FSYNC: Volume %u (%s) was left on line for an external %s request\n", V_id(vp), V_name(vp), command.reason == V_CLONE ? "clone" : command.reason == V_READONLY ? "readonly" : command.reason == V_DUMP ? "dump" : "UNKNOWN");
- 		    }
- 		}
- 		if (vp)
- 		    VPutVolume_r(vp);
- 	    }
- 	    rc = FSYNC_OK;
- 	    break;
- 	}
-     case FSYNC_MOVEVOLUME:
- 	/* Yuch:  the "reason" for the move is the site it got moved to... */
- 	/* still set specialStatus so we stop sending back VBUSY.
- 	 * also should still break callbacks.  Note that I don't know
- 	 * how to tell if we should break all or not, so we just do it
- 	 * since it doesn't matter much if we do an extra break
- 	 * volume callbacks on a volume move within the same server */
- 	vp = VGetVolume_r(&amp;error, command.volume);
- 	if (vp) {
- 	    vp-&gt;specialStatus = VMOVED;
- 	    VPutVolume_r(vp);
- 	}
- 
- 	if (V_BreakVolumeCallbacks) {
- 	    Log("fssync: volume %u moved to %x; breaking all call backs\n",
- 		command.volume, command.reason);
- 	    VOL_UNLOCK;
- 	    VATTACH_UNLOCK;
- 	    (*V_BreakVolumeCallbacks) (command.volume);
- 	    VATTACH_LOCK;
- 	    VOL_LOCK;
- 	}
- 	break;
-     case FSYNC_RESTOREVOLUME:
- 	/* if the volume is being restored, break all callbacks on it */
- 	if (V_BreakVolumeCallbacks) {
- 	    Log("fssync: volume %u restored; breaking all call backs\n",
- 		command.volume);
- 	    VOL_UNLOCK;
- 	    VATTACH_UNLOCK;
- 	    (*V_BreakVolumeCallbacks) (command.volume);
- 	    VATTACH_LOCK;
- 	    VOL_LOCK;
- 	}
- 	break;
-     default:
- 	rc = FSYNC_DENIED;
- 	break;
-     }
-     VOL_UNLOCK;
-     VATTACH_UNLOCK;
- #ifdef AFS_NT40_ENV
-     (void)send(fd, &amp;rc, 1, 0);
- #else
-     (void)write(fd, &amp;rc, 1);
- #endif
- }
- 
- static void
- FSYNC_Drop(int fd)
- {
-     struct offlineInfo *p;
-     register i;
-     Error error;
-     char tvolName[VMAXPATHLEN];
- 
-     VATTACH_LOCK;
-     VOL_LOCK;
-     p = OfflineVolumes[FindHandler(fd)];
-     for (i = 0; i &lt; MAXOFFLINEVOLUMES; i++) {
- 	if (p[i].volumeID) {
- 	    Volume *vp;
- 
- 	    tvolName[0] = '/';
- 	    sprintf(&amp;tvolName[1], VFORMAT, p[i].volumeID);
- 	    vp = VAttachVolumeByName_r(&amp;error, p[i].partName, tvolName,
- 				       V_VOLUPD);
- 	    if (vp)
- 		VPutVolume_r(vp);
- 	    p[i].volumeID = 0;
- 	}
-     }
-     VOL_UNLOCK;
-     VATTACH_UNLOCK;
-     RemoveHandler(fd);
- #ifdef AFS_NT40_ENV
-     closesocket(fd);
- #else
-     close(fd);
- #endif
-     AcceptOn();
- }
- 
- static int AcceptHandler = -1;	/* handler id for accept, if turned on */
- 
- static void
- AcceptOn()
- {
-     if (AcceptHandler == -1) {
- 	assert(AddHandler(AcceptSd, FSYNC_newconnection));
- 	AcceptHandler = FindHandler(AcceptSd);
-     }
- }
- 
- static void
- AcceptOff()
- {
-     if (AcceptHandler != -1) {
- 	assert(RemoveHandler(AcceptSd));
- 	AcceptHandler = -1;
-     }
- }
- 
- /* The multiple FD handling code. */
- 
- static int HandlerFD[MAXHANDLERS];
- static int (*HandlerProc[MAXHANDLERS]) ();
- 
- static void
- InitHandler()
- {
-     register int i;
-     ObtainWriteLock(&amp;FSYNC_handler_lock);
-     for (i = 0; i &lt; MAXHANDLERS; i++) {
- 	HandlerFD[i] = -1;
- 	HandlerProc[i] = 0;
-     }
-     ReleaseWriteLock(&amp;FSYNC_handler_lock);
- }
- 
- static void
- CallHandler(fd_set * fdsetp)
- {
-     register int i;
-     ObtainReadLock(&amp;FSYNC_handler_lock);
-     for (i = 0; i &lt; MAXHANDLERS; i++) {
- 	if (HandlerFD[i] &gt;= 0 &amp;&amp; FD_ISSET(HandlerFD[i], fdsetp)) {
- 	    ReleaseReadLock(&amp;FSYNC_handler_lock);
- 	    (*HandlerProc[i]) (HandlerFD[i]);
- 	    ObtainReadLock(&amp;FSYNC_handler_lock);
- 	}
-     }
-     ReleaseReadLock(&amp;FSYNC_handler_lock);
- }
- 
- static int
- AddHandler(int afd, int (*aproc) ())
- {
-     register int i;
-     ObtainWriteLock(&amp;FSYNC_handler_lock);
-     for (i = 0; i &lt; MAXHANDLERS; i++)
- 	if (HandlerFD[i] == -1)
- 	    break;
-     if (i &gt;= MAXHANDLERS) {
- 	ReleaseWriteLock(&amp;FSYNC_handler_lock);
- 	return 0;
-     }
-     HandlerFD[i] = afd;
-     HandlerProc[i] = aproc;
-     ReleaseWriteLock(&amp;FSYNC_handler_lock);
-     return 1;
- }
- 
- static int
- FindHandler(register int afd)
- {
-     register int i;
-     ObtainReadLock(&amp;FSYNC_handler_lock);
-     for (i = 0; i &lt; MAXHANDLERS; i++)
- 	if (HandlerFD[i] == afd) {
- 	    ReleaseReadLock(&amp;FSYNC_handler_lock);
- 	    return i;
- 	}
-     ReleaseReadLock(&amp;FSYNC_handler_lock);	/* just in case */
-     assert(1 == 2);
-     return -1;			/* satisfy compiler */
- }
- 
- static int
- FindHandler_r(register int afd)
- {
-     register int i;
-     for (i = 0; i &lt; MAXHANDLERS; i++)
- 	if (HandlerFD[i] == afd) {
- 	    return i;
- 	}
-     assert(1 == 2);
-     return -1;			/* satisfy compiler */
- }
- 
- static int
- RemoveHandler(register int afd)
- {
-     ObtainWriteLock(&amp;FSYNC_handler_lock);
-     HandlerFD[FindHandler_r(afd)] = -1;
-     ReleaseWriteLock(&amp;FSYNC_handler_lock);
-     return 1;
- }
- 
- static void
- GetHandler(fd_set * fdsetp, int *maxfdp)
- {
-     register int i;
-     register int maxfd = -1;
-     FD_ZERO(fdsetp);
-     ObtainReadLock(&amp;FSYNC_handler_lock);	/* just in case */
-     for (i = 0; i &lt; MAXHANDLERS; i++)
- 	if (HandlerFD[i] != -1) {
- 	    FD_SET(HandlerFD[i], fdsetp);
- 	    if (maxfd &lt; HandlerFD[i])
- 		maxfd = HandlerFD[i];
- 	}
-     *maxfdp = maxfd;
-     ReleaseReadLock(&amp;FSYNC_handler_lock);	/* just in case */
- }
--- 0 ----
Index: openafs/src/vol/fssync.h
diff -c openafs/src/vol/fssync.h:1.4 openafs/src/vol/fssync.h:1.5
*** openafs/src/vol/fssync.h:1.4	Tue Jul 15 19:17:38 2003
--- openafs/src/vol/fssync.h	Fri Mar 17 14:54:51 2006
***************
*** 5,10 ****
--- 5,12 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /*
***************
*** 14,51 ****
  
   */
  
  
- /* FSYNC commands */
  
! #define FSYNC_ON		1	/* Volume online */
! #define FSYNC_OFF		2	/* Volume offline */
! #define FSYNC_LISTVOLUMES	3	/* Update local volume list */
! #define FSYNC_NEEDVOLUME	4	/* Put volume in whatever mode (offline, or whatever)
! 					 * best fits the attachment mode provided in reason */
! #define FSYNC_MOVEVOLUME	5	/* Generate temporary relocation information
! 					 * for this volume to another site, to be used
! 					 * if this volume disappears */
! #define	FSYNC_RESTOREVOLUME	6	/* Break all the callbacks on this volume since                                   it is being restored */
! #define FSYNC_DONE		7	/* Done with this volume (used after a delete).
! 					 * Don't put online, but remove from list */
  
  
! /* Reasons (these could be communicated to venus or converted to messages) */
  
- #define FSYNC_WHATEVER		0	/* XXXX */
- #define FSYNC_SALVAGE		1	/* volume is being salvaged */
- #define FSYNC_MOVE		2	/* volume is being moved */
- #define FSYNC_OPERATOR		3	/* operator forced volume offline */
  
  
! /* Replies (1 byte) */
! 
! #define FSYNC_DENIED		0
! #define FSYNC_OK		1
  
  
! /* Prototypes from fssync.c */
! void FSYNC_clientFinis(void);
! int FSYNC_clientInit(void);
! void FSYNC_fsInit(void);
! int FSYNC_askfs(VolumeId volume, char *partName, int com, int reason);
--- 16,132 ----
  
   */
  
+ #ifndef __fssync_h_
+ #define __fssync_h_
  
  
! #define FSYNC_PROTO_VERSION     2
  
  
! /* FSYNC command codes */
! #define FSYNC_VOL_ON		SYNC_COM_CODE_DECL(0)	/* Volume online */
! #define FSYNC_VOL_OFF		SYNC_COM_CODE_DECL(1)	/* Volume offline */
! #define FSYNC_VOL_LISTVOLUMES	SYNC_COM_CODE_DECL(2)	/* Update local volume list */
! #define FSYNC_VOL_NEEDVOLUME	SYNC_COM_CODE_DECL(3)	/* Put volume in whatever mode (offline, or whatever)
! 							 * best fits the attachment mode provided in reason */
! #define FSYNC_VOL_MOVE	        SYNC_COM_CODE_DECL(4)	/* Generate temporary relocation information
! 							 * for this volume to another site, to be used
! 							 * if this volume disappears */
! #define	FSYNC_VOL_BREAKCBKS	SYNC_COM_CODE_DECL(5)	/* Break all the callbacks on this volume */
! #define FSYNC_VOL_DONE		SYNC_COM_CODE_DECL(6)	/* Done with this volume (used after a delete).
! 							 * Don't put online, but remove from list */
! #define FSYNC_VOL_QUERY         SYNC_COM_CODE_DECL(7)   /* query the volume state */
! #define FSYNC_VOL_QUERY_HDR     SYNC_COM_CODE_DECL(8)   /* query the volume disk data structure */
! #define FSYNC_VOL_QUERY_VOP     SYNC_COM_CODE_DECL(9)   /* query the volume for pending vol op info */
! #define FSYNC_VOL_STATS_GENERAL SYNC_COM_CODE_DECL(10)  /* query the general volume package statistics */
! #define FSYNC_VOL_STATS_VICEP   SYNC_COM_CODE_DECL(11)  /* query the per-partition volume package stats */
! #define FSYNC_VOL_STATS_HASH    SYNC_COM_CODE_DECL(12)  /* query the per hash-chain volume package stats */
! #define FSYNC_VOL_STATS_HDR     SYNC_COM_CODE_DECL(13)  /* query the volume header cache statistics */
! #define FSYNC_VOL_STATS_VLRU    SYNC_COM_CODE_DECL(14)  /* query the VLRU statistics */
! 
! /* FSYNC reason codes */
! #define FSYNC_WHATEVER		SYNC_REASON_CODE_DECL(0)  /* XXXX */
! #define FSYNC_SALVAGE		SYNC_REASON_CODE_DECL(1)  /* volume is being salvaged */
! #define FSYNC_MOVE		SYNC_REASON_CODE_DECL(2)  /* volume is being moved */
! #define FSYNC_OPERATOR		SYNC_REASON_CODE_DECL(3)  /* operator forced volume offline */
! #define FSYNC_EXCLUSIVE         SYNC_REASON_CODE_DECL(4)  /* somebody else has the volume offline */
! #define FSYNC_UNKNOWN_VOLID     SYNC_REASON_CODE_DECL(5)  /* volume id not known by fileserver */
! #define FSYNC_HDR_NOT_ATTACHED  SYNC_REASON_CODE_DECL(6)  /* volume header not currently attached */
! #define FSYNC_NO_PENDING_VOL_OP SYNC_REASON_CODE_DECL(7)  /* no volume operation pending */
! #define FSYNC_VOL_PKG_ERROR     SYNC_REASON_CODE_DECL(8)  /* error in the volume package */
! 
! /* FSYNC response codes */
! 
! /* FSYNC flag codes */
! 
! 
! 
! struct offlineInfo {
!     afs_uint32 volumeID;
!     char partName[16];
! };
! 
! typedef struct FSSYNC_VolOp_hdr {
!     afs_uint32 volume;          /* volume id associated with request */
!     char partName[16];		/* partition name, e.g. /vicepa */
! } FSSYNC_VolOp_hdr;
! 
! typedef struct FSSYNC_VolOp_command {
!     SYNC_command_hdr * hdr;
!     FSSYNC_VolOp_hdr * vop;
!     SYNC_command * com;
!     struct offlineInfo * v;
!     struct offlineInfo * volumes;
! } FSSYNC_VolOp_command;
! 
! typedef struct FSSYNC_VolOp_info {
!     SYNC_command_hdr com;
!     FSSYNC_VolOp_hdr vop;
! } FSSYNC_VolOp_info;
! 
! 
! typedef struct FSSYNC_StatsOp_hdr {
!     union {
! 	afs_uint32 vlru_generation;
! 	afs_uint32 hash_bucket;
! 	char partName[16];
!     } args;
! } FSSYNC_StatsOp_hdr;
! 
! typedef struct FSSYNC_StatsOp_command {
!     SYNC_command_hdr * hdr;
!     FSSYNC_StatsOp_hdr * sop;
!     SYNC_command * com;
! } FSSYNC_StatsOp_command;
  
  
  
! /*
!  * common interfaces
!  */
! extern void FSYNC_Init(void);
  
+ /* 
+  * fsync client interfaces 
+  */
+ extern void FSYNC_clientFinis(void);
+ extern int FSYNC_clientInit(void);
+ extern int FSYNC_clientChildProcReconnect(void);
+ 
+ /* generic low-level interface */
+ extern afs_int32 FSYNC_askfs(SYNC_command * com, SYNC_response * res);
+ 
+ /* generic higher-level interface */
+ extern afs_int32 FSYNC_GenericOp(void * ext_hdr, size_t ext_len,
+ 				 int command, int reason,
+ 				 SYNC_response * res);
+ 
+ /* volume operations interface */
+ extern afs_int32 FSYNC_VolOp(VolumeId volume, char *partName, int com, int reason, 
+ 			     SYNC_response * res);
+ 
+ /* statistics query interface */
+ extern afs_int32 FSYNC_StatsOp(FSSYNC_StatsOp_hdr * scom, int command, int reason,
+ 			       SYNC_response * res_in);
  
! #endif /* __fssync_h_ */
Index: openafs/src/vol/fstab.c
diff -c openafs/src/vol/fstab.c:1.4 openafs/src/vol/fstab.c:removed
*** openafs/src/vol/fstab.c:1.4	Wed Aug 18 20:22:38 2004
--- openafs/src/vol/fstab.c	Thu Apr 27 12:42:32 2006
***************
*** 1,181 ****
- /*
-  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
-  *
-  * @APPLE_LICENSE_HEADER_START@
-  * 
-  * This file contains Original Code and/or Modifications of Original Code
-  * as defined in and that are subject to the Apple Public Source License
-  * Version 2.0 (the 'License'). You may not use this file except in
-  * compliance with the License. Please obtain a copy of the License at
-  * http://www.opensource.apple.com/apsl/ and read it before using this
-  * file.
-  * 
-  * The Original Code and all software distributed under the License are
-  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
-  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
-  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
-  * Please see the License for the specific language governing rights and
-  * limitations under the License.
-  * 
-  * @APPLE_LICENSE_HEADER_END@
-  */
- /*
-  * Copyright (c) 1980, 1988, 1993
-  *	The Regents of the University of California.  All rights reserved.
-  *
-  * Redistribution and use in source and binary forms, with or without
-  * modification, are permitted provided that the following conditions
-  * are met:
-  * 1. Redistributions of source code must retain the above copyright
-  *    notice, this list of conditions and the following disclaimer.
-  * 2. Redistributions in binary form must reproduce the above copyright
-  *    notice, this list of conditions and the following disclaimer in the
-  *    documentation and/or other materials provided with the distribution.
-  * 3. All advertising materials mentioning features or use of this software
-  *    must display the following acknowledgement:
-  *	This product includes software developed by the University of
-  *	California, Berkeley and its contributors.
-  * 4. Neither the name of the University nor the names of its contributors
-  *    may be used to endorse or promote products derived from this software
-  *    without specific prior written permission.
-  *
-  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-  * SUCH DAMAGE.
-  */
- 
- #include &lt;afs/param.h&gt;
- 
- #if defined(AFS_DARWIN_ENV)
- /*-----------------------------------------------------------------------
-  * This version of fstab.c is intended to be used on Darwin systems to
-  * replace getfsent() and family.  It has been modified so that rather
-  * than read /etc/fstab, it calls getfsstat() to get the real list of
-  * mounted volumes.
-  *-----------------------------------------------------------------------*/
- 
- #include &lt;errno.h&gt;
- #include &lt;fstab.h&gt;
- #include &lt;stdio.h&gt;
- #include &lt;string.h&gt;
- #include &lt;stdlib.h&gt;
- #include &lt;sys/param.h&gt;
- #include &lt;sys/ucred.h&gt;
- #include &lt;sys/mount.h&gt;
- 
- #define	STDERR_FILENO	2
- 
- static struct fstab _fs_fstab;
- static struct statfs *_fs_buf;
- static struct statfs *_fs_ptr;
- static int _fs_count;
- 
- static error __P((int));
- static fstabscan __P((void));
- 
- static
- fstabscan()
- {
-     if (_fs_count &lt;= 0)
- 	return (0);
-     _fs_fstab.fs_spec = _fs_ptr-&gt;f_mntfromname;
-     _fs_fstab.fs_file = _fs_ptr-&gt;f_mntonname;
-     _fs_fstab.fs_vfstype = _fs_ptr-&gt;f_fstypename;
-     _fs_fstab.fs_mntops = _fs_ptr-&gt;f_fstypename;	// no mount options given
-     _fs_fstab.fs_type = (_fs_ptr-&gt;f_flags &amp; MNT_RDONLY) ? FSTAB_RO : FSTAB_RW;
-     _fs_fstab.fs_freq = 0;
-     _fs_fstab.fs_passno = 0;
- 
-     _fs_ptr++;
-     _fs_count--;
-     return (1);
- }
- 
- struct fstab *
- getfsent()
- {
-     if (!_fs_buf &amp;&amp; !setfsent() || !fstabscan())
- 	return ((struct fstab *)NULL);
-     return (&amp;_fs_fstab);
- }
- 
- struct fstab *
- getfsspec(name)
-      register const char *name;
- {
-     if (setfsent())
- 	while (fstabscan())
- 	    if (!strcmp(_fs_fstab.fs_spec, name))
- 		return (&amp;_fs_fstab);
-     return ((struct fstab *)NULL);
- }
- 
- struct fstab *
- getfsfile(name)
-      register const char *name;
- {
-     if (setfsent())
- 	while (fstabscan())
- 	    if (!strcmp(_fs_fstab.fs_file, name))
- 		return (&amp;_fs_fstab);
-     return ((struct fstab *)NULL);
- }
- 
- setfsent()
- {
-     long bufsize;
- 
-     if (_fs_buf) {
- 	free(_fs_buf);
- 	_fs_buf = NULL;
-     }
-     if ((_fs_count = getfsstat(NULL, 0, MNT_WAIT)) &lt; 0) {
- 	error(errno);
- 	return (0);
-     }
-     bufsize = (long)_fs_count *sizeof(struct statfs);
-     if ((_fs_buf = malloc(bufsize)) == NULL) {
- 	error(errno);
- 	return (0);
-     }
-     if (getfsstat(_fs_buf, bufsize, MNT_WAIT) &lt; 0) {
- 	error(errno);
- 	return (0);
-     }
-     _fs_ptr = _fs_buf;
-     return (1);
- }
- 
- void
- endfsent()
- {
-     if (_fs_buf) {
- 	free(_fs_buf);
- 	_fs_buf = NULL;
-     }
-     _fs_count = 0;
- }
- 
- static
- error(err)
-      int err;
- {
-     char *p;
- 
-     (void)write(STDERR_FILENO, "fstab: ", 7);
-     (void)write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1);
-     (void)write(STDERR_FILENO, ": ", 1);
-     p = strerror(err);
-     (void)write(STDERR_FILENO, p, strlen(p));
-     (void)write(STDERR_FILENO, "\n", 1);
- }
- #endif /* defined(AFS_DARWIN_ENV) */
--- 0 ----
Index: openafs/src/vol/ihandle.h
diff -c openafs/src/vol/ihandle.h:1.9 openafs/src/vol/ihandle.h:1.10
*** openafs/src/vol/ihandle.h:1.9	Wed Aug 18 20:22:38 2004
--- openafs/src/vol/ihandle.h	Wed Apr 26 11:43:17 2006
***************
*** 221,226 ****
--- 221,227 ----
  
  /* Flags for the Inode handle */
  #define IH_REALLY_CLOSED		1
+ #define IH_DELAY_SYNC			16
  
  /* Hash function for inode handles */
  #define I_HANDLE_HASH_SIZE	1024	/* power of 2 */
***************
*** 466,472 ****
  #define FDH_WRITE(H, B, S) OS_WRITE((H)-&gt;fd_fd, B, S)
  #define FDH_SEEK(H, O, F) OS_SEEK((H)-&gt;fd_fd, O, F)
  
! #define FDH_SYNC(H) OS_SYNC((H)-&gt;fd_fd)
  #define FDH_TRUNC(H, L) OS_TRUNC((H)-&gt;fd_fd, L)
  #define FDH_SIZE(H) OS_SIZE((H)-&gt;fd_fd)
  
--- 467,473 ----
  #define FDH_WRITE(H, B, S) OS_WRITE((H)-&gt;fd_fd, B, S)
  #define FDH_SEEK(H, O, F) OS_SEEK((H)-&gt;fd_fd, O, F)
  
! #define FDH_SYNC(H) ((H-&gt;fd_ih-&gt;ih_flags&amp;IH_DELAY_SYNC) ? 0 : OS_SYNC((H)-&gt;fd_fd))
  #define FDH_TRUNC(H, L) OS_TRUNC((H)-&gt;fd_fd, L)
  #define FDH_SIZE(H) OS_SIZE((H)-&gt;fd_fd)
  
Index: openafs/src/vol/namei_ops.c
diff -c openafs/src/vol/namei_ops.c:1.27 openafs/src/vol/namei_ops.c:1.28
*** openafs/src/vol/namei_ops.c:1.27	Tue Nov  1 11:42:47 2005
--- openafs/src/vol/namei_ops.c	Wed Apr 26 11:43:17 2006
***************
*** 13,19 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/namei_ops.c,v 1.27 2005/11/01 16:42:47 shadow Exp $");
  
  #ifdef AFS_NAMEI_ENV
  #include &lt;stdio.h&gt;
--- 13,19 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/namei_ops.c,v 1.28 2006/04/26 15:43:17 shadow Exp $");
  
  #ifdef AFS_NAMEI_ENV
  #include &lt;stdio.h&gt;
***************
*** 572,577 ****
--- 572,579 ----
  
      if (p2 == -1 &amp;&amp; p3 == VI_LINKTABLE) {
  	/* hack at tmp to setup for set link count call. */
+ 	memset((void *)&amp;tfd, 0, sizeof(FdHandle_t));	/* minimalistic still, but a little cleaner */
+ 	tfd.fd_ih = &amp;tmp;
  	tfd.fd_fd = fd;
  	code = namei_SetLinkCount(&amp;tfd, (Inode) 0, 1, 0);
      }
Index: openafs/src/vol/nuke.c
diff -c openafs/src/vol/nuke.c:1.16 openafs/src/vol/nuke.c:1.17
*** openafs/src/vol/nuke.c:1.16	Sat Oct  2 11:54:28 2004
--- openafs/src/vol/nuke.c	Fri Mar 17 14:54:51 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/nuke.c,v 1.16 2004/10/02 15:54:28 shadow Exp $");
  
  #include &lt;rx/xdr.h&gt;
  #include &lt;afs/afsint.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/nuke.c,v 1.17 2006/03/17 19:54:51 shadow Exp $");
  
  #include &lt;rx/xdr.h&gt;
  #include &lt;afs/afsint.h&gt;
***************
*** 41,46 ****
--- 41,47 ----
  #include "partition.h"
  #include "viceinode.h"
  #include "salvage.h"
+ #include "daemon_com.h"
  #include "fssync.h"
  
  #ifdef O_LARGEFILE
Index: openafs/src/vol/partition.c
diff -c openafs/src/vol/partition.c:1.32 openafs/src/vol/partition.c:1.33
*** openafs/src/vol/partition.c:1.32	Mon Oct 17 16:45:39 2005
--- openafs/src/vol/partition.c	Fri Mar 17 14:54:51 2006
***************
*** 7,12 ****
--- 7,13 ----
   * directory or online at http://www.openafs.org/dl/license10.html
   *
   * Portions Copyright (c) 2003 Apple Computer, Inc.
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /*
***************
*** 21,27 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/partition.c,v 1.32 2005/10/17 20:45:39 shadow Exp $");
  
  #include &lt;ctype.h&gt;
  #ifdef AFS_NT40_ENV
--- 22,28 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/partition.c,v 1.33 2006/03/17 19:54:51 shadow Exp $");
  
  #include &lt;ctype.h&gt;
  #ifdef AFS_NT40_ENV
***************
*** 189,194 ****
--- 190,203 ----
  int aixlow_water = 8;		/* default 8% */
  struct DiskPartition *DiskPartitionList;
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ static struct DiskPartition *DiskPartitionTable[VOLMAXPARTS+1];
+ 
+ static struct DiskPartition * VLookupPartition_r(char * path);
+ static void AddPartitionToTable_r(struct DiskPartition *);
+ static void DeletePartitionFromTable_r(struct DiskPartition *);
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  #ifdef AFS_SGI_XFS_IOPS_ENV
  /* Verify that the on disk XFS inodes on the partition are large enough to
   * hold the AFS attribute. Returns -1 if the attribute can't be set or is
***************
*** 225,232 ****
      }
      return code;
  }
! #endif
  
  
  static void
  VInitPartition_r(char *path, char *devname, Device dev)
--- 234,249 ----
      }
      return code;
  }
! #endif /* AFS_SGI_XFS_IOPS_ENV */
  
+ int
+ VInitPartitionPackage(void)
+ {
+ #ifdef AFS_DEMAND_ATTACH_ENV
+     memset(&amp;DiskPartitionTable, 0, sizeof(DiskPartitionTable));
+ #endif /* AFS_DEMAND_ATTACH_ENV */
+     return 0;
+ }
  
  static void
  VInitPartition_r(char *path, char *devname, Device dev)
***************
*** 245,250 ****
--- 262,268 ----
      dp-&gt;next = 0;
      dp-&gt;name = (char *)malloc(strlen(path) + 1);
      strncpy(dp-&gt;name, path, strlen(path) + 1);
+     dp-&gt;index = volutil_GetPartitionID(path);
  #if defined(AFS_NAMEI_ENV) &amp;&amp; !defined(AFS_NT40_ENV)
      /* Create a lockfile for the partition, of the form /vicepa/Lock/vicepa */
      dp-&gt;devName = (char *)malloc(2 * strlen(path) + 6);
***************
*** 254,260 ****
      mkdir(dp-&gt;devName, 0700);
      strcat(dp-&gt;devName, path);
      close(afs_open(dp-&gt;devName, O_RDWR | O_CREAT, 0600));
!     dp-&gt;device = volutil_GetPartitionID(path);
  #else
      dp-&gt;devName = (char *)malloc(strlen(devname) + 1);
      strncpy(dp-&gt;devName, devname, strlen(devname) + 1);
--- 272,278 ----
      mkdir(dp-&gt;devName, 0700);
      strcat(dp-&gt;devName, path);
      close(afs_open(dp-&gt;devName, O_RDWR | O_CREAT, 0600));
!     dp-&gt;device = dp-&gt;index;
  #else
      dp-&gt;devName = (char *)malloc(strlen(devname) + 1);
      strncpy(dp-&gt;devName, devname, strlen(devname) + 1);
***************
*** 268,273 ****
--- 286,296 ----
  	(void)namei_ViceREADME(VPartitionPath(dp));
  #endif
      VSetPartitionDiskUsage_r(dp);
+ #ifdef AFS_DEMAND_ATTACH_FS
+     AddPartitionToTable_r(dp);
+     queue_Init(&amp;dp-&gt;vol_list);
+     assert(pthread_cond_init(&amp;dp-&gt;vol_list.cv, NULL) == 0);
+ #endif /* AFS_DEMAND_ATTACH_FS */
  }
  
  static void
***************
*** 352,358 ****
  	return -1;
  #endif
  #endif /* AFS_NAMEI_ENV */
! #endif
  
  #if defined(AFS_DUX40_ENV) &amp;&amp; !defined(AFS_NAMEI_ENV)
      if (status.st_ino != ROOTINO) {
--- 375,381 ----
  	return -1;
  #endif
  #endif /* AFS_NAMEI_ENV */
! #endif /* !AFS_LINUX20_ENV &amp;&amp; !AFS_NT40_ENV */
  
  #if defined(AFS_DUX40_ENV) &amp;&amp; !defined(AFS_NAMEI_ENV)
      if (status.st_ino != ROOTINO) {
***************
*** 825,834 ****
--- 848,861 ----
  VGetPartition_r(char *name, int abortp)
  {
      register struct DiskPartition *dp;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     dp = VLookupPartition_r(name);
+ #else /* AFS_DEMAND_ATTACH_FS */
      for (dp = DiskPartitionList; dp; dp = dp-&gt;next) {
  	if (strcmp(dp-&gt;name, name) == 0)
  	    break;
      }
+ #endif /* AFS_DEMAND_ATTACH_FS */
      if (abortp)
  	assert(dp != NULL);
      return dp;
***************
*** 1234,1236 ****
--- 1261,1320 ----
      VUnlockPartition_r(name);
      VOL_UNLOCK;
  }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /* XXX not sure this will work on AFS_NT40_ENV
+  * needs to be tested!
+  */
+ struct DiskPartition * 
+ VGetPartitionById_r(afs_int32 id, int abortp)
+ {
+     struct DiskPartition * dp = NULL;
+ 
+     if ((id &gt;= 0) &amp;&amp; (id &lt;= VOLMAXPARTS)) {
+ 	dp = DiskPartitionTable[id];
+     }
+ 
+     if (abortp) {
+ 	assert(dp != NULL);
+     }
+     return dp;
+ }
+ 
+ struct DiskPartition *
+ VGetPartitionById(afs_int32 id, int abortp)
+ {
+     struct Diskpartition * dp;
+ 
+     VOL_LOCK;
+     dp = VGetPartitionById_r(id, abortp);
+     VOL_UNLOCK;
+ 
+     return dp;
+ }
+ 
+ static struct DiskPartition * 
+ VLookupPartition_r(char * path)
+ {
+     afs_int32 id = volutil_GetPartitionID(path);
+ 
+     if (id &lt; 0 || id &gt; VOLMAXPARTS)
+ 	return NULL;
+ 
+     return DiskPartitionTable[id];
+ }
+ 
+ static void 
+ AddPartitionToTable_r(struct DiskPartition * dp)
+ {
+     assert(dp-&gt;index &gt;= 0 &amp;&amp; dp-&gt;index &lt;= VOLMAXPARTS);
+     DiskPartitionTable[dp-&gt;index] = dp;
+ }
+ 
+ static void 
+ DeletePartitionFromTable_r(struct DiskPartition * dp)
+ {
+     assert(dp-&gt;index &gt;= 0 &amp;&amp; dp-&gt;index &lt;= VOLMAXPARTS);
+     DiskPartitionTable[dp-&gt;index] = NULL;
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
Index: openafs/src/vol/partition.h
diff -c openafs/src/vol/partition.h:1.9 openafs/src/vol/partition.h:1.10
*** openafs/src/vol/partition.h:1.9	Fri Aug  8 16:40:45 2003
--- openafs/src/vol/partition.h	Fri Mar 17 14:54:51 2006
***************
*** 5,10 ****
--- 5,12 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /*
***************
*** 27,32 ****
--- 29,35 ----
  #define	AFS_RDSKDEV	"/dev/r"
  #endif
  
+ 
  /* All Vice partitions on a server will have the following name prefix */
  #define VICE_PARTITION_PREFIX	"/vicep"
  #define VICE_PREFIX_SIZE	(sizeof(VICE_PARTITION_PREFIX)-1)
***************
*** 53,58 ****
--- 56,62 ----
      char *name;			/* Mounted partition name */
      char *devName;		/* Device mounted on */
      Device device;		/* device number */
+     afs_int32 index;            /* partition index (0&lt;=x&lt;=VOLMAXPARTS) */
      int lock_fd;		/* File descriptor of this partition if locked; otherwise -1;
  				 * Not used by the file server */
      int free;			/* Total number of blocks (1K) presumed
***************
*** 77,83 ****
--- 81,106 ----
  				 * from the superblock */
      int flags;
      int f_files;		/* total number of files in this partition */
+ #ifdef AFS_DEMAND_ATTACH_FS
+     struct {
+ 	struct rx_queue head;   /* list of volumes on this partition (VByPList) */
+ 	afs_uint32 len;         /* length of volume list */
+ 	int busy;               /* asynch vol list op in progress */
+ 	pthread_cond_t cv;      /* vol_list.busy change cond var */
+     } vol_list;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ };
+ 
+ struct DiskPartitionStats {
+     afs_int32 free;
+     afs_int32 totalUsable;
+     afs_int32 minFree;
+     afs_int32 f_files;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     afs_int32 vol_list_len;
+ #endif
  };
+ 
  #define	PART_DONTUPDATE	1
  #define PART_DUPLICATE  2	/* NT - used if we find more than one partition 
  				 * using the same drive. Will be dumped before
***************
*** 93,99 ****
  struct Volume;			/* Potentially forward definition */
  
  extern struct DiskPartition *DiskPartitionList;
! extern struct DiskPartition *VGetPartition();
  extern int VAttachPartitions(void);
  extern void VLockPartition(char *name);
  extern void VLockPartition_r(char *name);
--- 116,127 ----
  struct Volume;			/* Potentially forward definition */
  
  extern struct DiskPartition *DiskPartitionList;
! extern struct DiskPartition *VGetPartition(char * name, int abortp);
! extern struct DiskPartition *VGetPartition_r(char * name, int abortp);
! #ifdef AFS_DEMAND_ATTACH_FS
! extern struct DiskPartition *VGetPartitionById(afs_int32 index, int abortp);
! extern struct DiskPartition *VGetPartitionById_r(afs_int32 index, int abortp);
! #endif
  extern int VAttachPartitions(void);
  extern void VLockPartition(char *name);
  extern void VLockPartition_r(char *name);
***************
*** 108,110 ****
--- 136,139 ----
  			     afs_sfsize_t blocks, afs_sfsize_t checkBlocks);
  extern int VDiskUsage(struct Volume *vp, afs_sfsize_t blocks);
  extern void VPrintDiskStats(void);
+ extern int VInitPartitionPackage(void);
Index: openafs/src/vol/purge.c
diff -c openafs/src/vol/purge.c:1.10 openafs/src/vol/purge.c:1.12
*** openafs/src/vol/purge.c:1.10	Wed Aug 18 20:22:38 2004
--- openafs/src/vol/purge.c	Wed Apr 26 11:43:17 2006
***************
*** 17,23 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/purge.c,v 1.10 2004/08/19 00:22:38 kolya Exp $");
  
  #include &lt;stdio.h&gt;
  #ifdef AFS_NT40_ENV
--- 17,23 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/purge.c,v 1.12 2006/04/26 15:43:17 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #ifdef AFS_NT40_ENV
***************
*** 52,62 ****
  #include "volume.h"
  #include "viceinode.h"
  #include "partition.h"
  #include "fssync.h"
  
  /* forward declarations */
! void PurgeIndex_r(Volume * vp, VnodeClass class);
! void PurgeHeader_r(Volume * vp);
  
  void
  VPurgeVolume_r(Error * ec, Volume * vp)
--- 52,67 ----
  #include "volume.h"
  #include "viceinode.h"
  #include "partition.h"
+ #include "daemon_com.h"
  #include "fssync.h"
  
  /* forward declarations */
! static int ObliterateRegion(Volume * avp, VnodeClass aclass, StreamHandle_t * afile,
! 			    afs_int32 * aoffset);
! static void PurgeIndex(Volume * vp, VnodeClass class);
! static void PurgeIndex_r(Volume * vp, VnodeClass class);
! static void PurgeHeader_r(Volume * vp);
! static void PurgeHeader(Volume * vp);
  
  void
  VPurgeVolume_r(Error * ec, Volume * vp)
***************
*** 78,84 ****
      /*
       * Call the fileserver to break all call backs for that volume
       */
!     FSYNC_askfs(V_id(vp), tpartp-&gt;name, FSYNC_RESTOREVOLUME, 0);
  }
  
  void
--- 83,89 ----
      /*
       * Call the fileserver to break all call backs for that volume
       */
!     FSYNC_VolOp(V_id(vp), tpartp-&gt;name, FSYNC_VOL_BREAKCBKS, 0, NULL);
  }
  
  void
***************
*** 89,95 ****
      VOL_UNLOCK;
  }
  
! #define MAXOBLITATONCE	200
  /* delete a portion of an index, adjusting offset appropriately.  Returns 0 if
     things work and we should be called again, 1 if success full and done, and -1
     if an error occurred.  It adjusts offset appropriately on 0 or 1 return codes,
--- 94,100 ----
      VOL_UNLOCK;
  }
  
! #define MAXOBLITATONCE	1000
  /* delete a portion of an index, adjusting offset appropriately.  Returns 0 if
     things work and we should be called again, 1 if success full and done, and -1
     if an error occurred.  It adjusts offset appropriately on 0 or 1 return codes,
***************
*** 148,157 ****
--- 153,165 ----
      OS_SYNC(afile-&gt;str_fd);
  
      /* finally, do the idec's */
+     V_linkHandle(avp)-&gt;ih_flags|=IH_DELAY_SYNC;		/* severe performance penalty */
      for (i = 0; i &lt; iindex; i++) {
  	IH_DEC(V_linkHandle(avp), inodes[i], V_parentId(avp));
  	DOPOLL;
      }
+     V_linkHandle(avp)-&gt;ih_flags&amp;=~IH_DELAY_SYNC;
+     IH_CONDSYNC(V_linkHandle(avp));
  
      /* return the new offset */
      *aoffset = offset;
***************
*** 161,167 ****
      return -1;
  }
  
! void
  PurgeIndex(Volume * vp, VnodeClass class)
  {
      VOL_LOCK;
--- 169,175 ----
      return -1;
  }
  
! static void
  PurgeIndex(Volume * vp, VnodeClass class)
  {
      VOL_LOCK;
***************
*** 169,175 ****
      VOL_UNLOCK;
  }
  
! void
  PurgeIndex_r(Volume * vp, VnodeClass class)
  {
      StreamHandle_t *ifile;
--- 177,183 ----
      VOL_UNLOCK;
  }
  
! static void
  PurgeIndex_r(Volume * vp, VnodeClass class)
  {
      StreamHandle_t *ifile;
***************
*** 199,205 ****
      FDH_CLOSE(fdP);
  }
  
! void
  PurgeHeader(Volume * vp)
  {
      VOL_LOCK;
--- 207,213 ----
      FDH_CLOSE(fdP);
  }
  
! static void
  PurgeHeader(Volume * vp)
  {
      VOL_LOCK;
***************
*** 207,213 ****
      VOL_UNLOCK;
  }
  
! void
  PurgeHeader_r(Volume * vp)
  {
      IH_REALLYCLOSE(V_diskDataHandle(vp));
--- 215,221 ----
      VOL_UNLOCK;
  }
  
! static void
  PurgeHeader_r(Volume * vp)
  {
      IH_REALLYCLOSE(V_diskDataHandle(vp));
Index: openafs/src/vol/salvage.h
diff -c openafs/src/vol/salvage.h:1.4 openafs/src/vol/salvage.h:1.5
*** openafs/src/vol/salvage.h:1.4	Tue Jul 15 19:17:40 2003
--- openafs/src/vol/salvage.h	Fri Mar 17 14:54:51 2006
***************
*** 14,19 ****
--- 14,22 ----
  
   */
  
+ #ifndef __salvage_h_
+ #define __salvage_h_
+ 
  #include &lt;afs/afssyscalls.h&gt;
  /* Definition of DirHandle for salvager.  Not the same as for the file server */
  
***************
*** 24,26 ****
--- 27,31 ----
      IHandle_t *dirh_handle;
      afs_int32 dirh_cacheCheck;
  } DirHandle;
+ 
+ #endif /* __salvage_h_ */
Index: openafs/src/vol/salvaged.c
diff -c /dev/null openafs/src/vol/salvaged.c:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/salvaged.c	Fri Mar 17 23:20:19 2006
***************
*** 0 ****
--- 1,738 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /* 
+  * demand attach fs
+  * online salvager daemon
+  */
+ 
+ /* Main program file. Define globals. */
+ #define MAIN 1
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/vol/salvaged.c,v 1.1 2006/03/18 04:20:19 shadow Exp $");
+ 
+ #include &lt;stdlib.h&gt;
+ #include &lt;stdio.h&gt;
+ #include &lt;string.h&gt;
+ #include &lt;dirent.h&gt;
+ #include &lt;sys/stat.h&gt;
+ #include &lt;time.h&gt;
+ #include &lt;errno.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;io.h&gt;
+ #include &lt;WINNT/afsevent.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/file.h&gt;
+ #ifndef ITIMER_REAL
+ #include &lt;sys/time.h&gt;
+ #endif /* ITIMER_REAL */
+ #endif
+ #if	defined(AFS_AIX_ENV) || defined(AFS_SUN4_ENV)
+ #define WCOREDUMP(x)	(x &amp; 0200)
+ #endif
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include &lt;afs/assert.h&gt;
+ #if !defined(AFS_SGI_ENV) &amp;&amp; !defined(AFS_NT40_ENV)
+ #if defined(AFS_VFSINCL_ENV)
+ #include &lt;sys/vnode.h&gt;
+ #ifdef	AFS_SUN5_ENV
+ #include &lt;sys/fs/ufs_inode.h&gt;
+ #else
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+ #include &lt;ufs/ufs/dinode.h&gt;
+ #include &lt;ufs/ffs/fs.h&gt;
+ #else
+ #include &lt;ufs/inode.h&gt;
+ #endif
+ #endif
+ #else /* AFS_VFSINCL_ENV */
+ #ifdef	AFS_OSF_ENV
+ #include &lt;ufs/inode.h&gt;
+ #else /* AFS_OSF_ENV */
+ #if !defined(AFS_LINUX20_ENV) &amp;&amp; !defined(AFS_XBSD_ENV)
+ #include &lt;sys/inode.h&gt;
+ #endif
+ #endif
+ #endif /* AFS_VFSINCL_ENV */
+ #endif /* AFS_SGI_ENV */
+ #ifdef	AFS_AIX_ENV
+ #include &lt;sys/vfs.h&gt;
+ #include &lt;sys/lockf.h&gt;
+ #else
+ #ifdef	AFS_HPUX_ENV
+ #include &lt;unistd.h&gt;
+ #include &lt;checklist.h&gt;
+ #else
+ #if defined(AFS_SGI_ENV)
+ #include &lt;unistd.h&gt;
+ #include &lt;fcntl.h&gt;
+ #include &lt;mntent.h&gt;
+ #else
+ #if	defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
+ #ifdef	  AFS_SUN5_ENV
+ #include &lt;unistd.h&gt;
+ #include &lt;sys/mnttab.h&gt;
+ #include &lt;sys/mntent.h&gt;
+ #else
+ #include &lt;mntent.h&gt;
+ #endif
+ #else
+ #endif /* AFS_SGI_ENV */
+ #endif /* AFS_HPUX_ENV */
+ #endif
+ #endif
+ #include &lt;fcntl.h&gt;
+ #ifndef AFS_NT40_ENV
+ #include &lt;afs/osi_inode.h&gt;
+ #endif
+ #include &lt;afs/cmd.h&gt;
+ #include &lt;afs/afsutil.h&gt;
+ #include &lt;afs/fileutil.h&gt;
+ #include &lt;afs/procmgmt.h&gt;	/* signal(), kill(), wait(), etc. */
+ #ifndef AFS_NT40_ENV
+ #include &lt;syslog.h&gt;
+ #endif
+ 
+ #include "nfs.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include &lt;afs/afssyscalls.h&gt;
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ #include "daemon_com.h"
+ #include "fssync.h"
+ #include "salvsync.h"
+ #include "viceinode.h"
+ #include "salvage.h"
+ #include "volinodes.h"		/* header magic number, etc. stuff */
+ #include "vol-salvage.h"
+ #ifdef AFS_NT40_ENV
+ #include &lt;pthread.h&gt;
+ #endif
+ 
+ 
+ #if !defined(AFS_DEMAND_ATTACH_FS)
+ #error "online salvager only supported for demand attach fileserver"
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ #if defined(AFS_NT40_ENV)
+ #error "online salvager not supported on NT"
+ #endif /* AFS_NT40_ENV */
+ 
+ 
+ /* Forward declarations */
+ /*@printflike@*/ void Log(const char *format, ...);
+ /*@printflike@*/ void Abort(const char *format, ...);
+ 
+ 
+ /*@+fcnmacros +macrofcndecl@*/
+ #ifdef O_LARGEFILE
+ #define afs_fopen	fopen64
+ #else /* !O_LARGEFILE */
+ #define afs_fopen	fopen
+ #endif /* !O_LARGEFILE */
+ /*@=fcnmacros =macrofcndecl@*/
+ 
+ 
+ 
+ static volatile int current_workers = 0;
+ static volatile struct rx_queue pending_q;
+ static pthread_mutex_t worker_lock;
+ static pthread_cond_t worker_cv;
+ 
+ static void * SalvageChildReaperThread(void *);
+ static int DoSalvageVolume(struct SalvageQueueNode * node, int slot);
+ 
+ static void SalvageServer(void);
+ static void SalvageClient(VolumeId vid, char * pname);
+ 
+ static int Reap_Child(char * prog, int * pid, int * status);
+ 
+ static void * SalvageLogCleanupThread(void *);
+ static int SalvageLogCleanup(int pid);
+ 
+ struct log_cleanup_node {
+     struct rx_queue q;
+     int pid;
+ };
+ 
+ struct {
+     struct rx_queue queue_head;
+     pthread_cond_t queue_change_cv;
+ } log_cleanup_queue;
+ 
+ 
+ #define DEFAULT_PARALLELISM 4 /* allow 4 parallel salvage workers by default */
+ 
+ static int
+ handleit(struct cmd_syndesc *as)
+ {
+     register struct cmd_item *ti;
+     char pname[100], *temp;
+     afs_int32 seenpart = 0, seenvol = 0, vid = 0, seenany = 0;
+     struct DiskPartition *partP;
+ 
+ 
+ #ifdef AFS_SGI_VNODE_GLUE
+     if (afs_init_kernel_config(-1) &lt; 0) {
+ 	printf
+ 	    ("Can't determine NUMA configuration, not starting salvager.\n");
+ 	exit(1);
+     }
+ #endif
+ 
+     if (as-&gt;parms[2].items)	/* -debug */
+ 	debug = 1;
+     if (as-&gt;parms[3].items)	/* -nowrite */
+ 	Testing = 1;
+     if (as-&gt;parms[4].items)	/* -inodes */
+ 	ListInodeOption = 1;
+     if (as-&gt;parms[5].items)	/* -oktozap */
+ 	OKToZap = 1;
+     if (as-&gt;parms[6].items)	/* -rootinodes */
+ 	ShowRootFiles = 1;
+     if (as-&gt;parms[8].items)	/* -ForceReads */
+ 	forceR = 1;
+     if ((ti = as-&gt;parms[9].items)) {	/* -Parallel # */
+ 	temp = ti-&gt;data;
+ 	if (strncmp(temp, "all", 3) == 0) {
+ 	    PartsPerDisk = 1;
+ 	    temp += 3;
+ 	}
+ 	if (strlen(temp) != 0) {
+ 	    Parallel = atoi(temp);
+ 	    if (Parallel &lt; 1)
+ 		Parallel = 1;
+ 	    if (Parallel &gt; MAXPARALLEL) {
+ 		printf("Setting parallel salvages to maximum of %d \n",
+ 		       MAXPARALLEL);
+ 		Parallel = MAXPARALLEL;
+ 	    }
+ 	}
+     } else {
+ 	Parallel = MIN(DEFAULT_PARALLELISM, MAXPARALLEL);
+     }
+     if ((ti = as-&gt;parms[10].items)) {	/* -tmpdir */
+ 	DIR *dirp;
+ 
+ 	tmpdir = ti-&gt;data;
+ 	dirp = opendir(tmpdir);
+ 	if (!dirp) {
+ 	    printf
+ 		("Can't open temporary placeholder dir %s; using current partition \n",
+ 		 tmpdir);
+ 	    tmpdir = NULL;
+ 	} else
+ 	    closedir(dirp);
+     }
+     if ((ti = as-&gt;parms[11].items))	/* -showlog */
+ 	ShowLog = 1;
+     if ((ti = as-&gt;parms[12].items)) {	/* -orphans */
+ 	if (Testing)
+ 	    orphans = ORPH_IGNORE;
+ 	else if (strcmp(ti-&gt;data, "remove") == 0
+ 		 || strcmp(ti-&gt;data, "r") == 0)
+ 	    orphans = ORPH_REMOVE;
+ 	else if (strcmp(ti-&gt;data, "attach") == 0
+ 		 || strcmp(ti-&gt;data, "a") == 0)
+ 	    orphans = ORPH_ATTACH;
+     }
+ #ifndef AFS_NT40_ENV		/* ignore options on NT */
+     if ((ti = as-&gt;parms[13].items)) {	/* -syslog */
+ 	useSyslog = 1;
+ 	ShowLog = 0;
+     }
+     if ((ti = as-&gt;parms[14].items)) {	/* -syslogfacility */
+ 	useSyslogFacility = atoi(ti-&gt;data);
+     }
+ 
+     if ((ti = as-&gt;parms[15].items)) {	/* -datelogs */
+ 	TimeStampLogFile(AFSDIR_SERVER_SALSRVLOG_FILEPATH);
+     }
+ #endif
+ 
+     if ((ti = as-&gt;parms[16].items)) {   /* -client */
+ 	if ((ti = as-&gt;parms[0].items)) {	/* -partition */
+ 	    seenpart = 1;
+ 	    strlcpy(pname, ti-&gt;data, sizeof(pname));
+ 	}
+ 	if ((ti = as-&gt;parms[1].items)) {	/* -volumeid */
+ 	    seenvol = 1;
+ 	    vid = atoi(ti-&gt;data);
+ 	}
+ 
+ 	if (!seenpart || !seenvol) {
+ 	    printf("You must specify '-partition' and '-volumeid' with the '-client' option\n");
+ 	    exit(-1);
+ 	}
+ 
+ 	SalvageClient(vid, pname);
+ 
+     } else {  /* salvageserver mode */
+ 	SalvageServer();
+     }
+     return (0);
+ }
+ 
+ 
+ #ifndef AFS_NT40_ENV
+ #include "AFS_component_version_number.c"
+ #endif
+ #define MAX_ARGS 128
+ #ifdef AFS_NT40_ENV
+ char *save_args[MAX_ARGS];
+ int n_save_args = 0;
+ pthread_t main_thread;
+ #endif
+ 
+ static char commandLine[150];
+ 
+ int
+ main(int argc, char **argv)
+ {
+     struct cmd_syndesc *ts;
+     int err = 0;
+ 
+     int i;
+     extern char cml_version_number[];
+ 
+ #ifdef	AFS_AIX32_ENV
+     /*
+      * The following signal action for AIX is necessary so that in case of a 
+      * crash (i.e. core is generated) we can include the user's data section 
+      * in the core dump. Unfortunately, by default, only a partial core is
+      * generated which, in many cases, isn't too useful.
+      */
+     struct sigaction nsa;
+ 
+     sigemptyset(&amp;nsa.sa_mask);
+     nsa.sa_handler = SIG_DFL;
+     nsa.sa_flags = SA_FULLDUMP;
+     sigaction(SIGABRT, &amp;nsa, NULL);
+     sigaction(SIGSEGV, &amp;nsa, NULL);
+ #endif
+ 
+     /* Initialize directory paths */
+     if (!(initAFSDirPath() &amp; AFSDIR_SERVER_PATHS_OK)) {
+ #ifdef AFS_NT40_ENV
+ 	ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
+ #endif
+ 	fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
+ 		argv[0]);
+ 	exit(2);
+     }
+ #ifdef AFS_NT40_ENV
+     main_thread = pthread_self();
+     if (spawnDatap &amp;&amp; spawnDataLen) {
+ 	/* This is a child per partition salvager. Don't setup log or
+ 	 * try to lock the salvager lock.
+ 	 */
+ 	if (nt_SetupPartitionSalvage(spawnDatap, spawnDataLen) &lt; 0)
+ 	    exit(3);
+     } else {
+ #endif
+ 	for (commandLine[0] = '\0', i = 0; i &lt; argc; i++) {
+ 	    if (i &gt; 0)
+ 		strlcat(commandLine, " ", sizeof(commandLine));
+ 	    strlcat(commandLine, argv[i], sizeof(commandLine));
+ 	}
+ 
+ #ifndef AFS_NT40_ENV
+ 	if (geteuid() != 0) {
+ 	    printf("Salvager must be run as root.\n");
+ 	    fflush(stdout);
+ 	    Exit(0);
+ 	}
+ #endif
+ 
+ 	/* bad for normal help flag processing, but can do nada */
+ 
+ #ifdef AFS_NT40_ENV
+     }
+ #endif
+ 
+     ts = cmd_CreateSyntax("initcmd", handleit, 0, "initialize the program");
+     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
+ 		"Name of partition to salvage");
+     cmd_AddParm(ts, "-volumeid", CMD_SINGLE, CMD_OPTIONAL,
+ 		"Volume Id to salvage");
+     cmd_AddParm(ts, "-debug", CMD_FLAG, CMD_OPTIONAL,
+ 		"Run in Debugging mode");
+     cmd_AddParm(ts, "-nowrite", CMD_FLAG, CMD_OPTIONAL,
+ 		"Run readonly/test mode");
+     cmd_AddParm(ts, "-inodes", CMD_FLAG, CMD_OPTIONAL,
+ 		"Just list affected afs inodes - debugging flag");
+     cmd_AddParm(ts, "-oktozap", CMD_FLAG, CMD_OPTIONAL,
+ 		"Give permission to destroy bogus inodes/volumes - debugging flag");
+     cmd_AddParm(ts, "-rootinodes", CMD_FLAG, CMD_OPTIONAL,
+ 		"Show inodes owned by root - debugging flag");
+     cmd_AddParm(ts, "-salvagedirs", CMD_FLAG, CMD_OPTIONAL,
+ 		"Force rebuild/salvage of all directories");
+     cmd_AddParm(ts, "-blockreads", CMD_FLAG, CMD_OPTIONAL,
+ 		"Read smaller blocks to handle IO/bad blocks");
+     cmd_AddParm(ts, "-parallel", CMD_SINGLE, CMD_OPTIONAL,
+ 		"# of max parallel partition salvaging");
+     cmd_AddParm(ts, "-tmpdir", CMD_SINGLE, CMD_OPTIONAL,
+ 		"Name of dir to place tmp files ");
+     cmd_AddParm(ts, "-showlog", CMD_FLAG, CMD_OPTIONAL,
+ 		"Show log file upon completion");
+     cmd_AddParm(ts, "-orphans", CMD_SINGLE, CMD_OPTIONAL,
+ 		"ignore | remove | attach");
+ 
+     /* note - syslog isn't avail on NT, but if we make it conditional, have
+      * to deal with screwy offsets for cmd params */
+     cmd_AddParm(ts, "-syslog", CMD_FLAG, CMD_OPTIONAL,
+ 		"Write salvage log to syslogs");
+     cmd_AddParm(ts, "-syslogfacility", CMD_SINGLE, CMD_OPTIONAL,
+ 		"Syslog facility number to use");
+     cmd_AddParm(ts, "-datelogs", CMD_FLAG, CMD_OPTIONAL,
+ 		"Include timestamp in logfile filename");
+ 
+     cmd_AddParm(ts, "-client", CMD_FLAG, CMD_OPTIONAL,
+ 		"Use SALVSYNC to ask salvageserver to salvage a volume");
+ 
+     err = cmd_Dispatch(argc, argv);
+     Exit(err);
+ }
+ 
+ static void
+ SalvageClient(VolumeId vid, char * pname)
+ {
+     int done = 0;
+     afs_int32 code;
+     SYNC_response res;
+     SALVSYNC_response_hdr sres;
+ 
+     VInitVolumePackage(volumeUtility, 5, 5, DONT_CONNECT_FS, 0);
+     SALVSYNC_clientInit();
+     
+     code = SALVSYNC_SalvageVolume(vid, pname, SALVSYNC_SALVAGE, SALVSYNC_OPERATOR, 0, NULL);
+     if (code != SYNC_OK) {
+ 	goto sync_error;
+     }
+ 
+     res.payload.buf = (void *) &amp;sres;
+     res.payload.len = sizeof(sres);
+ 
+     while(!done) {
+ 	sleep(2);
+ 	code = SALVSYNC_SalvageVolume(vid, pname, SALVSYNC_QUERY, SALVSYNC_WHATEVER, 0, &amp;res);
+ 	if (code != SYNC_OK) {
+ 	    goto sync_error;
+ 	}
+ 	switch (sres.state) {
+ 	case SALVSYNC_STATE_ERROR:
+ 	    printf("salvageserver reports salvage ended in an error; check log files for more details\n");
+ 	case SALVSYNC_STATE_DONE:
+ 	case SALVSYNC_STATE_UNKNOWN:
+ 	    done = 1;
+ 	}
+     }
+     SALVSYNC_clientFinis();
+     return;
+ 
+  sync_error:
+     if (code == SYNC_DENIED) {
+ 	printf("salvageserver refused to salvage volume %u on partition %s\n",
+ 	       vid, pname);
+     } else if (code == SYNC_BAD_COMMAND) {
+ 	printf("SALVSYNC protocol mismatch; please make sure fileserver, volserver, salvageserver and salvager are same version\n");
+     } else if (code == SYNC_COM_ERROR) {
+ 	printf("SALVSYNC communications error\n");
+     }
+     SALVSYNC_clientFinis();
+     exit(-1);
+ }
+ 
+ static int * child_slot;
+ 
+ static void
+ SalvageServer(void)
+ {
+     int pid, ret;
+     struct SalvageQueueNode * node;
+     pthread_t tid;
+     pthread_attr_t attrs;
+     int slot;
+ 
+     /* All entries to the log will be appended.  Useful if there are
+      * multiple salvagers appending to the log.
+      */
+ 
+     CheckLogFile(AFSDIR_SERVER_SALSRVLOG_FILEPATH);
+ #ifndef AFS_NT40_ENV
+ #ifdef AFS_LINUX20_ENV
+     fcntl(fileno(logFile), F_SETFL, O_APPEND);	/* Isn't this redundant? */
+ #else
+     fcntl(fileno(logFile), F_SETFL, FAPPEND);	/* Isn't this redundant? */
+ #endif
+ #endif
+     setlinebuf(logFile);
+ 
+     fprintf(logFile, "%s\n", cml_version_number);
+     Log("Starting OpenAFS Online Salvage Server %s (%s)\n", SalvageVersion, commandLine);
+     
+     /* Get and hold a lock for the duration of the salvage to make sure
+      * that no other salvage runs at the same time.  The routine
+      * VInitVolumePackage (called below) makes sure that a file server or
+      * other volume utilities don't interfere with the salvage.
+      */
+     
+     /* even demand attach online salvager
+      * still needs this because we don't want
+      * a stand-alone salvager to conflict with
+      * the salvager daemon */
+     ObtainSalvageLock();
+ 
+     child_slot = (int *) malloc(Parallel * sizeof(int));
+     assert(child_slot != NULL);
+     memset(child_slot, 0, Parallel * sizeof(int));
+ 	    
+     /* initialize things */
+     VInitVolumePackage(salvageServer, 5, 5,
+ 		       1, 0);
+     DInit(10);
+     queue_Init(&amp;pending_q);
+     queue_Init(&amp;log_cleanup_queue);
+     assert(pthread_mutex_init(&amp;worker_lock, NULL) == 0);
+     assert(pthread_cond_init(&amp;worker_cv, NULL) == 0);
+     assert(pthread_cond_init(&amp;log_cleanup_queue.queue_change_cv, NULL) == 0);
+     assert(pthread_attr_init(&amp;attrs) == 0);
+ 
+     /* start up the reaper and log cleaner threads */
+     assert(pthread_attr_setdetachstate(&amp;attrs, PTHREAD_CREATE_DETACHED) == 0);
+     assert(pthread_create(&amp;tid, 
+ 			  &amp;attrs, 
+ 			  &amp;SalvageChildReaperThread,
+ 			  NULL) == 0);
+     assert(pthread_create(&amp;tid, 
+ 			  &amp;attrs, 
+ 			  &amp;SalvageLogCleanupThread,
+ 			  NULL) == 0);
+ 
+     /* loop forever serving requests */
+     while (1) {
+ 	node = SALVSYNC_getWork();
+ 	assert(node != NULL);
+ 
+ 	VOL_LOCK;
+ 	/* find a slot */
+ 	for (slot = 0; slot &lt; Parallel; slot++) {
+ 	  if (!child_slot[slot])
+ 	    break;
+ 	}
+ 	assert (slot &lt; Parallel);
+ 
+ 	pid = Fork();
+ 	if (pid == 0) {
+ 	    VOL_UNLOCK;
+ 	    ret = DoSalvageVolume(node, slot);
+ 	    Exit(ret);
+ 	} else if (pid &lt; 0) {
+ 	    VOL_UNLOCK;
+ 	    SALVSYNC_doneWork(node, 1);
+ 	} else {
+ 	    child_slot[slot] = pid;
+ 	    node-&gt;pid = pid;
+ 	    VOL_UNLOCK;
+ 	    
+ 	    assert(pthread_mutex_lock(&amp;worker_lock) == 0);
+ 	    current_workers++;
+ 	    
+ 	    /* let the reaper thread know another worker was spawned */
+ 	    assert(pthread_cond_broadcast(&amp;worker_cv) == 0);
+ 	    
+ 	    /* if we're overquota, wait for the reaper */
+ 	    while (current_workers &gt;= Parallel) {
+ 		assert(pthread_cond_wait(&amp;worker_cv, &amp;worker_lock) == 0);
+ 	    }
+ 	    assert(pthread_mutex_unlock(&amp;worker_lock) == 0);
+ 	}
+     }
+ }
+ 
+ static int
+ DoSalvageVolume(struct SalvageQueueNode * node, int slot)
+ {
+     char childLog[AFSDIR_PATH_MAX];
+     int ret;
+     struct DiskPartition * partP;
+ 
+     VChildProcReconnectFS();
+ 
+     /* do not attempt to close parent's logFile handle as
+      * another thread may have held the lock on the FILE
+      * structure when fork was called! */
+ 
+     afs_snprintf(childLog, sizeof(childLog), "%s.%d", 
+ 		 AFSDIR_SERVER_SLVGLOG_FILEPATH, getpid());
+ 
+     logFile = afs_fopen(childLog, "a");
+     if (!logFile) {		/* still nothing, use stdout */
+ 	logFile = stdout;
+ 	ShowLog = 0;
+     }
+ 
+     if (node-&gt;command.sop.volume &lt;= 0) {
+ 	Log("salvageServer: invalid volume id specified; salvage aborted\n");
+ 	return 1;
+     }
+     
+     partP = VGetPartition(node-&gt;command.sop.partName, 0);
+     if (!partP) {
+ 	Log("salvageServer: Unknown or unmounted partition %s; salvage aborted\n", 
+ 	    node-&gt;command.sop.partName);
+ 	return 1;
+     }
+ 
+     /* Salvage individual volume; don't notify fs */
+     SalvageFileSys1(partP, node-&gt;command.sop.volume);
+ 
+     VDisconnectFS();
+ 
+     fclose(logFile);
+     return 0;
+ }
+ 
+ 
+ static void *
+ SalvageChildReaperThread(void * args)
+ {
+     int slot, pid, status, code, found;
+     struct SalvageQueueNode *qp, *nqp;
+     struct log_cleanup_node * cleanup;
+ 
+     assert(pthread_mutex_lock(&amp;worker_lock) == 0);
+ 
+     /* loop reaping our children */
+     while (1) {
+ 	/* wait() won't block unless we have children, so
+ 	 * block on the cond var if we're childless */
+ 	while (current_workers == 0) {
+ 	    assert(pthread_cond_wait(&amp;worker_cv, &amp;worker_lock) == 0);
+ 	}
+ 
+ 	assert(pthread_mutex_unlock(&amp;worker_lock) == 0);
+ 
+ 	cleanup = (struct log_cleanup_node *) malloc(sizeof(struct log_cleanup_node));
+ 
+ 	while (Reap_Child("salvageserver", &amp;pid, &amp;status) &lt; 0) {
+ 	    /* try to prevent livelock if something goes wrong */
+ 	    sleep(1);
+ 	}
+ 
+ 	VOL_LOCK;
+ 	for (slot = 0; slot &lt; Parallel; slot++) {
+ 	    if (child_slot[slot] == pid)
+ 		break;
+ 	}
+ 	assert(slot &lt; Parallel);
+ 	child_slot[slot] = 0;
+ 	VOL_UNLOCK;
+ 
+ 	assert(pthread_mutex_lock(&amp;worker_lock) == 0);
+ 
+ 	if (cleanup) {
+ 	    cleanup-&gt;pid = pid;
+ 	    queue_Append(&amp;log_cleanup_queue, cleanup);
+ 	    assert(pthread_cond_signal(&amp;log_cleanup_queue.queue_change_cv) == 0);
+ 	}
+ 
+ 	/* ok, we've reaped a child */
+ 	current_workers--;
+ 	SALVSYNC_doneWorkByPid(pid, 0);
+ 	assert(pthread_cond_broadcast(&amp;worker_cv) == 0);
+     }
+ 
+     return NULL;
+ }
+ 
+ static int
+ Reap_Child(char *prog, int * pid, int * status)
+ {
+     int ret;
+     ret = wait(status);
+ 
+     if (ret &gt;= 0) {
+ 	*pid = ret;
+         if (WCOREDUMP(*status))
+ 	    Log("\"%s\" core dumped!\n", prog);
+ 	if (WIFSIGNALED(*status) != 0 || WEXITSTATUS(*status) != 0)
+ 	    Log("\"%s\" (pid=%d) terminated abnormally!\n", prog, ret);
+     } else {
+ 	Log("wait returned -1\n");
+     }
+     return ret;
+ }
+ 
+ /*
+  * thread to combine salvager child logs
+  * back into the main salvageserver log
+  */
+ static void *
+ SalvageLogCleanupThread(void * arg)
+ {
+     struct log_cleanup_node * cleanup;
+ 
+     assert(pthread_mutex_lock(&amp;worker_lock) == 0);
+ 
+     while (1) {
+ 	while (queue_IsEmpty(&amp;log_cleanup_queue)) {
+ 	    assert(pthread_cond_wait(&amp;log_cleanup_queue.queue_change_cv, &amp;worker_lock) == 0);
+ 	}
+ 
+ 	while (queue_IsNotEmpty(&amp;log_cleanup_queue)) {
+ 	    cleanup = queue_First(&amp;log_cleanup_queue, log_cleanup_node);
+ 	    queue_Remove(cleanup);
+ 	    assert(pthread_mutex_unlock(&amp;worker_lock) == 0);
+ 	    SalvageLogCleanup(cleanup-&gt;pid);
+ 	    free(cleanup);
+ 	    assert(pthread_mutex_lock(&amp;worker_lock) == 0);
+ 	}	    
+     }
+ 
+     assert(pthread_mutex_unlock(&amp;worker_lock) == 0);
+     return NULL;
+ }
+ 
+ #define LOG_XFER_BUF_SIZE 65536
+ static int
+ SalvageLogCleanup(int pid)
+ {
+     int pidlog, len;
+     char fn[AFSDIR_PATH_MAX];
+     static char buf[LOG_XFER_BUF_SIZE];
+ 
+     afs_snprintf(fn, sizeof(fn), "%s.%d", 
+ 		 AFSDIR_SERVER_SLVGLOG_FILEPATH, pid);
+     
+ 
+     pidlog = open(fn, O_RDONLY);
+     unlink(fn);
+     if (pidlog &lt; 0)
+ 	return 1;
+ 
+     len = read(pidlog, buf, LOG_XFER_BUF_SIZE);
+     while (len) {
+ 	fwrite(buf, len, 1, logFile);
+ 	len = read(pidlog, buf, LOG_XFER_BUF_SIZE);
+     }
+ 
+     close(pidlog);
+ 
+     return 0;
+ }
Index: openafs/src/vol/salvager.c
diff -c /dev/null openafs/src/vol/salvager.c:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/salvager.c	Fri Mar 17 23:20:19 2006
***************
*** 0 ****
--- 1,499 ----
+ /*
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  *      System:		VICE-TWO
+  *      Module:		salvager.c
+  *      Institution:	The Information Technology Center, Carnegie-Mellon University
+  */
+ 
+ 
+ /* Main program file. Define globals. */
+ #define MAIN 1
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/vol/salvager.c,v 1.1 2006/03/18 04:20:19 shadow Exp $");
+ 
+ #include &lt;stdlib.h&gt;
+ #include &lt;stdio.h&gt;
+ #include &lt;string.h&gt;
+ #include &lt;dirent.h&gt;
+ #include &lt;sys/stat.h&gt;
+ #include &lt;time.h&gt;
+ #include &lt;errno.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;io.h&gt;
+ #include &lt;WINNT/afsevent.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/file.h&gt;
+ #ifndef ITIMER_REAL
+ #include &lt;sys/time.h&gt;
+ #endif /* ITIMER_REAL */
+ #endif
+ #if	defined(AFS_AIX_ENV) || defined(AFS_SUN4_ENV)
+ #define WCOREDUMP(x)	(x &amp; 0200)
+ #endif
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include &lt;afs/assert.h&gt;
+ #if !defined(AFS_SGI_ENV) &amp;&amp; !defined(AFS_NT40_ENV)
+ #if defined(AFS_VFSINCL_ENV)
+ #include &lt;sys/vnode.h&gt;
+ #ifdef	AFS_SUN5_ENV
+ #include &lt;sys/fs/ufs_inode.h&gt;
+ #else
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+ #include &lt;ufs/ufs/dinode.h&gt;
+ #include &lt;ufs/ffs/fs.h&gt;
+ #else
+ #include &lt;ufs/inode.h&gt;
+ #endif
+ #endif
+ #else /* AFS_VFSINCL_ENV */
+ #ifdef	AFS_OSF_ENV
+ #include &lt;ufs/inode.h&gt;
+ #else /* AFS_OSF_ENV */
+ #if !defined(AFS_LINUX20_ENV) &amp;&amp; !defined(AFS_XBSD_ENV)
+ #include &lt;sys/inode.h&gt;
+ #endif
+ #endif
+ #endif /* AFS_VFSINCL_ENV */
+ #endif /* AFS_SGI_ENV */
+ #ifdef	AFS_AIX_ENV
+ #include &lt;sys/vfs.h&gt;
+ #include &lt;sys/lockf.h&gt;
+ #else
+ #ifdef	AFS_HPUX_ENV
+ #include &lt;unistd.h&gt;
+ #include &lt;checklist.h&gt;
+ #else
+ #if defined(AFS_SGI_ENV)
+ #include &lt;unistd.h&gt;
+ #include &lt;fcntl.h&gt;
+ #include &lt;mntent.h&gt;
+ #else
+ #if	defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
+ #ifdef	  AFS_SUN5_ENV
+ #include &lt;unistd.h&gt;
+ #include &lt;sys/mnttab.h&gt;
+ #include &lt;sys/mntent.h&gt;
+ #else
+ #include &lt;mntent.h&gt;
+ #endif
+ #else
+ #endif /* AFS_SGI_ENV */
+ #endif /* AFS_HPUX_ENV */
+ #endif
+ #endif
+ #include &lt;fcntl.h&gt;
+ #ifndef AFS_NT40_ENV
+ #include &lt;afs/osi_inode.h&gt;
+ #endif
+ #include &lt;afs/cmd.h&gt;
+ #include &lt;afs/afsutil.h&gt;
+ #include &lt;afs/fileutil.h&gt;
+ #include &lt;afs/procmgmt.h&gt;	/* signal(), kill(), wait(), etc. */
+ #ifndef AFS_NT40_ENV
+ #include &lt;syslog.h&gt;
+ #endif
+ 
+ #include "nfs.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include &lt;afs/afssyscalls.h&gt;
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ #include "daemon_com.h"
+ #include "fssync.h"
+ #include "salvsync.h"
+ #include "viceinode.h"
+ #include "salvage.h"
+ #include "volinodes.h"		/* header magic number, etc. stuff */
+ #include "vol-salvage.h"
+ #ifdef AFS_NT40_ENV
+ #include &lt;pthread.h&gt;
+ #endif
+ 
+ 
+ static int get_salvage_lock = 0;
+ 
+ 
+ /* Forward declarations */
+ /*@printflike@*/ void Log(const char *format, ...);
+ /*@printflike@*/ void Abort(const char *format, ...);
+ 
+ 
+ static int
+ handleit(struct cmd_syndesc *as)
+ {
+     register struct cmd_item *ti;
+     char pname[100], *temp;
+     afs_int32 seenpart = 0, seenvol = 0, vid = 0, seenany = 0;
+     struct DiskPartition *partP;
+ 
+ #ifdef AFS_SGI_VNODE_GLUE
+     if (afs_init_kernel_config(-1) &lt; 0) {
+ 	printf
+ 	    ("Can't determine NUMA configuration, not starting salvager.\n");
+ 	exit(1);
+     }
+ #endif
+ 
+ #ifdef FAST_RESTART
+     {
+ 	afs_int32 i;
+ 	for (i = 0; i &lt; CMD_MAXPARMS; i++) {
+ 	    if (as-&gt;parms[i].items) {
+ 		seenany = 1;
+ 		break;
+ 	    }
+ 	}
+     }
+     if (!seenany) {
+ 	char *msg =
+ 	    "Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!";
+ 
+ 	if (useSyslog)
+ 	    Log(msg);
+ 	else
+ 	    printf("%s\n", msg);
+ 
+ 	Exit(0);
+     }
+ #endif /* FAST_RESTART */
+     if ((ti = as-&gt;parms[0].items)) {	/* -partition */
+ 	seenpart = 1;
+ 	strncpy(pname, ti-&gt;data, 100);
+     }
+     if ((ti = as-&gt;parms[1].items)) {	/* -volumeid */
+ 	if (!seenpart) {
+ 	    printf
+ 		("You must also specify '-partition' option with the '-volumeid' option\n");
+ 	    exit(-1);
+ 	}
+ 	seenvol = 1;
+ 	vid = atoi(ti-&gt;data);
+     }
+     if (as-&gt;parms[2].items)	/* -debug */
+ 	debug = 1;
+     if (as-&gt;parms[3].items)	/* -nowrite */
+ 	Testing = 1;
+     if (as-&gt;parms[4].items)	/* -inodes */
+ 	ListInodeOption = 1;
+     if (as-&gt;parms[5].items)	/* -force */
+ 	ForceSalvage = 1;
+     if (as-&gt;parms[6].items)	/* -oktozap */
+ 	OKToZap = 1;
+     if (as-&gt;parms[7].items)	/* -rootinodes */
+ 	ShowRootFiles = 1;
+     if (as-&gt;parms[8].items)	/* -RebuildDirs */
+ 	RebuildDirs = 1;
+     if (as-&gt;parms[9].items)	/* -ForceReads */
+ 	forceR = 1;
+     if ((ti = as-&gt;parms[10].items)) {	/* -Parallel # */
+ 	temp = ti-&gt;data;
+ 	if (strncmp(temp, "all", 3) == 0) {
+ 	    PartsPerDisk = 1;
+ 	    temp += 3;
+ 	}
+ 	if (strlen(temp) != 0) {
+ 	    Parallel = atoi(temp);
+ 	    if (Parallel &lt; 1)
+ 		Parallel = 1;
+ 	    if (Parallel &gt; MAXPARALLEL) {
+ 		printf("Setting parallel salvages to maximum of %d \n",
+ 		       MAXPARALLEL);
+ 		Parallel = MAXPARALLEL;
+ 	    }
+ 	}
+     }
+     if ((ti = as-&gt;parms[11].items)) {	/* -tmpdir */
+ 	DIR *dirp;
+ 
+ 	tmpdir = ti-&gt;data;
+ 	dirp = opendir(tmpdir);
+ 	if (!dirp) {
+ 	    printf
+ 		("Can't open temporary placeholder dir %s; using current partition \n",
+ 		 tmpdir);
+ 	    tmpdir = NULL;
+ 	} else
+ 	    closedir(dirp);
+     }
+     if ((ti = as-&gt;parms[12].items))	/* -showlog */
+ 	ShowLog = 1;
+     if ((ti = as-&gt;parms[13].items)) {	/* -log */
+ 	Testing = 1;
+ 	ShowSuid = 1;
+ 	Showmode = 1;
+     }
+     if ((ti = as-&gt;parms[14].items)) {	/* -showmounts */
+ 	Testing = 1;
+ 	Showmode = 1;
+ 	ShowMounts = 1;
+     }
+     if ((ti = as-&gt;parms[15].items)) {	/* -orphans */
+ 	if (Testing)
+ 	    orphans = ORPH_IGNORE;
+ 	else if (strcmp(ti-&gt;data, "remove") == 0
+ 		 || strcmp(ti-&gt;data, "r") == 0)
+ 	    orphans = ORPH_REMOVE;
+ 	else if (strcmp(ti-&gt;data, "attach") == 0
+ 		 || strcmp(ti-&gt;data, "a") == 0)
+ 	    orphans = ORPH_ATTACH;
+     }
+ #ifndef AFS_NT40_ENV		/* ignore options on NT */
+     if ((ti = as-&gt;parms[16].items)) {	/* -syslog */
+ 	useSyslog = 1;
+ 	ShowLog = 0;
+     }
+     if ((ti = as-&gt;parms[17].items)) {	/* -syslogfacility */
+ 	useSyslogFacility = atoi(ti-&gt;data);
+     }
+ 
+     if ((ti = as-&gt;parms[18].items)) {	/* -datelogs */
+ 	TimeStampLogFile(AFSDIR_SERVER_SLVGLOG_FILEPATH);
+     }
+ #endif
+ 
+ #ifdef FAST_RESTART
+     if (ti = as-&gt;parms[19].items) {	/* -DontSalvage */
+ 	char *msg =
+ 	    "Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!";
+ 
+ 	if (useSyslog)
+ 	    Log(msg);
+ 	else
+ 	    printf("%s\n", msg);
+ 	Exit(0);
+     }
+ #elif defined(DEMAND_ATTACH_ENABLE)
+     if (seenvol &amp;&amp; !as-&gt;parms[19].items) {
+ 	char * msg =
+ 	    "The standalone salvager cannot be run concurrently with a Demand Attach Fileserver.  Please use 'salvageserver -client &lt;partition&gt; &lt;volume id&gt;' to manually schedule volume salvages with the salvageserver (new versions of 'bos salvage' automatically do this for you).  Or, if you insist on using the standalone salvager, add the -forceDAFS flag to your salvager command line.";
+ 
+ 	if (useSyslog)
+ 	    Log(msg);
+ 	else
+ 	    printf("%s\n", msg);
+ 	Exit(1);
+     }
+ #endif
+ 
+     if (get_salvage_lock) {
+ 	ObtainSalvageLock();
+     }
+ 
+     /* Note:  if seenvol we initialize this as a standard volume utility:  this has the
+      * implication that the file server may be running; negotations have to be made with
+      * the file server in this case to take the read write volume and associated read-only
+      * volumes off line before salvaging */
+ #ifdef AFS_NT40_ENV
+     if (seenvol) {
+ 	if (afs_winsockInit() &lt; 0) {
+ 	    ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0,
+ 				AFSDIR_SALVAGER_FILE, 0);
+ 	    Log("Failed to initailize winsock, exiting.\n");
+ 	    Exit(1);
+ 	}
+     }
+ #endif
+     VInitVolumePackage(seenvol ? volumeUtility : salvager, 5, 5,
+ 		       DONT_CONNECT_FS, 0);
+     DInit(10);
+ #ifdef AFS_NT40_ENV
+     if (myjob.cj_number != NOT_CHILD) {
+ 	if (!seenpart) {
+ 	    seenpart = 1;
+ 	    (void)strcpy(pname, myjob.cj_part);
+ 	}
+     }
+ #endif
+     if (seenpart == 0) {
+ 	for (partP = DiskPartitionList; partP; partP = partP-&gt;next) {
+ 	    SalvageFileSysParallel(partP);
+ 	}
+ 	SalvageFileSysParallel(0);
+     } else {
+ 	partP = VGetPartition(pname, 0);
+ 	if (!partP) {
+ 	    Log("salvage: Unknown or unmounted partition %s; salvage aborted\n", pname);
+ 	    Exit(1);
+ 	}
+ 	if (!seenvol)
+ 	    SalvageFileSys(partP, 0);
+ 	else {
+ 	    /* Salvage individual volume */
+ 	    if (vid &lt;= 0) {
+ 		Log("salvage: invalid volume id specified; salvage aborted\n");
+ 		Exit(1);
+ 	    }
+ 	    SalvageFileSys(partP, vid);
+ 	}
+     }
+     return (0);
+ }
+ 
+ 
+ #ifndef AFS_NT40_ENV
+ #include "AFS_component_version_number.c"
+ #endif
+ #define MAX_ARGS 128
+ #ifdef AFS_NT40_ENV
+ char *save_args[MAX_ARGS];
+ int n_save_args = 0;
+ pthread_t main_thread;
+ #endif
+ 
+ int
+ main(int argc, char **argv)
+ {
+     struct cmd_syndesc *ts;
+     int err = 0;
+     char commandLine[150];
+ 
+     int i;
+     extern char cml_version_number[];
+ 
+ #ifdef	AFS_AIX32_ENV
+     /*
+      * The following signal action for AIX is necessary so that in case of a 
+      * crash (i.e. core is generated) we can include the user's data section 
+      * in the core dump. Unfortunately, by default, only a partial core is
+      * generated which, in many cases, isn't too useful.
+      */
+     struct sigaction nsa;
+ 
+     sigemptyset(&amp;nsa.sa_mask);
+     nsa.sa_handler = SIG_DFL;
+     nsa.sa_flags = SA_FULLDUMP;
+     sigaction(SIGABRT, &amp;nsa, NULL);
+     sigaction(SIGSEGV, &amp;nsa, NULL);
+ #endif
+ 
+     /* Initialize directory paths */
+     if (!(initAFSDirPath() &amp; AFSDIR_SERVER_PATHS_OK)) {
+ #ifdef AFS_NT40_ENV
+ 	ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
+ #endif
+ 	fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
+ 		argv[0]);
+ 	exit(2);
+     }
+ #ifdef AFS_NT40_ENV
+     main_thread = pthread_self();
+     if (spawnDatap &amp;&amp; spawnDataLen) {
+ 	/* This is a child per partition salvager. Don't setup log or
+ 	 * try to lock the salvager lock.
+ 	 */
+ 	if (nt_SetupPartitionSalvage(spawnDatap, spawnDataLen) &lt; 0)
+ 	    exit(3);
+     } else {
+ #endif
+ 	for (commandLine[0] = '\0', i = 0; i &lt; argc; i++) {
+ 	    if (i &gt; 0)
+ 		strcat(commandLine, " ");
+ 	    strcat(commandLine, argv[i]);
+ 	}
+ 
+ 	/* All entries to the log will be appended.  Useful if there are
+ 	 * multiple salvagers appending to the log.
+ 	 */
+ 
+ 	CheckLogFile(AFSDIR_SERVER_SLVGLOG_FILEPATH);
+ #ifndef AFS_NT40_ENV
+ #ifdef AFS_LINUX20_ENV
+ 	fcntl(fileno(logFile), F_SETFL, O_APPEND);	/* Isn't this redundant? */
+ #else
+ 	fcntl(fileno(logFile), F_SETFL, FAPPEND);	/* Isn't this redundant? */
+ #endif
+ #endif
+ 	setlinebuf(logFile);
+ 
+ #ifndef AFS_NT40_ENV
+ 	if (geteuid() != 0) {
+ 	    printf("Salvager must be run as root.\n");
+ 	    fflush(stdout);
+ 	    Exit(0);
+ 	}
+ #endif
+ 
+ 	/* bad for normal help flag processing, but can do nada */
+ 
+ 	fprintf(logFile, "%s\n", cml_version_number);
+ 	Log("STARTING AFS SALVAGER %s (%s)\n", SalvageVersion, commandLine);
+ 
+ 	/* Get and hold a lock for the duration of the salvage to make sure
+ 	 * that no other salvage runs at the same time.  The routine
+ 	 * VInitVolumePackage (called below) makes sure that a file server or
+ 	 * other volume utilities don't interfere with the salvage.
+ 	 */
+ 	get_salvage_lock = 1;
+ #ifdef AFS_NT40_ENV
+     }
+ #endif
+ 
+     ts = cmd_CreateSyntax("initcmd", handleit, 0, "initialize the program");
+     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
+ 		"Name of partition to salvage");
+     cmd_AddParm(ts, "-volumeid", CMD_SINGLE, CMD_OPTIONAL,
+ 		"Volume Id to salvage");
+     cmd_AddParm(ts, "-debug", CMD_FLAG, CMD_OPTIONAL,
+ 		"Run in Debugging mode");
+     cmd_AddParm(ts, "-nowrite", CMD_FLAG, CMD_OPTIONAL,
+ 		"Run readonly/test mode");
+     cmd_AddParm(ts, "-inodes", CMD_FLAG, CMD_OPTIONAL,
+ 		"Just list affected afs inodes - debugging flag");
+     cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "Force full salvaging");
+     cmd_AddParm(ts, "-oktozap", CMD_FLAG, CMD_OPTIONAL,
+ 		"Give permission to destroy bogus inodes/volumes - debugging flag");
+     cmd_AddParm(ts, "-rootinodes", CMD_FLAG, CMD_OPTIONAL,
+ 		"Show inodes owned by root - debugging flag");
+     cmd_AddParm(ts, "-salvagedirs", CMD_FLAG, CMD_OPTIONAL,
+ 		"Force rebuild/salvage of all directories");
+     cmd_AddParm(ts, "-blockreads", CMD_FLAG, CMD_OPTIONAL,
+ 		"Read smaller blocks to handle IO/bad blocks");
+     cmd_AddParm(ts, "-parallel", CMD_SINGLE, CMD_OPTIONAL,
+ 		"# of max parallel partition salvaging");
+     cmd_AddParm(ts, "-tmpdir", CMD_SINGLE, CMD_OPTIONAL,
+ 		"Name of dir to place tmp files ");
+     cmd_AddParm(ts, "-showlog", CMD_FLAG, CMD_OPTIONAL,
+ 		"Show log file upon completion");
+     cmd_AddParm(ts, "-showsuid", CMD_FLAG, CMD_OPTIONAL,
+ 		"Report on suid/sgid files");
+     cmd_AddParm(ts, "-showmounts", CMD_FLAG, CMD_OPTIONAL,
+ 		"Report on mountpoints");
+     cmd_AddParm(ts, "-orphans", CMD_SINGLE, CMD_OPTIONAL,
+ 		"ignore | remove | attach");
+ 
+     /* note - syslog isn't avail on NT, but if we make it conditional, have
+      * to deal with screwy offsets for cmd params */
+     cmd_AddParm(ts, "-syslog", CMD_FLAG, CMD_OPTIONAL,
+ 		"Write salvage log to syslogs");
+     cmd_AddParm(ts, "-syslogfacility", CMD_SINGLE, CMD_OPTIONAL,
+ 		"Syslog facility number to use");
+     cmd_AddParm(ts, "-datelogs", CMD_FLAG, CMD_OPTIONAL,
+ 		"Include timestamp in logfile filename");
+ #ifdef FAST_RESTART
+     cmd_AddParm(ts, "-DontSalvage", CMD_FLAG, CMD_OPTIONAL,
+ 		"Don't salvage. This my be set in BosConfig to let the fileserver restart immediately after a crash. Bad volumes will be taken offline");
+ #elif defined(DEMAND_ATTACH_ENABLE)
+     cmd_AddParm(ts, "-forceDAFS", CMD_FLAG, CMD_OPTIONAL,
+ 		"For Demand Attach Fileserver, permit a manual volume salvage outside of the salvageserver");
+ #endif /* FAST_RESTART */
+     err = cmd_Dispatch(argc, argv);
+     Exit(err);
+ }
+ 
Index: openafs/src/vol/salvsync-client.c
diff -c /dev/null openafs/src/vol/salvsync-client.c:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/salvsync-client.c	Fri Mar 17 23:20:19 2006
***************
*** 0 ****
--- 1,172 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  * salvsync-client.c
+  *
+  * OpenAFS demand attach fileserver
+  * Salvage server synchronization with fileserver.
+  */
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/vol/salvsync-client.c,v 1.1 2006/03/18 04:20:19 shadow Exp $");
+ 
+ #include &lt;sys/types.h&gt;
+ #include &lt;stdio.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;winsock2.h&gt;
+ #include &lt;time.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/socket.h&gt;
+ #include &lt;netinet/in.h&gt;
+ #include &lt;netdb.h&gt;
+ #include &lt;sys/time.h&gt;
+ #endif
+ #include &lt;errno.h&gt;
+ #include &lt;assert.h&gt;
+ #include &lt;signal.h&gt;
+ 
+ #ifdef HAVE_STRING_H
+ #include &lt;string.h&gt;
+ #else
+ #ifdef HAVE_STRINGS_H
+ #include &lt;strings.h&gt;
+ #endif
+ #endif
+ 
+ 
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include "nfs.h"
+ #include &lt;afs/errors.h&gt;
+ #include "salvsync.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include &lt;afs/afssyscalls.h&gt;
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ #include &lt;rx/rx_queue.h&gt;
+ 
+ /*@printflike@*/ extern void Log(const char *format, ...);
+ 
+ #ifdef osi_Assert
+ #undef osi_Assert
+ #endif
+ #define osi_Assert(e) (void)(e)
+ 
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * SALVSYNC is a feature specific to the demand attach fileserver
+  */
+ 
+ extern int LogLevel;
+ extern int VInit;
+ extern pthread_mutex_t vol_salvsync_mutex;
+ 
+ static SYNC_client_state salvsync_client_state = { -1, 2041, SALVSYNC_PROTO_VERSION, 5, 120 };
+ 
+ /*
+  * client-side routines
+  */
+ 
+ int
+ SALVSYNC_clientInit(void)
+ {
+     return SYNC_connect(&amp;salvsync_client_state);
+ }
+ 
+ int
+ SALVSYNC_clientFinis(void)
+ {
+     SYNC_closeChannel(&amp;salvsync_client_state);
+     return 1;
+ }
+ 
+ int
+ SALVSYNC_clientReconnect(void)
+ {
+     return SYNC_reconnect(&amp;salvsync_client_state);
+ }
+ 
+ afs_int32
+ SALVSYNC_askSalv(SYNC_command * com, SYNC_response * res)
+ {
+     afs_int32 code;
+ 
+     VSALVSYNC_LOCK;
+     code = SYNC_ask(&amp;salvsync_client_state, com, res);
+     VSALVSYNC_UNLOCK;
+ 
+     switch (code) {
+     case SYNC_OK:
+     case SYNC_FAILED:
+       break;
+     case SYNC_COM_ERROR:
+     case SYNC_BAD_COMMAND:
+ 	Log("SALVSYNC_askSalv: fatal SALVSYNC protocol error; online salvager functionality disabled until next fileserver restart\n");
+ 	break;
+     case SYNC_DENIED:
+ 	Log("SALVSYNC_askSalv: SALVSYNC request denied for reason=%d\n", res-&gt;hdr.reason);
+ 	break;
+     default:
+ 	Log("SALVSYNC_askSalv: unknown protocol response %d\n", code);
+ 	break;
+     }
+ 
+     return code;
+ }
+ 
+ afs_int32
+ SALVSYNC_SalvageVolume(VolumeId volume, char *partName, int command, int reason, 
+ 		       afs_uint32 prio, SYNC_response * res_in)
+ {
+     SYNC_command com;
+     SYNC_response res_l, *res;
+     SALVSYNC_command_hdr scom;
+     SALVSYNC_response_hdr sres;
+     int n, tot;
+ 
+     memset(&amp;com, 0, sizeof(com));
+     memset(&amp;scom, 0, sizeof(scom));
+ 
+     if (res_in) {
+ 	res = res_in;
+     } else {
+ 	memset(&amp;res_l, 0, sizeof(res_l));
+ 	memset(&amp;sres, 0, sizeof(sres));
+ 	res_l.payload.buf = (void *) &amp;sres;
+ 	res_l.payload.len = sizeof(sres);
+ 	res = &amp;res_l;
+     }
+ 
+     com.payload.buf = (void *) &amp;scom;
+     com.payload.len = sizeof(scom);
+     com.hdr.command = command;
+     com.hdr.reason = reason;
+     com.hdr.command_len = sizeof(com.hdr) + sizeof(scom);
+     scom.volume = volume;
+     scom.prio = prio;
+ 
+     if (partName) {
+ 	strlcpy(scom.partName, partName, sizeof(scom.partName));
+     } else {
+ 	scom.partName[0] = '\0';
+     }
+ 
+     return SALVSYNC_askSalv(&amp;com, res);
+ }
+ 
+ #endif /* AFS_DEMAND_ATTACH_FS */
Index: openafs/src/vol/salvsync-server.c
diff -c /dev/null openafs/src/vol/salvsync-server.c:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/salvsync-server.c	Fri Mar 17 23:20:19 2006
***************
*** 0 ****
--- 1,1009 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  * salvsync-server.c
+  *
+  * OpenAFS demand attach fileserver
+  * Salvage server synchronization with fileserver.
+  */
+ 
+ /* This controls the size of an fd_set; it must be defined early before
+  * the system headers define that type and the macros that operate on it.
+  * Its value should be as large as the maximum file descriptor limit we
+  * are likely to run into on any platform.  Right now, that is 65536
+  * which is the default hard fd limit on Solaris 9 */
+ #ifndef _WIN32
+ #define FD_SETSIZE 65536
+ #endif
+ 
+ #include &lt;afsconfig.h&gt;
+ #include &lt;afs/param.h&gt;
+ 
+ RCSID
+     ("$Header: /cvs/openafs/src/vol/salvsync-server.c,v 1.1 2006/03/18 04:20:19 shadow Exp $");
+ 
+ #include &lt;sys/types.h&gt;
+ #include &lt;stdio.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;winsock2.h&gt;
+ #include &lt;time.h&gt;
+ #else
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/socket.h&gt;
+ #include &lt;netinet/in.h&gt;
+ #include &lt;netdb.h&gt;
+ #include &lt;sys/time.h&gt;
+ #endif
+ #include &lt;errno.h&gt;
+ #include &lt;assert.h&gt;
+ #include &lt;signal.h&gt;
+ 
+ #ifdef HAVE_STRING_H
+ #include &lt;string.h&gt;
+ #else
+ #ifdef HAVE_STRINGS_H
+ #include &lt;strings.h&gt;
+ #endif
+ #endif
+ 
+ 
+ #include &lt;rx/xdr.h&gt;
+ #include &lt;afs/afsint.h&gt;
+ #include "nfs.h"
+ #include &lt;afs/errors.h&gt;
+ #include "salvsync.h"
+ #include "lwp.h"
+ #include "lock.h"
+ #include &lt;afs/afssyscalls.h&gt;
+ #include "ihandle.h"
+ #include "vnode.h"
+ #include "volume.h"
+ #include "partition.h"
+ #include &lt;rx/rx_queue.h&gt;
+ 
+ #if !defined(offsetof)
+ #include &lt;stddef.h&gt;
+ #endif
+ 
+ /*@printflike@*/ extern void Log(const char *format, ...);
+ 
+ #ifdef osi_Assert
+ #undef osi_Assert
+ #endif
+ #define osi_Assert(e) (void)(e)
+ 
+ #define MAXHANDLERS	4	/* Up to 4 clients; must be at least 2, so that
+ 				 * move = dump+restore can run on single server */
+ 
+ #define MAX_BIND_TRIES	5	/* Number of times to retry socket bind */
+ 
+ 
+ 
+ /* Forward declarations */
+ static void * SALVSYNC_syncThread(void *);
+ static void SALVSYNC_newconnection(int fd);
+ static void SALVSYNC_com(int fd);
+ static void SALVSYNC_Drop(int fd);
+ static void AcceptOn(void);
+ static void AcceptOff(void);
+ static void InitHandler(void);
+ static void CallHandler(fd_set * fdsetp);
+ static int AddHandler(int afd, void (*aproc) (int));
+ static int FindHandler(register int afd);
+ static int FindHandler_r(register int afd);
+ static int RemoveHandler(register int afd);
+ static void GetHandler(fd_set * fdsetp, int *maxfdp);
+ 
+ 
+ /*
+  * This lock controls access to the handler array.
+  */
+ struct Lock SALVSYNC_handler_lock;
+ 
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * SALVSYNC is a feature specific to the demand attach fileserver
+  */
+ 
+ static int AddToSalvageQueue(struct SalvageQueueNode * node);
+ static void DeleteFromSalvageQueue(struct SalvageQueueNode * node);
+ static void AddToPendingQueue(struct SalvageQueueNode * node);
+ static void DeleteFromPendingQueue(struct SalvageQueueNode * node);
+ static struct SalvageQueueNode * LookupPendingCommand(SALVSYNC_command_hdr * qry);
+ static struct SalvageQueueNode * LookupPendingCommandByPid(int pid);
+ static void RaiseCommandPrio(struct SalvageQueueNode * node, SALVSYNC_command_hdr * com);
+ 
+ static struct SalvageQueueNode * LookupNode(VolumeId vid, char * partName);
+ static struct SalvageQueueNode * LookupNodeByCommand(SALVSYNC_command_hdr * qry);
+ static void AddNodeToHash(struct SalvageQueueNode * node);
+ static void DeleteNodeFromHash(struct SalvageQueueNode * node);
+ 
+ static afs_int32 SALVSYNC_com_Salvage(SALVSYNC_command * com, SALVSYNC_response * res);
+ static afs_int32 SALVSYNC_com_Cancel(SALVSYNC_command * com, SALVSYNC_response * res);
+ static afs_int32 SALVSYNC_com_RaisePrio(SALVSYNC_command * com, SALVSYNC_response * res);
+ static afs_int32 SALVSYNC_com_Query(SALVSYNC_command * com, SALVSYNC_response * res);
+ static afs_int32 SALVSYNC_com_CancelAll(SALVSYNC_command * com, SALVSYNC_response * res);
+ 
+ 
+ extern int LogLevel;
+ extern int VInit;
+ extern pthread_mutex_t vol_salvsync_mutex;
+ 
+ static int AcceptSd = -1;		/* Socket used by server for accepting connections */
+ 
+ 
+ /* be careful about rearranging elements in this structure.
+  * element placement has been optimized for locality of reference
+  * in SALVSYNC_getWork() */
+ struct SalvageQueue {
+     volatile int total_len;
+     volatile afs_int32 last_insert;    /* id of last partition to have a salvage node insert */
+     volatile int len[VOLMAXPARTS+1];
+     volatile struct rx_queue part[VOLMAXPARTS+1];
+     pthread_cond_t cv;
+ };
+ static struct SalvageQueue salvageQueue;  /* volumes waiting to be salvaged */
+ 
+ struct QueueHead {
+     volatile struct rx_queue q;
+     volatile int len;
+     pthread_cond_t queue_change_cv;
+ };
+ static struct QueueHead pendingQueue;  /* volumes being salvaged */
+ 
+ /* XXX
+  * whether a partition has a salvage in progress
+  *
+  * the salvager code only permits one salvage per partition at a time
+  *
+  * the following hack tries to keep salvaged parallelism high by
+  * only permitting one salvage dispatch per partition at a time
+  *
+  * unfortunately, the parallel salvager currently
+  * has a rather braindead routine that won't permit
+  * multiple salvages on the same "device".  this
+  * function happens to break pretty badly on lvm, raid luns, etc.
+  *
+  * this hack isn't good enough to stop the device limiting code from
+  * crippling performance.  someday that code needs to be rewritten
+  */
+ static int partition_salvaging[VOLMAXPARTS+1];
+ 
+ #define VSHASH_SIZE 64
+ #define VSHASH_MASK (VSHASH_SIZE-1)
+ #define VSHASH(vid) ((vid)&amp;VSHASH_MASK)
+ 
+ static struct QueueHead  SalvageHashTable[VSHASH_SIZE];
+ 
+ static struct SalvageQueueNode *
+ LookupNode(afs_uint32 vid, char * partName)
+ {
+     struct rx_queue *qp, *nqp;
+     struct SalvageQueueNode *vsp;
+     int idx = VSHASH(vid);
+ 
+     for (queue_Scan(&amp;SalvageHashTable[idx], qp, nqp, rx_queue)) {
+ 	vsp = (struct SalvageQueueNode *)((char *)qp - offsetof(struct SalvageQueueNode, hash_chain));
+ 	if ((vsp-&gt;command.sop.volume == vid) &amp;&amp;
+ 	    !strncmp(vsp-&gt;command.sop.partName, partName, sizeof(vsp-&gt;command.sop.partName))) {
+ 	    break;
+ 	}
+     }
+ 
+     if (queue_IsEnd(&amp;SalvageHashTable[idx], qp)) {
+ 	vsp = NULL;
+     }
+     return vsp;
+ }
+ 
+ static struct SalvageQueueNode *
+ LookupNodeByCommand(SALVSYNC_command_hdr * qry)
+ {
+     return LookupNode(qry-&gt;volume, qry-&gt;partName);
+ }
+ 
+ static void
+ AddNodeToHash(struct SalvageQueueNode * node)
+ {
+     int idx = VSHASH(node-&gt;command.sop.volume);
+ 
+     if (queue_IsOnQueue(&amp;node-&gt;hash_chain)) {
+ 	return;
+     }
+ 
+     queue_Append(&amp;SalvageHashTable[idx], &amp;node-&gt;hash_chain);
+     SalvageHashTable[idx].len++;
+ }
+ 
+ static void
+ DeleteNodeFromHash(struct SalvageQueueNode * node)
+ {
+     int idx = VSHASH(node-&gt;command.sop.volume);
+ 
+     if (queue_IsNotOnQueue(&amp;node-&gt;hash_chain)) {
+ 	return;
+     }
+ 
+     queue_Remove(&amp;node-&gt;hash_chain);
+     SalvageHashTable[idx].len--;
+ }
+ 
+ void
+ SALVSYNC_salvInit(void)
+ {
+     int i;
+     pthread_t tid;
+     pthread_attr_t tattr;
+ 
+     /* initialize the queues */
+     assert(pthread_cond_init(&amp;salvageQueue.cv, NULL) == 0);
+     for (i = 0; i &lt;= VOLMAXPARTS; i++) {
+ 	queue_Init(&amp;salvageQueue.part[i]);
+ 	salvageQueue.len[i] = 0;
+     }
+     assert(pthread_cond_init(&amp;pendingQueue.queue_change_cv, NULL) == 0);
+     queue_Init(&amp;pendingQueue);
+     salvageQueue.total_len = pendingQueue.len = 0;
+     salvageQueue.last_insert = -1;
+     memset(partition_salvaging, 0, sizeof(partition_salvaging));
+ 
+     for (i = 0; i &lt; VSHASH_SIZE; i++) {
+ 	assert(pthread_cond_init(&amp;SalvageHashTable[i].queue_change_cv, NULL) == 0);
+ 	SalvageHashTable[i].len = 0;
+ 	queue_Init(&amp;SalvageHashTable[i]);
+     }
+ 
+     /* start the salvsync thread */
+     assert(pthread_attr_init(&amp;tattr) == 0);
+     assert(pthread_attr_setdetachstate(&amp;tattr, PTHREAD_CREATE_DETACHED) == 0);
+     assert(pthread_create(&amp;tid, &amp;tattr, SALVSYNC_syncThread, NULL) == 0);
+ }
+ 
+ static int
+ getport(struct sockaddr_in *addr)
+ {
+     int sd;
+ 
+     memset(addr, 0, sizeof(*addr));
+     assert((sd = socket(AF_INET, SOCK_STREAM, 0)) &gt;= 0);
+ #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
+     addr-&gt;sin_len = sizeof(struct sockaddr_in);
+ #endif
+     addr-&gt;sin_addr.s_addr = htonl(0x7f000001);
+     addr-&gt;sin_family = AF_INET;	/* was localhost-&gt;h_addrtype */
+     addr-&gt;sin_port = htons(2041);	/* XXXX htons not _really_ neccessary */
+ 
+     return sd;
+ }
+ 
+ static fd_set SALVSYNC_readfds;
+ 
+ static void *
+ SALVSYNC_syncThread(void * args)
+ {
+     struct sockaddr_in addr;
+     int on = 1;
+     int code;
+     int numTries;
+     int tid;
+ 
+ #ifndef AFS_NT40_ENV
+     (void)signal(SIGPIPE, SIG_IGN);
+ #endif
+ 
+     /* set our 'thread-id' so that the host hold table works */
+     MUTEX_ENTER(&amp;rx_stats_mutex);	/* protects rxi_pthread_hinum */
+     tid = ++rxi_pthread_hinum;
+     MUTEX_EXIT(&amp;rx_stats_mutex);
+     pthread_setspecific(rx_thread_id_key, (void *)tid);
+     Log("Set thread id %d for SALVSYNC_syncThread\n", tid);
+ 
+     AcceptSd = getport(&amp;addr);
+     /* Reuseaddr needed because system inexplicably leaves crud lying around */
+     code =
+ 	setsockopt(AcceptSd, SOL_SOCKET, SO_REUSEADDR, (char *)&amp;on,
+ 		   sizeof(on));
+     if (code)
+ 	Log("SALVSYNC_sync: setsockopt failed with (%d)\n", errno);
+ 
+     for (numTries = 0; numTries &lt; MAX_BIND_TRIES; numTries++) {
+ 	if ((code =
+ 	     bind(AcceptSd, (struct sockaddr *)&amp;addr, sizeof(addr))) == 0)
+ 	    break;
+ 	Log("SALVSYNC_sync: bind failed with (%d), will sleep and retry\n",
+ 	    errno);
+ 	sleep(5);
+     }
+     assert(!code);
+     listen(AcceptSd, 100);
+     InitHandler();
+     AcceptOn();
+ 
+     for (;;) {
+ 	int maxfd;
+ 	GetHandler(&amp;SALVSYNC_readfds, &amp;maxfd);
+ 	/* Note: check for &gt;= 1 below is essential since IOMGR_select
+ 	 * doesn't have exactly same semantics as select.
+ 	 */
+ 	if (select(maxfd + 1, &amp;SALVSYNC_readfds, NULL, NULL, NULL) &gt;= 1)
+ 	    CallHandler(&amp;SALVSYNC_readfds);
+     }
+ 
+     return NULL;
+ }
+ 
+ static void
+ SALVSYNC_newconnection(int afd)
+ {
+     struct sockaddr_in other;
+     int junk, fd;
+     junk = sizeof(other);
+     fd = accept(afd, (struct sockaddr *)&amp;other, &amp;junk);
+     if (fd == -1) {
+ 	Log("SALVSYNC_newconnection:  accept failed, errno==%d\n", errno);
+ 	assert(1 == 2);
+     } else if (!AddHandler(fd, SALVSYNC_com)) {
+ 	AcceptOff();
+ 	assert(AddHandler(fd, SALVSYNC_com));
+     }
+ }
+ 
+ /* this function processes commands from an salvsync file descriptor (fd) */
+ static afs_int32 SALV_cnt = 0;
+ static void
+ SALVSYNC_com(int fd)
+ {
+     SYNC_command com;
+     SYNC_response res;
+     SALVSYNC_response_hdr sres_hdr;
+     SALVSYNC_command scom;
+     SALVSYNC_response sres;
+     SYNC_PROTO_BUF_DECL(buf);
+     
+     com.payload.buf = (void *)buf;
+     com.payload.len = SYNC_PROTO_MAX_LEN;
+     res.payload.buf = (void *) &amp;sres_hdr;
+     res.payload.len = sizeof(sres_hdr);
+     res.hdr.response_len = sizeof(res.hdr) + sizeof(sres_hdr);
+     res.hdr.proto_version = SALVSYNC_PROTO_VERSION;
+ 
+     scom.hdr = &amp;com.hdr;
+     scom.sop = (SALVSYNC_command_hdr *) buf;
+     scom.com = &amp;com;
+     sres.hdr = &amp;res.hdr;
+     sres.sop = &amp;sres_hdr;
+     sres.res = &amp;res;
+ 
+     SALV_cnt++;
+     if (SYNC_getCom(fd, &amp;com)) {
+ 	Log("SALVSYNC_com:  read failed; dropping connection (cnt=%d)\n", SALV_cnt);
+ 	SALVSYNC_Drop(fd);
+ 	return;
+     }
+ 
+     if (com.hdr.proto_version != SALVSYNC_PROTO_VERSION) {
+ 	Log("SALVSYNC_com:  invalid protocol version (%u)\n", com.hdr.proto_version);
+ 	res.hdr.response = SYNC_COM_ERROR;
+ 	res.hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;
+ 	goto respond;
+     }
+ 
+     if (com.recv_len != (sizeof(com.hdr) + sizeof(SALVSYNC_command_hdr))) {
+ 	Log("SALVSYNC_com:  invalid protocol message length (%u)\n", com.recv_len);
+ 	res.hdr.response = SYNC_COM_ERROR;
+ 	res.hdr.reason = SYNC_REASON_MALFORMED_PACKET;
+ 	res.hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;
+ 	goto respond;
+     }
+ 
+     VOL_LOCK;
+     switch (com.hdr.command) {
+     case SALVSYNC_NOP:
+ 	break;
+     case SALVSYNC_SALVAGE:
+ 	res.hdr.response = SALVSYNC_com_Salvage(&amp;scom, &amp;sres);
+ 	break;
+     case SALVSYNC_CANCEL:
+ 	/* cancel a salvage */
+ 	res.hdr.response = SALVSYNC_com_Cancel(&amp;scom, &amp;sres);
+ 	break;
+     case SALVSYNC_CANCELALL:
+ 	/* cancel all queued salvages */
+ 	res.hdr.response = SALVSYNC_com_CancelAll(&amp;scom, &amp;sres);
+ 	break;
+     case SALVSYNC_RAISEPRIO:
+ 	/* raise the priority of a salvage */
+ 	res.hdr.response = SALVSYNC_com_RaisePrio(&amp;scom, &amp;sres);
+ 	break;
+     case SALVSYNC_QUERY:
+ 	/* query whether a volume is done salvaging */
+ 	res.hdr.response = SALVSYNC_com_Query(&amp;scom, &amp;sres);
+ 	break;
+     case SYNC_COM_CHANNEL_CLOSE:
+ 	res.hdr.response = SYNC_OK;
+ 	res.hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;
+ 	break;
+     default:
+ 	res.hdr.response = SYNC_BAD_COMMAND;
+ 	break;
+     }
+ 
+     sres_hdr.sq_len = salvageQueue.total_len;
+     sres_hdr.pq_len = pendingQueue.len;
+     VOL_UNLOCK;
+ 
+  respond:
+     SYNC_putRes(fd, &amp;res);
+     if (res.hdr.flags &amp; SYNC_FLAG_CHANNEL_SHUTDOWN) {
+ 	SALVSYNC_Drop(fd);
+     }
+ }
+ 
+ static afs_int32
+ SALVSYNC_com_Salvage(SALVSYNC_command * com, SALVSYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     struct SalvageQueueNode * node;
+ 
+     if (SYNC_verifyProtocolString(com-&gt;sop-&gt;partName, sizeof(com-&gt;sop-&gt;partName))) {
+ 	code = SYNC_FAILED;
+ 	res-&gt;hdr-&gt;reason = SYNC_REASON_MALFORMED_PACKET;
+ 	goto done;
+     }
+ 
+     node = LookupNodeByCommand(com-&gt;sop);
+ 
+     /* schedule a salvage for this volume */
+     if (node != NULL) {
+ 	switch (node-&gt;state) {
+ 	case SALVSYNC_STATE_ERROR:
+ 	case SALVSYNC_STATE_DONE:
+ 	    memcpy(&amp;node-&gt;command.com, com-&gt;hdr, sizeof(SYNC_command_hdr));
+ 	    memcpy(&amp;node-&gt;command.sop, com-&gt;sop, sizeof(SALVSYNC_command_hdr));
+ 	    node-&gt;command.sop.prio = 0;
+ 	    if (AddToSalvageQueue(node)) {
+ 		code = SYNC_DENIED;
+ 	    }
+ 	    break;
+ 	default:
+ 	    break;
+ 	}
+     } else {
+ 	node = (struct SalvageQueueNode *) malloc(sizeof(struct SalvageQueueNode));
+ 	if (node == NULL) {
+ 	    code = SYNC_DENIED;
+ 	    goto done;
+ 	}
+ 	memset(node, 0, sizeof(struct SalvageQueueNode));
+ 	memcpy(&amp;node-&gt;command.com, com-&gt;hdr, sizeof(SYNC_command_hdr));
+ 	memcpy(&amp;node-&gt;command.sop, com-&gt;sop, sizeof(SALVSYNC_command_hdr));
+ 	AddNodeToHash(node);
+ 	if (AddToSalvageQueue(node)) {
+ 	    /* roll back */
+ 	    DeleteNodeFromHash(node);
+ 	    free(node);
+ 	    node = NULL;
+ 	    code = SYNC_DENIED;
+ 	    goto done;
+ 	}
+     }
+ 
+     res-&gt;hdr-&gt;flags |= SALVSYNC_FLAG_VOL_STATS_VALID;
+     res-&gt;sop-&gt;state = node-&gt;state;
+     res-&gt;sop-&gt;prio = node-&gt;command.sop.prio;
+ 
+  done:
+     return code;
+ }
+ 
+ static afs_int32
+ SALVSYNC_com_Cancel(SALVSYNC_command * com, SALVSYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     struct SalvageQueueNode * node;
+ 
+     if (SYNC_verifyProtocolString(com-&gt;sop-&gt;partName, sizeof(com-&gt;sop-&gt;partName))) {
+ 	code = SYNC_FAILED;
+ 	res-&gt;hdr-&gt;reason = SYNC_REASON_MALFORMED_PACKET;
+ 	goto done;
+     }
+ 
+     node = LookupNodeByCommand(com-&gt;sop);
+ 
+     if (node == NULL) {
+ 	res-&gt;sop-&gt;state = SALVSYNC_STATE_UNKNOWN;
+ 	res-&gt;sop-&gt;prio = 0;
+     } else {
+ 	res-&gt;hdr-&gt;flags |= SALVSYNC_FLAG_VOL_STATS_VALID;
+ 	res-&gt;sop-&gt;prio = node-&gt;command.sop.prio;
+ 	res-&gt;sop-&gt;state = node-&gt;state;
+ 	if (node-&gt;state == SALVSYNC_STATE_QUEUED) {
+ 	    DeleteFromSalvageQueue(node);
+ 	}
+     }
+ 
+  done:
+     return code;
+ }
+ 
+ static afs_int32
+ SALVSYNC_com_CancelAll(SALVSYNC_command * com, SALVSYNC_response * res)
+ {
+     struct SalvageQueueNode * np, *nnp;
+     struct DiskPartition * dp;
+ 
+     for (dp = DiskPartitionList ; dp ; dp = dp-&gt;next) {
+ 	for (queue_Scan(&amp;salvageQueue.part[dp-&gt;index], np, nnp, SalvageQueueNode)) {
+ 	    DeleteFromSalvageQueue(np);
+ 	}
+     }
+ 
+     return SYNC_OK;
+ }
+ 
+ static afs_int32
+ SALVSYNC_com_RaisePrio(SALVSYNC_command * com, SALVSYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     struct SalvageQueueNode * node;
+ 
+     if (SYNC_verifyProtocolString(com-&gt;sop-&gt;partName, sizeof(com-&gt;sop-&gt;partName))) {
+ 	code = SYNC_FAILED;
+ 	res-&gt;hdr-&gt;reason = SYNC_REASON_MALFORMED_PACKET;
+ 	goto done;
+     }
+ 
+     node = LookupNodeByCommand(com-&gt;sop);
+ 
+     /* raise the priority of a salvage */
+     if (node == NULL) {
+ 	code = SALVSYNC_com_Salvage(com, res);
+ 	node = LookupNodeByCommand(com-&gt;sop);
+     } else {
+ 	switch (node-&gt;state) {
+ 	case SALVSYNC_STATE_QUEUED:
+ 	    RaiseCommandPrio(node, com-&gt;sop);
+ 	    break;
+ 	case SALVSYNC_STATE_SALVAGING:
+ 	    break;
+ 	case SALVSYNC_STATE_ERROR:
+ 	case SALVSYNC_STATE_DONE:
+ 	    code = SALVSYNC_com_Salvage(com, res);
+ 	    break;
+ 	default:
+ 	    break;
+ 	}
+     }
+ 
+     if (node == NULL) {
+ 	res-&gt;sop-&gt;prio = 0;
+ 	res-&gt;sop-&gt;state = SALVSYNC_STATE_UNKNOWN;
+     } else {
+ 	res-&gt;hdr-&gt;flags |= SALVSYNC_FLAG_VOL_STATS_VALID;
+ 	res-&gt;sop-&gt;prio = node-&gt;command.sop.prio;
+ 	res-&gt;sop-&gt;state = node-&gt;state;
+     }
+ 
+  done:
+     return code;
+ }
+ 
+ static afs_int32
+ SALVSYNC_com_Query(SALVSYNC_command * com, SALVSYNC_response * res)
+ {
+     afs_int32 code = SYNC_OK;
+     struct SalvageQueueNode * node;
+ 
+     if (SYNC_verifyProtocolString(com-&gt;sop-&gt;partName, sizeof(com-&gt;sop-&gt;partName))) {
+ 	code = SYNC_FAILED;
+ 	res-&gt;hdr-&gt;reason = SYNC_REASON_MALFORMED_PACKET;
+ 	goto done;
+     }
+ 
+     node = LookupNodeByCommand(com-&gt;sop);
+ 
+     /* query whether a volume is done salvaging */
+     if (node == NULL) {
+ 	res-&gt;sop-&gt;state = SALVSYNC_STATE_UNKNOWN;
+ 	res-&gt;sop-&gt;prio = 0;
+     } else {
+ 	res-&gt;hdr-&gt;flags |= SALVSYNC_FLAG_VOL_STATS_VALID;
+ 	res-&gt;sop-&gt;state = node-&gt;state;
+ 	res-&gt;sop-&gt;prio = node-&gt;command.sop.prio;
+     }
+ 
+  done:
+     return code;
+ }
+ 
+ static void
+ SALVSYNC_Drop(int fd)
+ {
+     RemoveHandler(fd);
+ #ifdef AFS_NT40_ENV
+     closesocket(fd);
+ #else
+     close(fd);
+ #endif
+     AcceptOn();
+ }
+ 
+ static int AcceptHandler = -1;	/* handler id for accept, if turned on */
+ 
+ static void
+ AcceptOn(void)
+ {
+     if (AcceptHandler == -1) {
+ 	assert(AddHandler(AcceptSd, SALVSYNC_newconnection));
+ 	AcceptHandler = FindHandler(AcceptSd);
+     }
+ }
+ 
+ static void
+ AcceptOff(void)
+ {
+     if (AcceptHandler != -1) {
+ 	assert(RemoveHandler(AcceptSd));
+ 	AcceptHandler = -1;
+     }
+ }
+ 
+ /* The multiple FD handling code. */
+ 
+ static int HandlerFD[MAXHANDLERS];
+ static void (*HandlerProc[MAXHANDLERS]) (int);
+ 
+ static void
+ InitHandler(void)
+ {
+     register int i;
+     ObtainWriteLock(&amp;SALVSYNC_handler_lock);
+     for (i = 0; i &lt; MAXHANDLERS; i++) {
+ 	HandlerFD[i] = -1;
+ 	HandlerProc[i] = NULL;
+     }
+     ReleaseWriteLock(&amp;SALVSYNC_handler_lock);
+ }
+ 
+ static void
+ CallHandler(fd_set * fdsetp)
+ {
+     register int i;
+     ObtainReadLock(&amp;SALVSYNC_handler_lock);
+     for (i = 0; i &lt; MAXHANDLERS; i++) {
+ 	if (HandlerFD[i] &gt;= 0 &amp;&amp; FD_ISSET(HandlerFD[i], fdsetp)) {
+ 	    ReleaseReadLock(&amp;SALVSYNC_handler_lock);
+ 	    (*HandlerProc[i]) (HandlerFD[i]);
+ 	    ObtainReadLock(&amp;SALVSYNC_handler_lock);
+ 	}
+     }
+     ReleaseReadLock(&amp;SALVSYNC_handler_lock);
+ }
+ 
+ static int
+ AddHandler(int afd, void (*aproc) (int))
+ {
+     register int i;
+     ObtainWriteLock(&amp;SALVSYNC_handler_lock);
+     for (i = 0; i &lt; MAXHANDLERS; i++)
+ 	if (HandlerFD[i] == -1)
+ 	    break;
+     if (i &gt;= MAXHANDLERS) {
+ 	ReleaseWriteLock(&amp;SALVSYNC_handler_lock);
+ 	return 0;
+     }
+     HandlerFD[i] = afd;
+     HandlerProc[i] = aproc;
+     ReleaseWriteLock(&amp;SALVSYNC_handler_lock);
+     return 1;
+ }
+ 
+ static int
+ FindHandler(register int afd)
+ {
+     register int i;
+     ObtainReadLock(&amp;SALVSYNC_handler_lock);
+     for (i = 0; i &lt; MAXHANDLERS; i++)
+ 	if (HandlerFD[i] == afd) {
+ 	    ReleaseReadLock(&amp;SALVSYNC_handler_lock);
+ 	    return i;
+ 	}
+     ReleaseReadLock(&amp;SALVSYNC_handler_lock);	/* just in case */
+     assert(1 == 2);
+     return -1;			/* satisfy compiler */
+ }
+ 
+ static int
+ FindHandler_r(register int afd)
+ {
+     register int i;
+     for (i = 0; i &lt; MAXHANDLERS; i++)
+ 	if (HandlerFD[i] == afd) {
+ 	    return i;
+ 	}
+     assert(1 == 2);
+     return -1;			/* satisfy compiler */
+ }
+ 
+ static int
+ RemoveHandler(register int afd)
+ {
+     ObtainWriteLock(&amp;SALVSYNC_handler_lock);
+     HandlerFD[FindHandler_r(afd)] = -1;
+     ReleaseWriteLock(&amp;SALVSYNC_handler_lock);
+     return 1;
+ }
+ 
+ static void
+ GetHandler(fd_set * fdsetp, int *maxfdp)
+ {
+     register int i;
+     register int maxfd = -1;
+     FD_ZERO(fdsetp);
+     ObtainReadLock(&amp;SALVSYNC_handler_lock);	/* just in case */
+     for (i = 0; i &lt; MAXHANDLERS; i++)
+ 	if (HandlerFD[i] != -1) {
+ 	    FD_SET(HandlerFD[i], fdsetp);
+ 	    if (maxfd &lt; HandlerFD[i])
+ 		maxfd = HandlerFD[i];
+ 	}
+     *maxfdp = maxfd;
+     ReleaseReadLock(&amp;SALVSYNC_handler_lock);	/* just in case */
+ }
+ 
+ static int
+ AddToSalvageQueue(struct SalvageQueueNode * node)
+ {
+     afs_int32 id;
+ 
+     id = volutil_GetPartitionID(node-&gt;command.sop.partName);
+     if (id &lt; 0 || id &gt; VOLMAXPARTS) {
+ 	return 1;
+     }
+     if (!VGetPartitionById_r(id, 0)) {
+ 	/* don't enqueue salvage requests for unmounted partitions */
+ 	return 1;
+     }
+     queue_Append(&amp;salvageQueue.part[id], node);
+     salvageQueue.len[id]++;
+     salvageQueue.total_len++;
+     salvageQueue.last_insert = id;
+     node-&gt;partition_id = id;
+     node-&gt;state = SALVSYNC_STATE_QUEUED;
+     assert(pthread_cond_broadcast(&amp;salvageQueue.cv) == 0);
+     return 0;
+ }
+ 
+ static void
+ DeleteFromSalvageQueue(struct SalvageQueueNode * node)
+ {
+     if (queue_IsOnQueue(node)) {
+ 	queue_Remove(node);
+ 	salvageQueue.len[node-&gt;partition_id]--;
+ 	salvageQueue.total_len--;
+ 	node-&gt;state = SALVSYNC_STATE_UNKNOWN;
+ 	assert(pthread_cond_broadcast(&amp;salvageQueue.cv) == 0);
+     }
+ }
+ 
+ static void
+ AddToPendingQueue(struct SalvageQueueNode * node)
+ {
+     queue_Append(&amp;pendingQueue, node);
+     pendingQueue.len++;
+     node-&gt;state = SALVSYNC_STATE_SALVAGING;
+     assert(pthread_cond_broadcast(&amp;pendingQueue.queue_change_cv) == 0);
+ }
+ 
+ static void
+ DeleteFromPendingQueue(struct SalvageQueueNode * node)
+ {
+     if (queue_IsOnQueue(node)) {
+ 	queue_Remove(node);
+ 	pendingQueue.len--;
+ 	node-&gt;state = SALVSYNC_STATE_UNKNOWN;
+ 	assert(pthread_cond_broadcast(&amp;pendingQueue.queue_change_cv) == 0);
+     }
+ }
+ 
+ static struct SalvageQueueNode *
+ LookupPendingCommand(SALVSYNC_command_hdr * qry)
+ {
+     struct SalvageQueueNode * np, * nnp;
+ 
+     for (queue_Scan(&amp;pendingQueue, np, nnp, SalvageQueueNode)) {
+ 	if ((np-&gt;command.sop.volume == qry-&gt;volume) &amp;&amp; 
+ 	    !strncmp(np-&gt;command.sop.partName, qry-&gt;partName,
+ 		     sizeof(qry-&gt;partName)))
+ 	    break;
+     }
+ 
+     if (queue_IsEnd(&amp;pendingQueue, np))
+ 	np = NULL;
+     return np;
+ }
+ 
+ static struct SalvageQueueNode *
+ LookupPendingCommandByPid(int pid)
+ {
+     struct SalvageQueueNode * np, * nnp;
+ 
+     for (queue_Scan(&amp;pendingQueue, np, nnp, SalvageQueueNode)) {
+ 	if (np-&gt;pid == pid)
+ 	    break;
+     }
+ 
+     if (queue_IsEnd(&amp;pendingQueue, np))
+ 	np = NULL;
+     return np;
+ }
+ 
+ 
+ /* raise the priority of a previously scheduled salvage */
+ static void
+ RaiseCommandPrio(struct SalvageQueueNode * node, SALVSYNC_command_hdr * com)
+ {
+     struct SalvageQueueNode *np, *nnp;
+     afs_int32 id;
+ 
+     assert(queue_IsOnQueue(node));
+ 
+     node-&gt;command.sop.prio = com-&gt;prio;
+     id = node-&gt;partition_id;
+     if (queue_First(&amp;salvageQueue.part[id], SalvageQueueNode)-&gt;command.sop.prio &lt; com-&gt;prio) {
+ 	queue_Remove(node);
+ 	queue_Prepend(&amp;salvageQueue.part[id], node);
+     } else {
+ 	for (queue_ScanBackwardsFrom(&amp;salvageQueue.part[id], node, np, nnp, SalvageQueueNode)) {
+ 	    if (np-&gt;command.sop.prio &gt; com-&gt;prio)
+ 		break;
+ 	}
+ 	if (queue_IsEnd(&amp;salvageQueue.part[id], np)) {
+ 	    queue_Remove(node);
+ 	    queue_Prepend(&amp;salvageQueue.part[id], node);
+ 	} else if (node != np) {
+ 	    queue_Remove(node);
+ 	    queue_InsertAfter(np, node);
+ 	}
+     }
+ }
+ 
+ /* this will need to be rearchitected if we ever want more than one thread
+  * to wait for new salvage nodes */
+ struct SalvageQueueNode * 
+ SALVSYNC_getWork(void)
+ {
+     int i, ret;
+     struct DiskPartition * dp = NULL, * fdp;
+     static afs_int32 next_part_sched = 0;
+     struct SalvageQueueNode *node = NULL, *np;
+ 
+     VOL_LOCK;
+ 
+     /*
+      * wait for work to be scheduled
+      * if there are no disk partitions, just sit in this wait loop forever
+      */
+     while (!salvageQueue.total_len || !DiskPartitionList) {
+       assert(pthread_cond_wait(&amp;salvageQueue.cv, &amp;vol_glock_mutex) == 0);
+     }
+ 
+ 
+     /* 
+      * short circuit for simple case where only one partition has
+      * scheduled salvages
+      */
+     if (salvageQueue.last_insert &gt;= 0 &amp;&amp; salvageQueue.last_insert &lt;= VOLMAXPARTS &amp;&amp;
+ 	(salvageQueue.total_len == salvageQueue.len[salvageQueue.last_insert])) {
+ 	node = queue_First(&amp;salvageQueue.part[salvageQueue.last_insert], SalvageQueueNode);
+ 	goto have_node;
+     }
+ 
+ 
+     /* 
+      * ok, more than one partition has scheduled salvages.
+      * now search for partitions with scheduled salvages, but no pending salvages. 
+      */
+     dp = VGetPartitionById_r(next_part_sched, 0);
+     if (!dp) {
+ 	dp = DiskPartitionList;
+     }
+     fdp = dp;
+ 
+     for (i=0 ; 
+ 	 !i || dp != fdp ; 
+ 	 dp = (dp-&gt;next) ? dp-&gt;next : DiskPartitionList, i++ ) {
+ 	if (!partition_salvaging[dp-&gt;index] &amp;&amp; salvageQueue.len[dp-&gt;index]) {
+ 	    node = queue_First(&amp;salvageQueue.part[dp-&gt;index], SalvageQueueNode);
+ 	    goto have_node;
+ 	}
+     }
+ 
+ 
+     /*
+      * all partitions with scheduled salvages have at least one pending.
+      * now do an exhaustive search for a scheduled salvage.
+      */
+     dp = fdp;
+ 
+     for (i=0 ; 
+ 	 !i || dp != fdp ; 
+ 	 dp = (dp-&gt;next) ? dp-&gt;next : DiskPartitionList, i++ ) {
+ 	if (salvageQueue.len[dp-&gt;index]) {
+ 	    node = queue_First(&amp;salvageQueue.part[dp-&gt;index], SalvageQueueNode);
+ 	    goto have_node;
+ 	}
+     }
+ 
+     /* we should never reach this line */
+     assert(1==2);
+ 
+  have_node:
+     assert(node != NULL);
+     node-&gt;pid = 0;
+     partition_salvaging[node-&gt;partition_id]++;
+     DeleteFromSalvageQueue(node);
+     AddToPendingQueue(node);
+ 
+     if (dp) {
+ 	/* update next_part_sched field */
+ 	if (dp-&gt;next) {
+ 	    next_part_sched = dp-&gt;next-&gt;index;
+ 	} else if (DiskPartitionList) {
+ 	    next_part_sched = DiskPartitionList-&gt;index;
+ 	} else {
+ 	    next_part_sched = -1;
+ 	}
+     }
+ 
+  bail:
+     VOL_UNLOCK;
+     return node;
+ }
+ 
+ static void
+ SALVSYNC_doneWork_r(struct SalvageQueueNode * node, int result)
+ {
+     afs_int32 partid;
+     DeleteFromPendingQueue(node);
+     partid = node-&gt;partition_id;
+     if (partid &gt;=0 &amp;&amp; partid &lt;= VOLMAXPARTS) {
+ 	partition_salvaging[partid]--;
+     }
+     if (result == 0) {
+ 	node-&gt;state = SALVSYNC_STATE_DONE;
+     } else {
+ 	node-&gt;state = SALVSYNC_STATE_ERROR;
+     }
+ }
+ 
+ void 
+ SALVSYNC_doneWork(struct SalvageQueueNode * node, int result)
+ {
+     VOL_LOCK;
+     SALVSYNC_doneWork_r(node, result);
+     VOL_UNLOCK;
+ }
+ 
+ void
+ SALVSYNC_doneWorkByPid(int pid, int result)
+ {
+     struct SalvageQueueNode * node;
+ 
+     VOL_LOCK;
+     node = LookupPendingCommandByPid(pid);
+     if (node != NULL) {
+ 	SALVSYNC_doneWork_r(node, result);
+     }
+     VOL_UNLOCK;
+ }
+ 
+ #endif /* AFS_DEMAND_ATTACH_FS */
Index: openafs/src/vol/salvsync.h
diff -c /dev/null openafs/src/vol/salvsync.h:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/salvsync.h	Fri Mar 17 23:20:19 2006
***************
*** 0 ****
--- 1,111 ----
+ /*
+  * Copyright 2006, Sine Nomine Associates and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  * demand attach fs
+  * salvage server interface
+  */
+ #ifndef _AFS_VOL_SALVSYNC_H
+ #define _AFS_VOL_SALVSYNC_H
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ #include "daemon_com.h"
+ 
+ 
+ #define SALVSYNC_PROTO_VERSION        1
+ 
+ 
+ /* SALVSYNC command codes */
+ #define SALVSYNC_NOP            SYNC_COM_CODE_DECL(0)   /* just return stats */
+ #define SALVSYNC_SALVAGE	SYNC_COM_CODE_DECL(1)	/* schedule a salvage */
+ #define SALVSYNC_CANCEL         SYNC_COM_CODE_DECL(2)   /* Cancel a salvage */
+ #define SALVSYNC_RAISEPRIO      SYNC_COM_CODE_DECL(3)   /* move a salvage operation to
+ 							 * the head of the work queue */
+ #define SALVSYNC_QUERY          SYNC_COM_CODE_DECL(4)   /* query the status of a salvage */
+ #define SALVSYNC_CANCELALL      SYNC_COM_CODE_DECL(5)   /* cancel all pending salvages */
+ 
+ /* SALVSYNC reason codes */
+ #define SALVSYNC_WHATEVER	SYNC_REASON_CODE_DECL(0)  /* XXXX */
+ #define SALVSYNC_ERROR		SYNC_REASON_CODE_DECL(1)  /* volume is in error state */
+ #define SALVSYNC_OPERATOR	SYNC_REASON_CODE_DECL(2)  /* operator forced salvage */
+ #define SALVSYNC_SHUTDOWN       SYNC_REASON_CODE_DECL(3)  /* cancel due to shutdown */
+ #define SALVSYNC_NEEDED         SYNC_REASON_CODE_DECL(4)  /* needsSalvaged flag set */
+ 
+ /* SALVSYNC response codes */
+ 
+ /* SALVSYNC flags */
+ #define SALVSYNC_FLAG_VOL_STATS_VALID SYNC_FLAG_CODE_DECL(0) /* volume stats in response are valid */
+ 
+ /* SALVSYNC command state fields */
+ #define SALVSYNC_STATE_UNKNOWN        0         /* unknown state */
+ #define SALVSYNC_STATE_QUEUED         1         /* salvage request on queue */
+ #define SALVSYNC_STATE_SALVAGING      2         /* salvage is happening now */
+ #define SALVSYNC_STATE_ERROR          3         /* salvage ended in an error */
+ #define SALVSYNC_STATE_DONE           4         /* last salvage ended successfully */
+ 
+ 
+ typedef struct SALVSYNC_command_hdr {
+     afs_uint32 prio;
+     afs_uint32 volume;
+     char partName[16];		/* partition name, e.g. /vicepa */
+ } SALVSYNC_command_hdr;
+ 
+ typedef struct SALVSYNC_response_hdr {
+     afs_int32 state;
+     afs_int32 prio;
+     afs_int32 sq_len;
+     afs_int32 pq_len;
+ } SALVSYNC_response_hdr;
+ 
+ typedef struct SALVSYNC_command {
+     SYNC_command_hdr * hdr;
+     SALVSYNC_command_hdr * sop;
+     SYNC_command * com;
+ } SALVSYNC_command;
+ 
+ typedef struct SALVSYNC_response {
+     SYNC_response_hdr * hdr;
+     SALVSYNC_response_hdr * sop;
+     SYNC_response * res;
+ } SALVSYNC_response;
+ 
+ typedef struct SALVSYNC_command_info {
+     SYNC_command_hdr com;
+     SALVSYNC_command_hdr sop;
+ } SALVSYNC_command_info;
+ 
+ struct SalvageQueueNode {
+     struct rx_queue q;
+     struct rx_queue hash_chain;
+     afs_uint32 state;
+     struct SALVSYNC_command_info command;
+     afs_int32 partition_id;
+     int pid;
+ };
+ 
+ 
+ /* Prototypes from salvsync.c */
+ 
+ /* online salvager client interfaces */
+ extern int SALVSYNC_clientFinis(void);
+ extern int SALVSYNC_clientInit(void);
+ extern int SALVSYNC_clientReconnect(void);
+ extern afs_int32 SALVSYNC_askSalv(SYNC_command * com, SYNC_response * res);
+ extern afs_int32 SALVSYNC_SalvageVolume(VolumeId volume, char *partName, int com, int reason,
+ 					afs_uint32 prio, SYNC_response * res);
+ 
+ /* salvage server interfaces */
+ extern void SALVSYNC_salvInit(void);
+ extern struct SalvageQueueNode * SALVSYNC_getWork(void);
+ extern void SALVSYNC_doneWork(struct SalvageQueueNode *, int result);
+ extern void SALVSYNC_doneWorkByPid(int pid, int result);
+ 
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ #endif /* _AFS_VOL_SALVSYNC_H */
Index: openafs/src/vol/vnode.c
diff -c openafs/src/vol/vnode.c:1.26 openafs/src/vol/vnode.c:1.27
*** openafs/src/vol/vnode.c:1.26	Wed Oct 19 14:23:19 2005
--- openafs/src/vol/vnode.c	Fri Mar 17 14:54:51 2006
***************
*** 5,10 ****
--- 5,12 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /*
***************
*** 18,24 ****
  #define MAXINT     (~(1&lt;&lt;((sizeof(int)*8)-1)))
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vnode.c,v 1.26 2005/10/19 18:23:19 shadow Exp $");
  
  #include &lt;errno.h&gt;
  #include &lt;stdio.h&gt;
--- 20,26 ----
  #define MAXINT     (~(1&lt;&lt;((sizeof(int)*8)-1)))
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vnode.c,v 1.27 2006/03/17 19:54:51 shadow Exp $");
  
  #include &lt;errno.h&gt;
  #include &lt;stdio.h&gt;
***************
*** 46,51 ****
--- 48,54 ----
  #include "vnode.h"
  #include "volume.h"
  #include "partition.h"
+ #include "salvsync.h"
  #if defined(AFS_SGI_ENV)
  #include "sys/types.h"
  #include "fcntl.h"
***************
*** 73,80 ****
  struct VnodeClassInfo VnodeClassInfo[nVNODECLASSES];
  
  private int moveHash(register Vnode * vnp, bit32 newHash);
! void StickOnLruChain_r(register Vnode * vnp,
! 		       register struct VnodeClassInfo *vcp);
  
  #define BAD_IGET	-1000
  
--- 76,83 ----
  struct VnodeClassInfo VnodeClassInfo[nVNODECLASSES];
  
  private int moveHash(register Vnode * vnp, bit32 newHash);
! private void StickOnLruChain_r(register Vnode * vnp,
! 			       register struct VnodeClassInfo *vcp);
  
  #define BAD_IGET	-1000
  
***************
*** 162,167 ****
--- 165,247 ----
  #define VNODE_HASH(volumeptr,vnodenumber)\
      ((volumeptr-&gt;vnodeHashOffset + vnodenumber)&amp;(VNODE_HASH_TABLE_SIZE-1))
  
+ /*
+  * new support to secondarily hash vnodes by volume id
+  */
+ #define VNVOLUME_HASH(volumeId) (volumeId&amp;(VolumeHashTable.Mask))
+ 
+ #include "rx/rx_queue.h"
+ typedef struct VnodeHashByVolumeChainHead {
+     struct rx_queue queue;
+     int len;
+     /* someday we could put a per-chain lock here... */
+ #ifdef AFS_DEMAND_ATTACH_FS
+     int busy;
+     pthread_cond_t chain_busy_cv;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ } VnodeHashByVolumeChainHead;
+ private VnodeHashByVolumeChainHead *VnodeHashByVolumeTable = NULL;
+ 
+ void
+ VInitVnHashByVolume(void)
+ {
+     register int i;
+ 
+     VnodeHashByVolumeTable = (VnodeHashByVolumeChainHead *) calloc(VolumeHashTable.Size, 
+ 								   sizeof(VnodeHashByVolumeChainHead));
+     assert(VnodeHashByVolumeTable != NULL);
+     
+     for (i=0; i &lt; VolumeHashTable.Size; i++) {
+ 	queue_Init(&amp;VnodeHashByVolumeTable[i]);
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	assert(pthread_cond_init(&amp;VnodeHashByVolumeTable[i].chain_busy_cv, NULL) == 0);
+ #endif /* AFS_DEMAND_ATTACH_FS */
+     }
+ }
+ 
+ static void
+ AddToVnHashByVolumeTable(register Vnode * vnp)
+ {
+     VnodeHashByVolumeChainHead * head;
+ 
+     if (queue_IsOnQueue(vnp))
+ 	return;
+ 
+     head = &amp;VnodeHashByVolumeTable[VNVOLUME_HASH(vnp-&gt;volumePtr-&gt;hashid)];
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     while (head-&gt;busy) {
+ 	/* if the hash table is busy, wait */
+ 	assert(pthread_cond_wait(&amp;head-&gt;chain_busy_cv, &amp;vol_glock_mutex) == 0);
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+     head-&gt;len++;
+     queue_Append(head, vnp);
+ }
+ 
+ /* for demand-attach, caller MUST hold a ref count on vp */
+ static void
+ DeleteFromVnHashByVolumeTable(register Vnode * vnp)
+ {
+     VnodeHashByVolumeChainHead * head;
+ 
+     if (!queue_IsOnQueue(vnp))
+ 	return;
+ 
+     head = &amp;VnodeHashByVolumeTable[VNVOLUME_HASH(vnp-&gt;volumePtr-&gt;hashid)];
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     while (head-&gt;busy) {
+ 	/* if the hash table is busy, wait */
+ 	assert(pthread_cond_wait(&amp;head-&gt;chain_busy_cv, &amp;vol_glock_mutex) == 0);
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+     head-&gt;len--;
+     queue_Remove(vnp);
+ }
+ 
  /* Code to invalidate a vnode entry.  Called when we've damaged a vnode, and want
      to prevent future VGetVnode's from applying to it.  Leaves it in the same hash bucket
      but that shouldn't be important.  */
***************
*** 305,311 ****
  	unique = vp-&gt;nextVnodeUnique++;
  
      if (vp-&gt;nextVnodeUnique &gt; V_uniquifier(vp)) {
! 	VUpdateVolume_r(ec, vp);
  	if (*ec)
  	    return NULL;
      }
--- 385,391 ----
  	unique = vp-&gt;nextVnodeUnique++;
  
      if (vp-&gt;nextVnodeUnique &gt; V_uniquifier(vp)) {
! 	VUpdateVolume_r(ec, vp, VOL_UPDATE_WAIT);
  	if (*ec)
  	    return NULL;
      }
***************
*** 317,323 ****
      }
  
      /* Find a slot in the bit map */
!     bitNumber = VAllocBitmapEntry_r(ec, vp, &amp;vp-&gt;vnodeIndex[class]);
      if (*ec)
  	return NULL;
      vnodeNumber = bitNumberToVnodeNumber(bitNumber, class);
--- 397,404 ----
      }
  
      /* Find a slot in the bit map */
!     bitNumber = VAllocBitmapEntry_r(ec, vp, &amp;vp-&gt;vnodeIndex[class],
! 				    VOL_ALLOC_BITMAP_WAIT);
      if (*ec)
  	return NULL;
      vnodeNumber = bitNumberToVnodeNumber(bitNumber, class);
***************
*** 376,382 ****
  	vnp-&gt;volumePtr = vp;
  	vnp-&gt;cacheCheck = vp-&gt;cacheCheck;
  	vnp-&gt;nUsers = 1;
- 	moveHash(vnp, newHash);
  	/* This will never block */
  	ObtainWriteLock(&amp;vnp-&gt;lock);
  #ifdef AFS_PTHREAD_ENV
--- 457,462 ----
***************
*** 391,408 ****
  	    FdHandle_t *fdP;
  	    off_t off = vnodeIndexOffset(vcp, vnodeNumber);
  
  	    VOL_UNLOCK;
  	    fdP = IH_OPEN(ihP);
! 	    if (fdP == NULL)
! 		Abort("VAllocVnode: can't open index file!\n");
! 	    if ((size = FDH_SIZE(fdP)) &lt; 0)
! 		Abort("VAllocVnode: can't stat index file!\n");
! 	    if (FDH_SEEK(fdP, off, SEEK_SET) &lt; 0)
! 		Abort("VAllocVnode: can't seek on index file!\n");
! 	    if (off &lt; size) {
! 		if (FDH_READ(fdP, &amp;vnp-&gt;disk, vcp-&gt;diskSize) == vcp-&gt;diskSize) {
! 		    if (vnp-&gt;disk.type != vNull)
! 			Abort("VAllocVnode:  addled bitmap or index!\n");
  		}
  	    } else {
  		/* growing file - grow in a reasonable increment */
--- 471,503 ----
  	    FdHandle_t *fdP;
  	    off_t off = vnodeIndexOffset(vcp, vnodeNumber);
  
+ 	    /* XXX we have a potential race here if two threads
+ 	     * allocate new vnodes at the same time, and they
+ 	     * both decide it's time to extend the index
+ 	     * file size... */
+ 
  	    VOL_UNLOCK;
  	    fdP = IH_OPEN(ihP);
! 	    if (fdP == NULL) {
! 		Log("VAllocVnode: can't open index file!\n");
! 		goto error_encountered;
! 	    }
! 	    if ((size = FDH_SIZE(fdP)) &lt; 0) {
! 		Log("VAllocVnode: can't stat index file!\n");
! 		goto error_encountered;
! 	    }
! 	    if (FDH_SEEK(fdP, off, SEEK_SET) &lt; 0) {
! 		Log("VAllocVnode: can't seek on index file!\n");
! 		goto error_encountered;
! 	    }
! 	    if (off + vcp-&gt;diskSize &lt;= size) {
! 		if (FDH_READ(fdP, &amp;vnp-&gt;disk, vcp-&gt;diskSize) != vcp-&gt;diskSize) {
! 		    Log("VAllocVnode: can't read index file!\n");
! 		    goto error_encountered;
! 		}
! 		if (vnp-&gt;disk.type != vNull) {
! 		    Log("VAllocVnode:  addled bitmap or index!\n");
! 		    goto error_encountered;
  		}
  	    } else {
  		/* growing file - grow in a reasonable increment */
***************
*** 414,422 ****
--- 509,536 ----
  		free(buf);
  	    }
  	    FDH_CLOSE(fdP);
+ 	    fdP = NULL;
+ 	    VOL_LOCK;
+ 	    goto sane;
+ 
+ 	error_encountered:
+ #ifdef AFS_DEMAND_ATTACH_FS
  	    VOL_LOCK;
+ 	    VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
+ 	    if (fdP)
+ 		FDH_CLOSE(fdP);
+ 	    VInvalidateVnode_r(vnp);
+ 	    StickOnLruChain_r(vnp, vcp);
+ 	    return NULL;
+ #else
+ 	    assert(1 == 2);
+ #endif
+ 
  	}
+     sane:
  	VNLog(4, 2, vnodeNumber, (afs_int32) vnp);
+ 	AddToVnHashByVolumeTable(vnp);
+ 	moveHash(vnp, newHash);
      }
  
      VNLog(5, 1, (afs_int32) vnp);
***************
*** 510,515 ****
--- 624,631 ----
  	vcp-&gt;reads++;
  	vnp = VGetFreeVnode_r(vcp);
  	/* Remove it from the old hash chain */
+ 	if (vnp-&gt;volumePtr)
+ 	    DeleteFromVnHashByVolumeTable(vnp);
  	moveHash(vnp, newHash);
  	/* Remove it from the LRU chain */
  	if (vnp == vcp-&gt;lruHead)
***************
*** 525,530 ****
--- 641,647 ----
  	vnp-&gt;volumePtr = vp;
  	vnp-&gt;cacheCheck = vp-&gt;cacheCheck;
  	vnp-&gt;nUsers = 1;
+ 	AddToVnHashByVolumeTable(vnp);
  
  	/* This will never block */
  	ObtainWriteLock(&amp;vnp-&gt;lock);
***************
*** 540,550 ****
--- 657,677 ----
  	if (fdP == NULL) {
  	    Log("VGetVnode: can't open index dev=%u, i=%s\n", vp-&gt;device,
  		PrintInode(NULL, vp-&gt;vnodeIndex[class].handle-&gt;ih_ino));
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	    VOL_LOCK;
+ 	    VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
+ 	    VOL_UNLOCK;
+ #endif
  	    *ec = VIO;
  	    mlkReason = 9;
  	} else if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, vnodeNumber), SEEK_SET)
  		   &lt; 0) {
  	    Log("VGetVnode: can't seek on index file vn=%u\n", vnodeNumber);
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	    VOL_LOCK;
+ 	    VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
+ 	    VOL_UNLOCK;
+ #endif
  	    *ec = VIO;
  	    mlkReason = 10;
  	    FDH_REALLYCLOSE(fdP);
***************
*** 564,571 ****
  	     * is not allocated */
  	    if (n == -1 &amp;&amp; errno == EIO) {
  		Log("VGetVnode: Couldn't read vnode %u, volume %u (%s); volume needs salvage\n", vnodeNumber, V_id(vp), V_name(vp));
! 		VForceOffline_r(vp);
  		*ec = VSALVAGE;
  		mlkReason = 4;
  	    } else {
  		mlkReason = 5;
--- 691,708 ----
  	     * is not allocated */
  	    if (n == -1 &amp;&amp; errno == EIO) {
  		Log("VGetVnode: Couldn't read vnode %u, volume %u (%s); volume needs salvage\n", vnodeNumber, V_id(vp), V_name(vp));
! #ifdef AFS_DEMAND_ATTACH_FS
! 		if (programType == fileServer) {
! 		    VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
! 		    *ec = VSALVAGING;
! 		} else {
! 		    VForceOffline_r(vp, 0);
! 		    *ec = VSALVAGE;
! 		}
! #else
! 		VForceOffline_r(vp, 0);
  		*ec = VSALVAGE;
+ #endif
  		mlkReason = 4;
  	    } else {
  		mlkReason = 5;
***************
*** 603,611 ****
--- 740,758 ----
  		    *ec = VNOVNODE;
  		} else {
  		    Log("VGetVnode: Bad magic number, vnode %u, volume %u (%s); volume needs salvage\n", vnodeNumber, V_id(vp), V_name(vp));
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 		    if (programType == fileServer) {
+ 			VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
+ 			*ec = VSALVAGING;
+ 		    } else {
+ 			vp-&gt;goingOffline = 1;
+ 			*ec = VSALVAGE;
+ 		    }
+ #else
  		    vp-&gt;goingOffline = 1;	/* used to call VOffline, but that would mess
  						 * up the volume ref count if called here */
  		    *ec = VSALVAGE;
+ #endif
  		    mlkReason = 7;
  		}
  		VInvalidateVnode_r(vnp);
***************
*** 728,747 ****
  
  	    /* The vnode has been changed. Write it out to disk */
  	    if (!V_inUse(vp)) {
  		assert(V_needsSalvaged(vp));
  		*ec = VSALVAGE;
  	    } else {
  		IHandle_t *ihP = vp-&gt;vnodeIndex[class].handle;
  		FdHandle_t *fdP;
  		VOL_UNLOCK;
  		fdP = IH_OPEN(ihP);
! 		if (fdP == NULL)
! 		    Abort("VPutVnode: can't open index file!\n");
  		offset = vnodeIndexOffset(vcp, vnp-&gt;vnodeNumber);
  		if (FDH_SEEK(fdP, offset, SEEK_SET) &lt; 0) {
! 		    Abort
! 			("VPutVnode: can't seek on index file! fdp=0x%x offset=%d, errno=%d\n",
! 			 fdP, offset, errno);
  		}
  		code = FDH_WRITE(fdP, &amp;vnp-&gt;disk, vcp-&gt;diskSize);
  		if (code != vcp-&gt;diskSize) {
--- 875,901 ----
  
  	    /* The vnode has been changed. Write it out to disk */
  	    if (!V_inUse(vp)) {
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 		VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
+ 		*ec = VSALVAGING;
+ #else
  		assert(V_needsSalvaged(vp));
  		*ec = VSALVAGE;
+ #endif
  	    } else {
  		IHandle_t *ihP = vp-&gt;vnodeIndex[class].handle;
  		FdHandle_t *fdP;
  		VOL_UNLOCK;
  		fdP = IH_OPEN(ihP);
! 		if (fdP == NULL) {
! 		    Log("VPutVnode: can't open index file!\n");
! 		    goto error_encountered;
! 		}
  		offset = vnodeIndexOffset(vcp, vnp-&gt;vnodeNumber);
  		if (FDH_SEEK(fdP, offset, SEEK_SET) &lt; 0) {
! 		    Log("VPutVnode: can't seek on index file! fdp=0x%x offset=%d, errno=%d\n",
! 			fdP, offset, errno);
! 		    goto error_encountered;
  		}
  		code = FDH_WRITE(fdP, &amp;vnp-&gt;disk, vcp-&gt;diskSize);
  		if (code != vcp-&gt;diskSize) {
***************
*** 756,763 ****
  			*ec = VIO;
  		    } else {
  			Log("VPutVnode: Couldn't write vnode %u, volume %u (%s) (error %d)\n", vnp-&gt;vnodeNumber, V_id(vnp-&gt;volumePtr), V_name(vnp-&gt;volumePtr), code);
! 			VForceOffline_r(vp);
  			*ec = VSALVAGE;
  		    }
  		    VOL_UNLOCK;
  		    FDH_REALLYCLOSE(fdP);
--- 910,922 ----
  			*ec = VIO;
  		    } else {
  			Log("VPutVnode: Couldn't write vnode %u, volume %u (%s) (error %d)\n", vnp-&gt;vnodeNumber, V_id(vnp-&gt;volumePtr), V_name(vnp-&gt;volumePtr), code);
! #ifdef AFS_DEMAND_ATTACH_FS
! 			VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
! 			*ec = VSALVAGING;
! #else
! 			VForceOffline_r(vp, 0);
  			*ec = VSALVAGE;
+ #endif
  		    }
  		    VOL_UNLOCK;
  		    FDH_REALLYCLOSE(fdP);
***************
*** 765,770 ****
--- 924,946 ----
  		    FDH_CLOSE(fdP);
  		}
  		VOL_LOCK;
+ 		goto sane;
+ 
+ 	    error_encountered:
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 		/* XXX instead of dumping core, let's try to request a salvage
+ 		 * and just fail the putvnode */
+ 		if (fdP)
+ 		    FDH_CLOSE(fdP);
+ 		VOL_LOCK;
+ 		VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
+ 		*ec = VSALVAGING;
+ 		goto done;
+ #else
+ 		assert(1 == 2);
+ #endif
+ 
+ 	    sane:
  		/* If the vnode is to be deleted, and we wrote the vnode out,
  		 * free its bitmap entry. Do after the vnode is written so we
  		 * don't allocate from bitmap before the vnode is written
***************
*** 787,792 ****
--- 963,969 ----
  		 vnp);
      }
  
+  done:
      /* Do not look at disk portion of vnode after this point; it may
       * have been deleted above */
      if (vnp-&gt;nUsers-- == 1)
***************
*** 865,883 ****
  
  	/* The inode has been changed.  Write it out to disk */
  	if (!V_inUse(vp)) {
  	    assert(V_needsSalvaged(vp));
  	    *ec = VSALVAGE;
  	} else {
  	    IHandle_t *ihP = vp-&gt;vnodeIndex[class].handle;
  	    FdHandle_t *fdP;
  	    off_t off = vnodeIndexOffset(vcp, vnp-&gt;vnodeNumber);
  	    VOL_UNLOCK;
  	    fdP = IH_OPEN(ihP);
! 	    if (fdP == NULL)
! 		Abort("VPutVnode: can't open index file!\n");
  	    code = FDH_SEEK(fdP, off, SEEK_SET);
! 	    if (code &lt; 0)
! 		Abort("VPutVnode: can't seek on index file!\n");
  	    code = FDH_WRITE(fdP, &amp;vnp-&gt;disk, vcp-&gt;diskSize);
  	    if (code != vcp-&gt;diskSize) {
  		/*
--- 1042,1069 ----
  
  	/* The inode has been changed.  Write it out to disk */
  	if (!V_inUse(vp)) {
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	    VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
+ 	    *ec = VSALVAGING;
+ #else
  	    assert(V_needsSalvaged(vp));
  	    *ec = VSALVAGE;
+ #endif
  	} else {
  	    IHandle_t *ihP = vp-&gt;vnodeIndex[class].handle;
  	    FdHandle_t *fdP;
  	    off_t off = vnodeIndexOffset(vcp, vnp-&gt;vnodeNumber);
  	    VOL_UNLOCK;
  	    fdP = IH_OPEN(ihP);
! 	    if (fdP == NULL) {
! 		Log("VPutVnode: can't open index file!\n");
! 		goto error_encountered;
! 	    }
  	    code = FDH_SEEK(fdP, off, SEEK_SET);
! 	    if (code &lt; 0) {
! 		Log("VPutVnode: can't seek on index file!\n");
! 		goto error_encountered;
! 	    }
  	    code = FDH_WRITE(fdP, &amp;vnp-&gt;disk, vcp-&gt;diskSize);
  	    if (code != vcp-&gt;diskSize) {
  		/*
***************
*** 892,905 ****
  		    *ec = VIO;
  		} else {
  		    Log("VPutVnode: Couldn't write vnode %u, volume %u (%s)\n", vnp-&gt;vnodeNumber, V_id(vnp-&gt;volumePtr), V_name(vnp-&gt;volumePtr));
! 		    VForceOffline_r(vp);
  		    *ec = VSALVAGE;
  		}
  		VOL_UNLOCK;
  	    }
  	    FDH_CLOSE(fdP);
  	    VOL_LOCK;
  	}
  	vcp-&gt;writes++;
  	vnp-&gt;changed_newTime = vnp-&gt;changed_oldTime = 0;
      }
--- 1078,1110 ----
  		    *ec = VIO;
  		} else {
  		    Log("VPutVnode: Couldn't write vnode %u, volume %u (%s)\n", vnp-&gt;vnodeNumber, V_id(vnp-&gt;volumePtr), V_name(vnp-&gt;volumePtr));
! #ifdef AFS_DEMAND_ATTACH_FS
! 		    VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
! 		    *ec = VSALVAGING;
! #else
! 		    VForceOffline_r(vp, 0);
  		    *ec = VSALVAGE;
+ #endif
  		}
  		VOL_UNLOCK;
  	    }
  	    FDH_CLOSE(fdP);
  	    VOL_LOCK;
+ 	    goto sane;
+ 
+ 	error_encountered:
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	    if (fdP)
+ 		FDH_CLOSE(fdP);
+ 	    VOL_LOCK;
+ 	    VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
+ 	    *ec = VSALVAGING;
+ #else
+ 	    assert(1 == 2);
+ #endif
+ 
  	}
+     sane:
  	vcp-&gt;writes++;
  	vnp-&gt;changed_newTime = vnp-&gt;changed_oldTime = 0;
      }
***************
*** 931,937 ****
      return 0;
  }
  
! void
  StickOnLruChain_r(register Vnode * vnp, register struct VnodeClassInfo *vcp)
  {
      /* Add it to the circular LRU list */
--- 1136,1142 ----
      return 0;
  }
  
! private void
  StickOnLruChain_r(register Vnode * vnp, register struct VnodeClassInfo *vcp)
  {
      /* Add it to the circular LRU list */
***************
*** 950,957 ****
  	vcp-&gt;lruHead = vnp-&gt;lruNext;
      /* If caching is turned off, set volumeptr to NULL to invalidate the
       * entry */
!     if (!TrustVnodeCacheEntry)
  	vnp-&gt;volumePtr = NULL;
  }
  
  /* VCloseVnodeFiles - called when a volume is going off line. All open
--- 1155,1164 ----
  	vcp-&gt;lruHead = vnp-&gt;lruNext;
      /* If caching is turned off, set volumeptr to NULL to invalidate the
       * entry */
!     if (!TrustVnodeCacheEntry) {
! 	DeleteFromVnHashByVolumeTable(vnp);
  	vnp-&gt;volumePtr = NULL;
+     }
  }
  
  /* VCloseVnodeFiles - called when a volume is going off line. All open
***************
*** 962,976 ****
  VCloseVnodeFiles_r(Volume * vp)
  {
      int i;
!     Vnode *vnp;
  
!     for (i = 0; i &lt; VNODE_HASH_TABLE_SIZE; i++) {
! 	for (vnp = VnodeHashTable[i]; vnp; vnp = vnp-&gt;hashNext) {
! 	    if (vnp-&gt;volumePtr == vp) {
! 		IH_REALLYCLOSE(vnp-&gt;handle);
! 	    }
  	}
      }
  }
  
  /* VReleaseVnodeFiles - called when a volume is going detached. All open
--- 1169,1198 ----
  VCloseVnodeFiles_r(Volume * vp)
  {
      int i;
!     Vnode *vnp, *nvnp;
!     VnodeHashByVolumeChainHead * head;
  
!     head = &amp;VnodeHashByVolumeTable[VNVOLUME_HASH(vp-&gt;hashid)];
! #ifdef AFS_DEMAND_ATTACH_FS
!     while (head-&gt;busy) {
! 	assert(pthread_cond_wait(&amp;head-&gt;chain_busy_cv, &amp;vol_glock_mutex) == 0);
!     }
! 
!     head-&gt;busy = 1;
!     VOL_UNLOCK;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
!     for (queue_Scan(head, vnp, nvnp, Vnode)) {
! 	if (vnp-&gt;volumePtr == vp) {
! 	    IH_REALLYCLOSE(vnp-&gt;handle);
  	}
      }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     VOL_LOCK;
+     head-&gt;busy = 0;
+     assert(pthread_cond_broadcast(&amp;head-&gt;chain_busy_cv) == 0);
+ #endif /* AFS_DEMAND_ATTACH_FS */
  }
  
  /* VReleaseVnodeFiles - called when a volume is going detached. All open
***************
*** 981,993 ****
  VReleaseVnodeFiles_r(Volume * vp)
  {
      int i;
!     Vnode *vnp;
  
!     for (i = 0; i &lt; VNODE_HASH_TABLE_SIZE; i++) {
! 	for (vnp = VnodeHashTable[i]; vnp; vnp = vnp-&gt;hashNext) {
! 	    if (vnp-&gt;volumePtr == vp) {
! 		IH_RELEASE(vnp-&gt;handle);
! 	    }
  	}
      }
  }
--- 1203,1231 ----
  VReleaseVnodeFiles_r(Volume * vp)
  {
      int i;
!     Vnode *vnp, *nvnp;
!     VnodeHashByVolumeChainHead * head;
  
!     head = &amp;VnodeHashByVolumeTable[VNVOLUME_HASH(vp-&gt;hashid)];
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     while (head-&gt;busy) {
! 	assert(pthread_cond_wait(&amp;head-&gt;chain_busy_cv, &amp;vol_glock_mutex) == 0);
!     }
! 
!     head-&gt;busy = 1;
!     VOL_UNLOCK;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
!     for (queue_Scan(head, vnp, nvnp, Vnode)) {
! 	if (vnp-&gt;volumePtr == vp) {
! 	    IH_RELEASE(vnp-&gt;handle);
  	}
      }
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     VOL_LOCK;
+     head-&gt;busy = 0;
+     assert(pthread_cond_broadcast(&amp;head-&gt;chain_busy_cv) == 0);
+ #endif /* AFS_DEMAND_ATTACH_FS */
  }
Index: openafs/src/vol/vnode.h
diff -c openafs/src/vol/vnode.h:1.13 openafs/src/vol/vnode.h:1.15
*** openafs/src/vol/vnode.h:1.13	Thu Apr 28 01:02:19 2005
--- openafs/src/vol/vnode.h	Fri Mar 17 14:54:51 2006
***************
*** 118,123 ****
--- 118,124 ----
  #define SIZEOF_LARGEDISKVNODE	256
  
  typedef struct Vnode {
+     struct rx_queue vid_hash;   /* for vnode by volume id hash */
      struct Vnode *hashNext;	/* Next vnode on hash conflict chain */
      struct Vnode *lruNext;	/* Less recently used vnode than this one */
      struct Vnode *lruPrev;	/* More recently used vnode than this one */
***************
*** 202,208 ****
  #define VAclDiskSize(v)		(SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
  /*extern int VolumeHashOffset(); */
  extern int VolumeHashOffset_r(void);
! extern VInitVnodes(VnodeClass class, int nVnodes);
  /*extern VInitVnodes_r();*/
  extern Vnode *VGetVnode(Error * ec, struct Volume *vp, VnodeId vnodeNumber,
  			int locktype);
--- 203,209 ----
  #define VAclDiskSize(v)		(SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
  /*extern int VolumeHashOffset(); */
  extern int VolumeHashOffset_r(void);
! extern int VInitVnodes(VnodeClass class, int nVnodes);
  /*extern VInitVnodes_r();*/
  extern Vnode *VGetVnode(Error * ec, struct Volume *vp, VnodeId vnodeNumber,
  			int locktype);
***************
*** 210,218 ****
  			  int locktype);
  extern void VPutVnode(Error * ec, register Vnode * vnp);
  extern void VPutVnode_r(Error * ec, register Vnode * vnp);
! extern VVnodeWriteToRead(Error * ec, register Vnode * vnp);
! extern VVnodeWriteToRead_r(Error * ec, register Vnode * vnp);
  extern Vnode *VAllocVnode(Error * ec, struct Volume *vp, VnodeType type);
  extern Vnode *VAllocVnode_r(Error * ec, struct Volume *vp, VnodeType type);
  /*extern VFreeVnode();*/
  extern Vnode *VGetFreeVnode_r(struct VnodeClassInfo *vcp);
--- 211,220 ----
  			  int locktype);
  extern void VPutVnode(Error * ec, register Vnode * vnp);
  extern void VPutVnode_r(Error * ec, register Vnode * vnp);
! extern int VVnodeWriteToRead(Error * ec, register Vnode * vnp);
! extern int VVnodeWriteToRead_r(Error * ec, register Vnode * vnp);
  extern Vnode *VAllocVnode(Error * ec, struct Volume *vp, VnodeType type);
  extern Vnode *VAllocVnode_r(Error * ec, struct Volume *vp, VnodeType type);
  /*extern VFreeVnode();*/
  extern Vnode *VGetFreeVnode_r(struct VnodeClassInfo *vcp);
+ extern void VInitVnHashByVolume(void);
Index: openafs/src/vol/vol-salvage.c
diff -c openafs/src/vol/vol-salvage.c:1.47 openafs/src/vol/vol-salvage.c:1.51
*** openafs/src/vol/vol-salvage.c:1.47	Sat Mar 19 15:42:04 2005
--- openafs/src/vol/vol-salvage.c	Tue Apr  4 17:32:22 2006
***************
*** 83,99 ****
  */
  
  
- #define SalvageVersion "2.4"
- 
- /* Main program file. Define globals. */
- #define MAIN 1
- 
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vol-salvage.c,v 1.47 2005/03/19 20:42:04 shadow Exp $");
  
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
--- 83,101 ----
  */
  
  
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vol-salvage.c,v 1.51 2006/04/04 21:32:22 rees Exp $");
  
+ #ifndef AFS_NT40_ENV
+ #include &lt;sys/param.h&gt;
+ #include &lt;sys/file.h&gt;
+ #ifndef ITIMER_REAL
+ #include &lt;sys/time.h&gt;
+ #endif /* ITIMER_REAL */
+ #endif
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
***************
*** 104,115 ****
  #ifdef AFS_NT40_ENV
  #include &lt;io.h&gt;
  #include &lt;WINNT/afsevent.h&gt;
- #else
- #include &lt;sys/param.h&gt;
- #include &lt;sys/file.h&gt;
- #ifndef ITIMER_REAL
- #include &lt;sys/time.h&gt;
- #endif /* ITIMER_REAL */
  #endif
  #if	defined(AFS_AIX_ENV) || defined(AFS_SUN4_ENV)
  #define WCOREDUMP(x)	(x &amp; 0200)
--- 106,111 ----
***************
*** 186,195 ****
--- 182,194 ----
  #include "vnode.h"
  #include "volume.h"
  #include "partition.h"
+ #include "daemon_com.h"
  #include "fssync.h"
+ #include "salvsync.h"
  #include "viceinode.h"
  #include "salvage.h"
  #include "volinodes.h"		/* header magic number, etc. stuff */
+ #include "vol-salvage.h"
  #ifdef AFS_NT40_ENV
  #include &lt;pthread.h&gt;
  #endif
***************
*** 221,230 ****
  #endif
  static char *TimeStamp(time_t clock, int precision);
  
- #define ORPH_IGNORE 0
- #define ORPH_REMOVE 1
- #define ORPH_ATTACH 2
- 
  
  int debug;			/* -d flag */
  int Testing = 0;		/* -n flag */
--- 220,225 ----
***************
*** 251,257 ****
  int ForceSalvage;		/* If salvage should occur despite the DONT_SALVAGE flag
  				 * in the volume header */
  
! static FILE *logFile = 0;	/* one of {/usr/afs/logs,/vice/file}/SalvageLog */
  
  #define ROOTINODE	2	/* Root inode of a 4.2 Unix file system
  				 * partition */
--- 246,252 ----
  int ForceSalvage;		/* If salvage should occur despite the DONT_SALVAGE flag
  				 * in the volume header */
  
! FILE *logFile = 0;	/* one of {/usr/afs/logs,/vice/file}/SalvageLog */
  
  #define ROOTINODE	2	/* Root inode of a 4.2 Unix file system
  				 * partition */
***************
*** 279,479 ****
  
  VolumeDiskData VolInfo;		/* A copy of the last good or salvaged volume header dealt with */
  
- struct InodeSummary {		/* Inode summary file--an entry for each
- 				 * volume in the inode file for a partition */
-     VolId volumeId;		/* Volume id */
-     VolId RWvolumeId;		/* RW volume associated */
-     int index;			/* index into inode file (0, 1, 2 ...) */
-     int nInodes;		/* Number of inodes for this volume */
-     int nSpecialInodes;		/* Number of special inodes, i.e.  volume
- 				 * header, index, etc.  These are all
- 				 * marked (viceinode.h) and will all be sorted
- 				 * to the beginning of the information for
- 				 * this volume.  Read-only volumes should
- 				 * ONLY have special inodes (all the other
- 				 * inodes look as if they belong to the
- 				 * original RW volume). */
-     Unique maxUniquifier;	/* The maximum uniquifier found in all the inodes.
- 				 * This is only useful for RW volumes and is used
- 				 * to compute a new volume uniquifier in the event
- 				 * that the header needs to be recreated. The inode
- 				 * uniquifier may be a truncated version of vnode
- 				 * uniquifier (AFS_3DISPARES). The real maxUniquifer
- 				 * is from the vnodes and later calcuated from it */
-     struct VolumeSummary *volSummary;
-     /* Either a pointer to the original volume
-      * header summary, or constructed summary
-      * information */
- } *inodeSummary;
- #define readOnly(isp)	((isp)-&gt;volumeId != (isp)-&gt;RWvolumeId)
  int nVolumesInInodeFile;	/* Number of read-write volumes summarized */
  int inodeFd;			/* File descriptor for inode file */
  
  
! struct VolumeSummary {		/* Volume summary an entry for each
! 				 * volume in a volume directory.
! 				 * Assumption: one volume directory per
! 				 * partition */
!     char *fileName;		/* File name on the partition for the volume
! 				 * header */
!     struct VolumeHeader header;
!     /* volume number, rw volume number, inode
!      * numbers of each major component of
!      * the volume */
!     IHandle_t *volumeInfoHandle;
!     byte wouldNeedCallback;	/* set if the file server should issue
! 				 * call backs for all the files in this volume when
! 				 * the volume goes back on line */
! };
! 
! struct VnodeInfo {
!     IHandle_t *handle;		/* Inode containing this index */
!     int nVnodes;		/* Total number of vnodes in index */
!     int nAllocatedVnodes;	/* Total number actually used */
!     int volumeBlockCount;	/* Total number of blocks used by volume */
!     Inode *inodes;		/* Directory only */
!     struct VnodeEssence {
! 	short count;		/* Number of references to vnode; MUST BE SIGNED */
! 	unsigned claimed:1;	/* Set when a parent directory containing an entry
! 				 * referencing this vnode is found.  The claim
! 				 * is that the parent in "parent" can point to
! 				 * this vnode, and no other */
! 	unsigned changed:1;	/* Set if any parameters (other than the count)
! 				 * in the vnode change.   It is determined if the
! 				 * link count has changed by noting whether it is
! 				 * 0 after scanning all directories */
! 	unsigned salvaged:1;	/* Set if this directory vnode has already been salvaged. */
! 	unsigned todelete:1;	/* Set if this vnode is to be deleted (should not be claimed) */
! 	afs_fsize_t blockCount;
! 	/* Number of blocks (1K) used by this vnode,
! 	 * approximately */
! 	VnodeId parent;		/* parent in vnode */
! 	Unique unique;		/* Must match entry! */
! 	char *name;		/* Name of directory entry */
! 	int modeBits;		/* File mode bits */
! 	Inode InodeNumber;	/* file's inode */
! 	int type;		/* File type */
! 	int author;		/* File author */
! 	int owner;		/* File owner */
! 	int group;		/* File group */
!     } *vnodes;
! } vnodeInfo[nVNODECLASSES];
! 
! struct DirSummary {
!     struct DirHandle dirHandle;
!     VnodeId vnodeNumber;
!     Unique unique;
!     unsigned haveDot, haveDotDot;
!     VolumeId rwVid;
!     int copied;			/* If the copy-on-write stuff has been applied */
!     VnodeId parent;
!     char *name;
!     char *vname;
!     IHandle_t *ds_linkH;
! };
  
  
  struct VolumeSummary *volumeSummaryp;	/* Holds all the volumes in a part */
  int nVolumes;			/* Number of volumes (read-write and read-only)
  				 * in volume summary */
  
! #ifdef AFS_NT40_ENV
! /* For NT, we can fork the per partition salvagers to gain the required
!  * safety against Aborts. But there's too many complex data structures at
!  * the per volume salvager layer to easilty copy the data across.
!  * childJobNumber is resset from -1 to the job number if this is a
!  * per partition child of the main salvager. This information is passed
!  * out-of-band in the extra data area setup for the now unused parent/child
!  * data transfer.
!  */
! #define SALVAGER_MAGIC 0x00BBaaDD
! #define NOT_CHILD -1		/* job numbers start at 0 */
! /* If new options need to be passed to child, add them here. */
! typedef struct {
!     int cj_magic;
!     int cj_number;
!     char cj_part[32];
! } childJob_t;
! 
! /* Child job this process is running. */
! childJob_t myjob = { SALVAGER_MAGIC, NOT_CHILD, "" };
! 
! int nt_SalvagePartition(char *partName, int jobn);
! int nt_SetupPartitionSalvage(void *datap, int len);
! 
! typedef struct {
!     struct InodeSummary *svgp_inodeSummaryp;
!     int svgp_count;
! } SVGParms_t;
! #define canfork 0
! #else
! #define canfork 1
! #endif
  
  
  
  /* Forward declarations */
  /*@printflike@*/ void Log(const char *format, ...);
  /*@printflike@*/ void Abort(const char *format, ...);
- void Exit(int code);
- int Fork(void);
- int Wait(char *prog);
- char *ToString(char *s);
- void AskOffline(VolumeId volumeId);
- void AskOnline(VolumeId volumeId, char *partition);
- void CheckLogFile(void);
- #ifndef AFS_NT40_ENV
- void TimeStampLogFile(void);
- #endif
- void ClearROInUseBit(struct VolumeSummary *summary);
- void CopyAndSalvage(register struct DirSummary *dir);
- int CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume);
- void CopyOnWrite(register struct DirSummary *dir);
- void CountVolumeInodes(register struct ViceInodeInfo *ip, int maxInodes,
- 		       register struct InodeSummary *summary);
- void DeleteExtraVolumeHeaderFile(register struct VolumeSummary *vsp);
- void DistilVnodeEssence(VolumeId vid, VnodeClass class, Inode ino,
- 			Unique * maxu);
- int GetInodeSummary(char *path, VolumeId singleVolumeNumber);
- void GetVolumeSummary(VolumeId singleVolumeNumber);
- void JudgeEntry(struct DirSummary *dir, char *name, VnodeId vnodeNumber,
- 		Unique unique);
- void MaybeZapVolume(register struct InodeSummary *isp, char *message,
- 		    int deleteMe, int check);
- void ObtainSalvageLock(void);
- void PrintInodeList(void);
- void PrintInodeSummary(void);
- void PrintVolumeSummary(void);
- int QuickCheck(register struct InodeSummary *isp, int nVols);
- void RemoveTheForce(char *path);
- void SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo,
- 		IHandle_t * alinkH, int i, struct DirSummary *rootdir,
- 		int *rootdirfound);
- void SalvageFileSysParallel(struct DiskPartition *partP);
- void SalvageFileSys(struct DiskPartition *partP, VolumeId singleVolumeNumber);
- void SalvageFileSys1(struct DiskPartition *partP,
- 		     VolumeId singleVolumeNumber);
- int SalvageHeader(register struct stuff *sp, struct InodeSummary *isp,
- 		  int check, int *deleteMe);
- int SalvageIndex(Inode ino, VnodeClass class, int RW,
- 		 register struct ViceInodeInfo *ip, int nInodes,
- 		 struct VolumeSummary *volSummary, int check);
- int SalvageVnodes(register struct InodeSummary *rwIsp,
- 		  register struct InodeSummary *thisIsp,
- 		  register struct ViceInodeInfo *inodes, int check);
- int SalvageVolume(register struct InodeSummary *rwIsp, IHandle_t * alinkH);
- void DoSalvageVolumeGroup(register struct InodeSummary *isp, int nVols);
- #ifdef AFS_NT40_ENV
- void SalvageVolumeGroup(register struct InodeSummary *isp, int nVols);
- #else
- #define SalvageVolumeGroup DoSalvageVolumeGroup
- #endif
- int SalvageVolumeHeaderFile(register struct InodeSummary *isp,
- 			    register struct ViceInodeInfo *inodes, int RW,
- 			    int check, int *deleteMe);
- void showlog(void);
- int UseTheForceLuke(char *path);
- 
  static int IsVnodeOrphaned(VnodeId vnode);
  
  /* Uniquifier stored in the Inode */
--- 274,297 ----
  
  VolumeDiskData VolInfo;		/* A copy of the last good or salvaged volume header dealt with */
  
  int nVolumesInInodeFile;	/* Number of read-write volumes summarized */
  int inodeFd;			/* File descriptor for inode file */
  
  
! struct VnodeInfo vnodeInfo[nVNODECLASSES];
  
  
  struct VolumeSummary *volumeSummaryp;	/* Holds all the volumes in a part */
  int nVolumes;			/* Number of volumes (read-write and read-only)
  				 * in volume summary */
  
! char *tmpdir = NULL;
  
  
  
  /* Forward declarations */
  /*@printflike@*/ void Log(const char *format, ...);
  /*@printflike@*/ void Abort(const char *format, ...);
  static int IsVnodeOrphaned(VnodeId vnode);
  
  /* Uniquifier stored in the Inode */
***************
*** 500,706 ****
  }
  
  
- char *tmpdir = 0;
- static int
- handleit(struct cmd_syndesc *as)
- {
-     register struct cmd_item *ti;
-     char pname[100], *temp;
-     afs_int32 seenpart = 0, seenvol = 0, vid = 0, seenany = 0;
-     struct DiskPartition *partP;
- 
- #ifdef AFS_SGI_VNODE_GLUE
-     if (afs_init_kernel_config(-1) &lt; 0) {
- 	printf
- 	    ("Can't determine NUMA configuration, not starting salvager.\n");
- 	exit(1);
-     }
- #endif
- 
- #ifdef FAST_RESTART
-     {
- 	afs_int32 i;
- 	for (i = 0; i &lt; CMD_MAXPARMS; i++) {
- 	    if (as-&gt;parms[i].items) {
- 		seenany = 1;
- 		break;
- 	    }
- 	}
-     }
-     if (!seenany) {
- 	char *msg =
- 	    "Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!";
- 
- 	if (useSyslog)
- 	    Log(msg);
- 	else
- 	    printf("%s\n", msg);
- 
- 	Exit(0);
-     }
- #endif /* FAST_RESTART */
-     if ((ti = as-&gt;parms[0].items)) {	/* -partition */
- 	seenpart = 1;
- 	strncpy(pname, ti-&gt;data, 100);
-     }
-     if ((ti = as-&gt;parms[1].items)) {	/* -volumeid */
- 	if (!seenpart) {
- 	    printf
- 		("You must also specify '-partition' option with the '-volumeid' option\n");
- 	    exit(-1);
- 	}
- 	seenvol = 1;
- 	vid = atoi(ti-&gt;data);
-     }
-     if (as-&gt;parms[2].items)	/* -debug */
- 	debug = 1;
-     if (as-&gt;parms[3].items)	/* -nowrite */
- 	Testing = 1;
-     if (as-&gt;parms[4].items)	/* -inodes */
- 	ListInodeOption = 1;
-     if (as-&gt;parms[5].items)	/* -force */
- 	ForceSalvage = 1;
-     if (as-&gt;parms[6].items)	/* -oktozap */
- 	OKToZap = 1;
-     if (as-&gt;parms[7].items)	/* -rootinodes */
- 	ShowRootFiles = 1;
-     if (as-&gt;parms[8].items)	/* -RebuildDirs */
- 	RebuildDirs = 1;
-     if (as-&gt;parms[9].items)	/* -ForceReads */
- 	forceR = 1;
-     if ((ti = as-&gt;parms[10].items)) {	/* -Parallel # */
- 	temp = ti-&gt;data;
- 	if (strncmp(temp, "all", 3) == 0) {
- 	    PartsPerDisk = 1;
- 	    temp += 3;
- 	}
- 	if (strlen(temp) != 0) {
- 	    Parallel = atoi(temp);
- 	    if (Parallel &lt; 1)
- 		Parallel = 1;
- 	    if (Parallel &gt; MAXPARALLEL) {
- 		printf("Setting parallel salvages to maximum of %d \n",
- 		       MAXPARALLEL);
- 		Parallel = MAXPARALLEL;
- 	    }
- 	}
-     }
-     if ((ti = as-&gt;parms[11].items)) {	/* -tmpdir */
- 	DIR *dirp;
- 
- 	tmpdir = ti-&gt;data;
- 	dirp = opendir(tmpdir);
- 	if (!dirp) {
- 	    printf
- 		("Can't open temporary placeholder dir %s; using current partition \n",
- 		 tmpdir);
- 	    tmpdir = NULL;
- 	} else
- 	    closedir(dirp);
-     }
-     if ((ti = as-&gt;parms[12].items))	/* -showlog */
- 	ShowLog = 1;
-     if ((ti = as-&gt;parms[13].items)) {	/* -log */
- 	Testing = 1;
- 	ShowSuid = 1;
- 	Showmode = 1;
-     }
-     if ((ti = as-&gt;parms[14].items)) {	/* -showmounts */
- 	Testing = 1;
- 	Showmode = 1;
- 	ShowMounts = 1;
-     }
-     if ((ti = as-&gt;parms[15].items)) {	/* -orphans */
- 	if (Testing)
- 	    orphans = ORPH_IGNORE;
- 	else if (strcmp(ti-&gt;data, "remove") == 0
- 		 || strcmp(ti-&gt;data, "r") == 0)
- 	    orphans = ORPH_REMOVE;
- 	else if (strcmp(ti-&gt;data, "attach") == 0
- 		 || strcmp(ti-&gt;data, "a") == 0)
- 	    orphans = ORPH_ATTACH;
-     }
- #ifndef AFS_NT40_ENV		/* ignore options on NT */
-     if ((ti = as-&gt;parms[16].items)) {	/* -syslog */
- 	useSyslog = 1;
- 	ShowLog = 0;
-     }
-     if ((ti = as-&gt;parms[17].items)) {	/* -syslogfacility */
- 	useSyslogFacility = atoi(ti-&gt;data);
-     }
- 
-     if ((ti = as-&gt;parms[18].items)) {	/* -datelogs */
- 	TimeStampLogFile();
-     }
- #endif
- 
- #ifdef FAST_RESTART
-     if (ti = as-&gt;parms[19].items) {	/* -DontSalvage */
- 	char *msg =
- 	    "Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!";
- 
- 	if (useSyslog)
- 	    Log(msg);
- 	else
- 	    printf("%s\n", msg);
- 	Exit(0);
-     }
- #endif /* FAST_RESTART */
- 
-     /* Note:  if seemvol we initialize this as a standard volume utility:  this has the
-      * implication that the file server may be running; negotations have to be made with
-      * the file server in this case to take the read write volume and associated read-only
-      * volumes off line before salvaging */
- #ifdef AFS_NT40_ENV
-     if (seenvol) {
- 	if (afs_winsockInit() &lt; 0) {
- 	    ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0,
- 				AFSDIR_SALVAGER_FILE, 0);
- 	    Log("Failed to initailize winsock, exiting.\n");
- 	    Exit(1);
- 	}
-     }
- #endif
-     VInitVolumePackage(seenvol ? volumeUtility : salvager, 5, 5,
- 		       DONT_CONNECT_FS, 0);
-     DInit(10);
- #ifdef AFS_NT40_ENV
-     if (myjob.cj_number != NOT_CHILD) {
- 	if (!seenpart) {
- 	    seenpart = 1;
- 	    (void)strcpy(pname, myjob.cj_part);
- 	}
-     }
- #endif
-     if (seenpart == 0) {
- 	for (partP = DiskPartitionList; partP; partP = partP-&gt;next) {
- 	    SalvageFileSysParallel(partP);
- 	}
- 	SalvageFileSysParallel(0);
-     } else {
- 	partP = VGetPartition(pname, 0);
- 	if (!partP) {
- 	    Log("salvage: Unknown or unmounted partition %s; salvage aborted\n", pname);
- 	    Exit(1);
- 	}
- 	if (!seenvol)
- 	    SalvageFileSys(partP, 0);
- 	else {
- 	    /* Salvage individual volume */
- 	    if (vid &lt;= 0) {
- 		Log("salvage: invalid volume id specified; salvage aborted\n");
- 		Exit(1);
- 	    }
- 	    SalvageFileSys(partP, vid);
- 	}
-     }
-     return (0);
- }
- 
- 
- #ifndef AFS_NT40_ENV
- #include "AFS_component_version_number.c"
- #endif
  #define MAX_ARGS 128
  #ifdef AFS_NT40_ENV
  char *save_args[MAX_ARGS];
--- 318,323 ----
***************
*** 708,850 ****
  pthread_t main_thread;
  #endif
  
- int
- main(int argc, char **argv)
- {
-     struct cmd_syndesc *ts;
-     int err = 0;
-     char commandLine[150];
- 
-     int i;
-     extern char cml_version_number[];
- 
- #ifdef	AFS_AIX32_ENV
-     /*
-      * The following signal action for AIX is necessary so that in case of a 
-      * crash (i.e. core is generated) we can include the user's data section 
-      * in the core dump. Unfortunately, by default, only a partial core is
-      * generated which, in many cases, isn't too useful.
-      */
-     struct sigaction nsa;
- 
-     sigemptyset(&amp;nsa.sa_mask);
-     nsa.sa_handler = SIG_DFL;
-     nsa.sa_flags = SA_FULLDUMP;
-     sigaction(SIGABRT, &amp;nsa, NULL);
-     sigaction(SIGSEGV, &amp;nsa, NULL);
- #endif
- 
-     /* Initialize directory paths */
-     if (!(initAFSDirPath() &amp; AFSDIR_SERVER_PATHS_OK)) {
- #ifdef AFS_NT40_ENV
- 	ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
- #endif
- 	fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
- 		argv[0]);
- 	exit(2);
-     }
- #ifdef AFS_NT40_ENV
-     main_thread = pthread_self();
-     if (spawnDatap &amp;&amp; spawnDataLen) {
- 	/* This is a child per partition salvager. Don't setup log or
- 	 * try to lock the salvager lock.
- 	 */
- 	if (nt_SetupPartitionSalvage(spawnDatap, spawnDataLen) &lt; 0)
- 	    exit(3);
-     } else {
- #endif
- 	for (commandLine[0] = '\0', i = 0; i &lt; argc; i++) {
- 	    if (i &gt; 0)
- 		strcat(commandLine, " ");
- 	    strcat(commandLine, argv[i]);
- 	}
- 
- 	/* All entries to the log will be appended.  Useful if there are
- 	 * multiple salvagers appending to the log.
- 	 */
- 
- 	CheckLogFile();
- #ifndef AFS_NT40_ENV
- #ifdef AFS_LINUX20_ENV
- 	fcntl(fileno(logFile), F_SETFL, O_APPEND);	/* Isn't this redundant? */
- #else
- 	fcntl(fileno(logFile), F_SETFL, FAPPEND);	/* Isn't this redundant? */
- #endif
- #endif
- 	setlinebuf(logFile);
- 
- #ifndef AFS_NT40_ENV
- 	if (geteuid() != 0) {
- 	    printf("Salvager must be run as root.\n");
- 	    fflush(stdout);
- 	    Exit(0);
- 	}
- #endif
- 
- 	/* bad for normal help flag processing, but can do nada */
- 
- 	fprintf(logFile, "%s\n", cml_version_number);
- 	Log("STARTING AFS SALVAGER %s (%s)\n", SalvageVersion, commandLine);
- 
- 	/* Get and hold a lock for the duration of the salvage to make sure
- 	 * that no other salvage runs at the same time.  The routine
- 	 * VInitVolumePackage (called below) makes sure that a file server or
- 	 * other volume utilities don't interfere with the salvage.
- 	 */
- 	ObtainSalvageLock();
- #ifdef AFS_NT40_ENV
-     }
- #endif
- 
-     ts = cmd_CreateSyntax("initcmd", handleit, 0, "initialize the program");
-     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
- 		"Name of partition to salvage");
-     cmd_AddParm(ts, "-volumeid", CMD_SINGLE, CMD_OPTIONAL,
- 		"Volume Id to salvage");
-     cmd_AddParm(ts, "-debug", CMD_FLAG, CMD_OPTIONAL,
- 		"Run in Debugging mode");
-     cmd_AddParm(ts, "-nowrite", CMD_FLAG, CMD_OPTIONAL,
- 		"Run readonly/test mode");
-     cmd_AddParm(ts, "-inodes", CMD_FLAG, CMD_OPTIONAL,
- 		"Just list affected afs inodes - debugging flag");
-     cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "Force full salvaging");
-     cmd_AddParm(ts, "-oktozap", CMD_FLAG, CMD_OPTIONAL,
- 		"Give permission to destroy bogus inodes/volumes - debugging flag");
-     cmd_AddParm(ts, "-rootinodes", CMD_FLAG, CMD_OPTIONAL,
- 		"Show inodes owned by root - debugging flag");
-     cmd_AddParm(ts, "-salvagedirs", CMD_FLAG, CMD_OPTIONAL,
- 		"Force rebuild/salvage of all directories");
-     cmd_AddParm(ts, "-blockreads", CMD_FLAG, CMD_OPTIONAL,
- 		"Read smaller blocks to handle IO/bad blocks");
-     cmd_AddParm(ts, "-parallel", CMD_SINGLE, CMD_OPTIONAL,
- 		"# of max parallel partition salvaging");
-     cmd_AddParm(ts, "-tmpdir", CMD_SINGLE, CMD_OPTIONAL,
- 		"Name of dir to place tmp files ");
-     cmd_AddParm(ts, "-showlog", CMD_FLAG, CMD_OPTIONAL,
- 		"Show log file upon completion");
-     cmd_AddParm(ts, "-showsuid", CMD_FLAG, CMD_OPTIONAL,
- 		"Report on suid/sgid files");
-     cmd_AddParm(ts, "-showmounts", CMD_FLAG, CMD_OPTIONAL,
- 		"Report on mountpoints");
-     cmd_AddParm(ts, "-orphans", CMD_SINGLE, CMD_OPTIONAL,
- 		"ignore | remove | attach");
- 
-     /* note - syslog isn't avail on NT, but if we make it conditional, have
-      * to deal with screwy offsets for cmd params */
-     cmd_AddParm(ts, "-syslog", CMD_FLAG, CMD_OPTIONAL,
- 		"Write salvage log to syslogs");
-     cmd_AddParm(ts, "-syslogfacility", CMD_SINGLE, CMD_OPTIONAL,
- 		"Syslog facility number to use");
-     cmd_AddParm(ts, "-datelogs", CMD_FLAG, CMD_OPTIONAL,
- 		"Include timestamp in logfile filename");
- 
- #ifdef FAST_RESTART
-     cmd_AddParm(ts, "-DontSalvage", CMD_FLAG, CMD_OPTIONAL,
- 		"Don't salvage. This my be set in BosConfig to let the fileserver restart immediately after a crash. Bad volumes will be taken offline");
- #endif /* FAST_RESTART */
-     err = cmd_Dispatch(argc, argv);
-     Exit(err);
- }
  
  /* Get the salvage lock if not already held. Hold until process exits. */
  void
--- 325,330 ----
***************
*** 1249,1255 ****
  	ForceSalvage = UseTheForceLuke(fileSysPath);
  
      if (singleVolumeNumber) {
! 	if (!VConnectFS()) {
  	    Abort("Couldn't connect to file server\n");
  	}
  	AskOffline(singleVolumeNumber);
--- 729,736 ----
  	ForceSalvage = UseTheForceLuke(fileSysPath);
  
      if (singleVolumeNumber) {
! 	/* salvageserver already setup fssync conn for us */
! 	if ((programType != salvageServer) &amp;&amp; !VConnectFS()) {
  	    Abort("Couldn't connect to file server\n");
  	}
  	AskOffline(singleVolumeNumber);
***************
*** 1520,1526 ****
  }
  
  int
! OnlyOneVolume(struct ViceInodeInfo *inodeinfo, VolumeId singleVolumeNumber, void *rock)
  {
      if (inodeinfo-&gt;u.vnode.vnodeNumber == INODESPECIAL)
  	return (inodeinfo-&gt;u.special.parentId == singleVolumeNumber);
--- 1001,1007 ----
  }
  
  int
! OnlyOneVolume(struct ViceInodeInfo *inodeinfo, int singleVolumeNumber, void *rock)
  {
      if (inodeinfo-&gt;u.vnode.vnodeNumber == INODESPECIAL)
  	return (inodeinfo-&gt;u.special.parentId == singleVolumeNumber);
***************
*** 2554,2560 ****
  		     * if no such match, take the first determined by our sort
  		     * order */
  		    register struct ViceInodeInfo *lip = ip;
! 		    register lnInodes = nInodes;
  		    while (lnInodes
  			   &amp;&amp; lip-&gt;u.vnode.vnodeNumber == vnodeNumber) {
  			if (VNDISK_GET_INO(vnode) == lip-&gt;inodeNumber) {
--- 2035,2041 ----
  		     * if no such match, take the first determined by our sort
  		     * order */
  		    register struct ViceInodeInfo *lip = ip;
! 		    register int lnInodes = nInodes;
  		    while (lnInodes
  			   &amp;&amp; lip-&gt;u.vnode.vnodeNumber == vnodeNumber) {
  			if (VNDISK_GET_INO(vnode) == lip-&gt;inodeNumber) {
***************
*** 2684,2694 ****
  			}
  			if (VNDISK_GET_INO(vnode)) {
  			    if (!Showmode) {
! 				Log("Vnode %d (unique %u): corresponding inode %s is missing; vnode deleted, vnode mod time=%s", vnodeNumber, vnode-&gt;uniquifier, PrintInode(NULL, VNDISK_GET_INO(vnode)), ctime((time_t *) &amp; (vnode-&gt;serverModifyTime)));
  			    }
  			} else {
! 			    if (!Showmode)
! 				Log("Vnode %d (unique %u): bad directory vnode (no inode number listed); vnode deleted, vnode mod time=%s", vnodeNumber, vnode-&gt;uniquifier, ctime((time_t *) &amp; (vnode-&gt;serverModifyTime)));
  			}
  			memset(vnode, 0, vcp-&gt;diskSize);
  			vnodeChanged = 1;
--- 2165,2178 ----
  			}
  			if (VNDISK_GET_INO(vnode)) {
  			    if (!Showmode) {
! 				time_t serverModifyTime = vnode-&gt;serverModifyTime;
! 				Log("Vnode %d (unique %u): corresponding inode %s is missing; vnode deleted, vnode mod time=%s", vnodeNumber, vnode-&gt;uniquifier, PrintInode(NULL, VNDISK_GET_INO(vnode)), ctime(&amp;serverModifyTime));
  			    }
  			} else {
! 			    if (!Showmode) {
! 				time_t serverModifyTime = vnode-&gt;serverModifyTime;
! 				Log("Vnode %d (unique %u): bad directory vnode (no inode number listed); vnode deleted, vnode mod time=%s", vnodeNumber, vnode-&gt;uniquifier, ctime(&amp;serverModifyTime));
! 			    }
  			}
  			memset(vnode, 0, vcp-&gt;diskSize);
  			vnodeChanged = 1;
***************
*** 3628,3635 ****
  void
  AskOffline(VolumeId volumeId)
  {
!     if (FSYNC_askfs(volumeId, NULL, FSYNC_OFF, FSYNC_SALVAGE) == FSYNC_DENIED) {
! 	Log("AskOffline:  file server denied offline request; a general salvage is required.\n");
  	Abort("Salvage aborted\n");
      }
  }
--- 3112,3149 ----
  void
  AskOffline(VolumeId volumeId)
  {
!     afs_int32 code, i;
! 
!     for (i = 0; i &lt; 3; i++) {
! 	code = FSYNC_VolOp(volumeId, NULL, FSYNC_VOL_OFF, FSYNC_SALVAGE, NULL);
! 
! 	if (code == SYNC_OK) {
! 	    break;
! 	} else if (code == SYNC_DENIED) {
! #ifdef DEMAND_ATTACH_ENABLE
! 	    Log("AskOffline:  file server denied offline request; a general salvage may be required.\n");
! #else
! 	    Log("AskOffline:  file server denied offline request; a general salvage is required.\n");
! #endif
! 	    Abort("Salvage aborted\n");
! 	} else if (code == SYNC_BAD_COMMAND) {
! 	    Log("AskOffline:  fssync protocol mismatch (bad command word '%d'); salvage aborting.\n",
! 		FSYNC_VOL_OFF);
! #ifdef DEMAND_ATTACH_ENABLE
! 	    Log("AskOffline:  please make sure fileserver, volserver, salvageserver and salvager binaries are same version.\n");
! #else
! 	    Log("AskOffline:  please make sure fileserver, volserver and salvager binaries are same version.\n");
! #endif
! 	    Abort("Salvage aborted\n");
! 	} else if (i &lt; 2) {
! 	    /* try it again */
! 	    Log("AskOffline:  request for fileserver to take volume offline failed; trying again...\n");
! 	    FSYNC_clientFinis();
! 	    FSYNC_clientInit();
! 	}
!     }
!     if (code != SYNC_OK) {
! 	Log("AskOffline:  request for fileserver to take volume offline failed; salvage aborting.\n");
  	Abort("Salvage aborted\n");
      }
  }
***************
*** 3637,3644 ****
  void
  AskOnline(VolumeId volumeId, char *partition)
  {
!     if (FSYNC_askfs(volumeId, partition, FSYNC_ON, 0) == FSYNC_DENIED) {
! 	Log("AskOnline:  file server denied online request to volume %u partition %s\n", volumeId, partition);
      }
  }
  
--- 3151,3180 ----
  void
  AskOnline(VolumeId volumeId, char *partition)
  {
!     afs_int32 code, i;
! 
!     for (i = 0; i &lt; 3; i++) {
! 	code = FSYNC_VolOp(volumeId, partition, FSYNC_VOL_ON, FSYNC_WHATEVER, NULL);
! 
! 	if (code == SYNC_OK) {
! 	    break;
! 	} else if (code == SYNC_DENIED) {
! 	    Log("AskOnline:  file server denied online request to volume %u partition %s; trying again...\n", volumeId, partition);
! 	} else if (code == SYNC_BAD_COMMAND) {
! 	    Log("AskOnline:  fssync protocol mismatch (bad command word '%d')\n",
! 		FSYNC_VOL_ON);
! #ifdef DEMAND_ATTACH_ENABLE
! 	    Log("AskOnline:  please make sure fileserver, volserver, salvageserver and salvager binaries are same version.\n");
! #else
! 	    Log("AskOnline:  please make sure fileserver, volserver and salvager binaries are same version.\n");
! #endif
! 	    break;
! 	} else if (i &lt; 2) {
! 	    /* try it again */
! 	    Log("AskOnline:  request for fileserver to take volume offline failed; trying again...\n");
! 	    FSYNC_clientFinis();
! 	    FSYNC_clientInit();
! 	}
      }
  }
  
***************
*** 3772,3778 ****
  }
  
  void
! CheckLogFile(void)
  {
      char oldSlvgLog[AFSDIR_PATH_MAX];
  
--- 3308,3314 ----
  }
  
  void
! CheckLogFile(char * log_path)
  {
      char oldSlvgLog[AFSDIR_PATH_MAX];
  
***************
*** 3783,3793 ****
      }
  #endif
  
!     strcpy(oldSlvgLog, AFSDIR_SERVER_SLVGLOG_FILEPATH);
      strcat(oldSlvgLog, ".old");
      if (!logFile) {
! 	renamefile(AFSDIR_SERVER_SLVGLOG_FILEPATH, oldSlvgLog);
! 	logFile = afs_fopen(AFSDIR_SERVER_SLVGLOG_FILEPATH, "a");
  
  	if (!logFile) {		/* still nothing, use stdout */
  	    logFile = stdout;
--- 3319,3329 ----
      }
  #endif
  
!     strcpy(oldSlvgLog, log_path);
      strcat(oldSlvgLog, ".old");
      if (!logFile) {
! 	renamefile(log_path, oldSlvgLog);
! 	logFile = afs_fopen(log_path, "a");
  
  	if (!logFile) {		/* still nothing, use stdout */
  	    logFile = stdout;
***************
*** 3801,3807 ****
  
  #ifndef AFS_NT40_ENV
  void
! TimeStampLogFile(void)
  {
      char stampSlvgLog[AFSDIR_PATH_MAX];
      struct tm *lt;
--- 3337,3343 ----
  
  #ifndef AFS_NT40_ENV
  void
! TimeStampLogFile(char * log_path)
  {
      char stampSlvgLog[AFSDIR_PATH_MAX];
      struct tm *lt;
***************
*** 3811,3823 ****
      lt = localtime(&amp;now);
      (void)afs_snprintf(stampSlvgLog, sizeof stampSlvgLog,
  		       "%s.%04d-%02d-%02d.%02d:%02d:%02d",
! 		       AFSDIR_SERVER_SLVGLOG_FILEPATH, lt-&gt;tm_year + 1900,
  		       lt-&gt;tm_mon + 1, lt-&gt;tm_mday, lt-&gt;tm_hour, lt-&gt;tm_min,
  		       lt-&gt;tm_sec);
  
      /* try to link the logfile to a timestamped filename */
      /* if it fails, oh well, nothing we can do */
!     link(AFSDIR_SERVER_SLVGLOG_FILEPATH, stampSlvgLog);
  }
  #endif
  
--- 3347,3359 ----
      lt = localtime(&amp;now);
      (void)afs_snprintf(stampSlvgLog, sizeof stampSlvgLog,
  		       "%s.%04d-%02d-%02d.%02d:%02d:%02d",
! 		       log_path, lt-&gt;tm_year + 1900,
  		       lt-&gt;tm_mon + 1, lt-&gt;tm_mday, lt-&gt;tm_hour, lt-&gt;tm_min,
  		       lt-&gt;tm_sec);
  
      /* try to link the logfile to a timestamped filename */
      /* if it fails, oh well, nothing we can do */
!     link(log_path, stampSlvgLog);
  }
  #endif
  
***************
*** 3937,3943 ****
   *
   * NOTE:
   *	The VRMIX fsck will not muck with the filesystem it is supposedly
!  *	fixing and create a "FORCESAVAGE" file (by design).  Instead, we
   *	muck directly with the root inode, which is within the normal
   *	domain of fsck.
   *	ListViceInodes() has a side effect of setting ForceSalvage if
--- 3473,3479 ----
   *
   * NOTE:
   *	The VRMIX fsck will not muck with the filesystem it is supposedly
!  *	fixing and create a "FORCESALVAGE" file (by design).  Instead, we
   *	muck directly with the root inode, which is within the normal
   *	domain of fsck.
   *	ListViceInodes() has a side effect of setting ForceSalvage if
Index: openafs/src/vol/vol-salvage.h
diff -c /dev/null openafs/src/vol/vol-salvage.h:1.1
*** /dev/null	Thu Apr 27 12:42:32 2006
--- openafs/src/vol/vol-salvage.h	Fri Mar 17 23:20:19 2006
***************
*** 0 ****
--- 1,282 ----
+ /*
+  * Copyright 2000, International Business Machines Corporation and others.
+  * All Rights Reserved.
+  * 
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+ 
+ /*
+  *      Module:		vol-salvage.h
+  */
+ 
+ #ifndef __vol_salvage_h_
+ #define __vol_salvage_h_
+ 
+ #define SalvageVersion "2.4"
+ 
+ #include "salvage.h"
+ #include "volinodes.h"
+ 
+ /* salvager data structures */
+ struct InodeSummary {		/* Inode summary file--an entry for each
+ 				 * volume in the inode file for a partition */
+     VolId volumeId;		/* Volume id */
+     VolId RWvolumeId;		/* RW volume associated */
+     int index;			/* index into inode file (0, 1, 2 ...) */
+     int nInodes;		/* Number of inodes for this volume */
+     int nSpecialInodes;		/* Number of special inodes, i.e.  volume
+ 				 * header, index, etc.  These are all
+ 				 * marked (viceinode.h) and will all be sorted
+ 				 * to the beginning of the information for
+ 				 * this volume.  Read-only volumes should
+ 				 * ONLY have special inodes (all the other
+ 				 * inodes look as if they belong to the
+ 				 * original RW volume). */
+     Unique maxUniquifier;	/* The maximum uniquifier found in all the inodes.
+ 				 * This is only useful for RW volumes and is used
+ 				 * to compute a new volume uniquifier in the event
+ 				 * that the header needs to be recreated. The inode
+ 				 * uniquifier may be a truncated version of vnode
+ 				 * uniquifier (AFS_3DISPARES). The real maxUniquifer
+ 				 * is from the vnodes and later calcuated from it */
+     struct VolumeSummary *volSummary;
+     /* Either a pointer to the original volume
+      * header summary, or constructed summary
+      * information */
+ } *inodeSummary;
+ #define readOnly(isp)	((isp)-&gt;volumeId != (isp)-&gt;RWvolumeId)
+ 
+ struct VolumeSummary {		/* Volume summary an entry for each
+ 				 * volume in a volume directory.
+ 				 * Assumption: one volume directory per
+ 				 * partition */
+     char *fileName;		/* File name on the partition for the volume
+ 				 * header */
+     struct VolumeHeader header;
+     /* volume number, rw volume number, inode
+      * numbers of each major component of
+      * the volume */
+     IHandle_t *volumeInfoHandle;
+     byte wouldNeedCallback;	/* set if the file server should issue
+ 				 * call backs for all the files in this volume when
+ 				 * the volume goes back on line */
+ };
+ 
+ struct VnodeInfo {
+     IHandle_t *handle;		/* Inode containing this index */
+     int nVnodes;		/* Total number of vnodes in index */
+     int nAllocatedVnodes;	/* Total number actually used */
+     int volumeBlockCount;	/* Total number of blocks used by volume */
+     Inode *inodes;		/* Directory only */
+     struct VnodeEssence {
+ 	short count;		/* Number of references to vnode; MUST BE SIGNED */
+ 	unsigned claimed:1;	/* Set when a parent directory containing an entry
+ 				 * referencing this vnode is found.  The claim
+ 				 * is that the parent in "parent" can point to
+ 				 * this vnode, and no other */
+ 	unsigned changed:1;	/* Set if any parameters (other than the count)
+ 				 * in the vnode change.   It is determined if the
+ 				 * link count has changed by noting whether it is
+ 				 * 0 after scanning all directories */
+ 	unsigned salvaged:1;	/* Set if this directory vnode has already been salvaged. */
+ 	unsigned todelete:1;	/* Set if this vnode is to be deleted (should not be claimed) */
+ 	afs_fsize_t blockCount;
+ 	/* Number of blocks (1K) used by this vnode,
+ 	 * approximately */
+ 	VnodeId parent;		/* parent in vnode */
+ 	Unique unique;		/* Must match entry! */
+ 	char *name;		/* Name of directory entry */
+ 	int modeBits;		/* File mode bits */
+ 	Inode InodeNumber;	/* file's inode */
+ 	int type;		/* File type */
+ 	int author;		/* File author */
+ 	int owner;		/* File owner */
+ 	int group;		/* File group */
+     } *vnodes;
+ };
+ 
+ struct DirSummary {
+     struct DirHandle dirHandle;
+     VnodeId vnodeNumber;
+     Unique unique;
+     unsigned haveDot, haveDotDot;
+     VolumeId rwVid;
+     int copied;			/* If the copy-on-write stuff has been applied */
+     VnodeId parent;
+     char *name;
+     char *vname;
+     IHandle_t *ds_linkH;
+ };
+ 
+ #define ORPH_IGNORE 0
+ #define ORPH_REMOVE 1
+ #define ORPH_ATTACH 2
+ 
+ 
+ /* command line options */
+ extern int debug;			/* -d flag */
+ extern int Testing;		        /* -n flag */
+ extern int ListInodeOption;		/* -i flag */
+ extern int ShowRootFiles;		/* -r flag */
+ extern int RebuildDirs;		        /* -sal flag */
+ extern int Parallel;		        /* -para X flag */
+ extern int PartsPerDisk;		/* Salvage up to 8 partitions on same disk sequentially */
+ extern int forceR;			/* -b flag */
+ extern int ShowLog;		        /* -showlog flag */
+ extern int ShowSuid;		        /* -showsuid flag */
+ extern int ShowMounts;		        /* -showmounts flag */
+ extern int orphans;	                /* -orphans option */
+ extern int Showmode;
+ 
+ #ifndef AFS_NT40_ENV
+ extern int useSyslog;		        /* -syslog flag */
+ extern int useSyslogFacility;	        /* -syslogfacility option */
+ #endif
+ 
+ #define	MAXPARALLEL	32
+ 
+ extern int OKToZap;			/* -o flag */
+ extern int ForceSalvage;		/* If salvage should occur despite the DONT_SALVAGE flag
+ 					 * in the volume header */
+ 
+ 
+ #define ROOTINODE	2	/* Root inode of a 4.2 Unix file system
+ 				 * partition */
+ extern Device fileSysDevice;	/* The device number of the current
+ 				 * partition being salvaged */
+ #ifdef AFS_NT40_ENV
+ extern char fileSysPath[8];
+ #else
+ extern char *fileSysPath;	/* The path of the mounted partition currently
+ 				 * being salvaged, i.e. the directory
+ 				 * containing the volume headers */
+ #endif /* AFS_NT40_ENV */
+ extern char *fileSysPathName;	/* NT needs this to make name pretty in log. */
+ extern IHandle_t *VGLinkH;	/* Link handle for current volume group. */
+ extern int VGLinkH_cnt;	        /* # of references to lnk handle. */
+ extern struct DiskPartition *fileSysPartition;	/* Partition  being salvaged */
+ #ifndef AFS_NT40_ENV
+ extern char *fileSysDeviceName;	/* The block device where the file system
+ 				 * being salvaged was mounted */
+ extern char *filesysfulldev;
+ #endif /* AFS_NT40_ENV */
+ extern int VolumeChanged;	/* Set by any routine which would change the volume in
+ 				 * a way which would require callback is to be broken if the
+ 				 * volume was put back on line by an active file server */
+ 
+ extern VolumeDiskData VolInfo;	/* A copy of the last good or salvaged volume header dealt with */
+ 
+ extern int nVolumesInInodeFile;	/* Number of read-write volumes summarized */
+ extern int inodeFd;     	/* File descriptor for inode file */
+ 
+ 
+ extern struct VnodeInfo vnodeInfo[nVNODECLASSES];
+ 
+ 
+ extern struct VolumeSummary *volumeSummaryp;	/* Holds all the volumes in a part */
+ extern int nVolumes;		/* Number of volumes (read-write and read-only)
+ 				 * in volume summary */
+ 
+ extern char * tmpdir;
+ extern FILE *logFile;	        /* one of {/usr/afs/logs,/vice/file}/SalvageLog */
+ 
+ 
+ #ifdef AFS_NT40_ENV
+ /* For NT, we can fork the per partition salvagers to gain the required
+  * safety against Aborts. But there's too many complex data structures at
+  * the per volume salvager layer to easilty copy the data across.
+  * childJobNumber is resset from -1 to the job number if this is a
+  * per partition child of the main salvager. This information is passed
+  * out-of-band in the extra data area setup for the now unused parent/child
+  * data transfer.
+  */
+ #define SALVAGER_MAGIC 0x00BBaaDD
+ #define NOT_CHILD -1		/* job numbers start at 0 */
+ /* If new options need to be passed to child, add them here. */
+ typedef struct {
+     int cj_magic;
+     int cj_number;
+     char cj_part[32];
+ } childJob_t;
+ 
+ /* Child job this process is running. */
+ extern childJob_t myjob = { SALVAGER_MAGIC, NOT_CHILD, "" };
+ 
+ extern int nt_SalvagePartition(char *partName, int jobn);
+ extern int nt_SetupPartitionSalvage(void *datap, int len);
+ 
+ typedef struct {
+     struct InodeSummary *svgp_inodeSummaryp;
+     int svgp_count;
+ } SVGParms_t;
+ #define canfork 0
+ #else /* AFS_NT40_ENV */
+ #define canfork 1
+ #endif /* AFS_NT40_ENV */
+ 
+ 
+ /* prototypes */
+ extern void Exit(int code);
+ extern int Fork(void);
+ extern int Wait(char *prog);
+ extern char *ToString(char *s);
+ extern void AskOffline(VolumeId volumeId);
+ extern void AskOnline(VolumeId volumeId, char *partition);
+ extern void CheckLogFile(char * log_path);
+ #ifndef AFS_NT40_ENV
+ extern void TimeStampLogFile(char * log_path);
+ #endif
+ extern void ClearROInUseBit(struct VolumeSummary *summary);
+ extern void CopyAndSalvage(register struct DirSummary *dir);
+ extern int CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume);
+ extern void CopyOnWrite(register struct DirSummary *dir);
+ extern void CountVolumeInodes(register struct ViceInodeInfo *ip, int maxInodes,
+ 		       register struct InodeSummary *summary);
+ extern void DeleteExtraVolumeHeaderFile(register struct VolumeSummary *vsp);
+ extern void DistilVnodeEssence(VolumeId vid, VnodeClass class, Inode ino,
+ 			       Unique * maxu);
+ extern int GetInodeSummary(char *path, VolumeId singleVolumeNumber);
+ extern void GetVolumeSummary(VolumeId singleVolumeNumber);
+ extern void JudgeEntry(struct DirSummary *dir, char *name, VnodeId vnodeNumber,
+ 		       Unique unique);
+ extern void MaybeZapVolume(register struct InodeSummary *isp, char *message,
+ 			   int deleteMe, int check);
+ extern void ObtainSalvageLock(void);
+ extern void PrintInodeList(void);
+ extern void PrintInodeSummary(void);
+ extern void PrintVolumeSummary(void);
+ extern int QuickCheck(register struct InodeSummary *isp, int nVols);
+ extern void RemoveTheForce(char *path);
+ extern void SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo,
+ 		       IHandle_t * alinkH, int i, struct DirSummary *rootdir,
+ 		       int *rootdirfound);
+ extern void SalvageFileSysParallel(struct DiskPartition *partP);
+ extern void SalvageFileSys(struct DiskPartition *partP, VolumeId singleVolumeNumber);
+ extern void SalvageFileSys1(struct DiskPartition *partP,
+ 			    VolumeId singleVolumeNumber);
+ extern int SalvageHeader(register struct stuff *sp, struct InodeSummary *isp,
+ 			 int check, int *deleteMe);
+ extern int SalvageIndex(Inode ino, VnodeClass class, int RW,
+ 			register struct ViceInodeInfo *ip, int nInodes,
+ 			struct VolumeSummary *volSummary, int check);
+ extern int SalvageVnodes(register struct InodeSummary *rwIsp,
+ 			 register struct InodeSummary *thisIsp,
+ 			 register struct ViceInodeInfo *inodes, int check);
+ extern int SalvageVolume(register struct InodeSummary *rwIsp, IHandle_t * alinkH);
+ extern void DoSalvageVolumeGroup(register struct InodeSummary *isp, int nVols);
+ #ifdef AFS_NT40_ENV
+ extern void SalvageVolumeGroup(register struct InodeSummary *isp, int nVols);
+ #else
+ #define SalvageVolumeGroup DoSalvageVolumeGroup
+ #endif
+ extern int SalvageVolumeHeaderFile(register struct InodeSummary *isp,
+ 				   register struct ViceInodeInfo *inodes, int RW,
+ 				   int check, int *deleteMe);
+ extern void showlog(void);
+ extern int UseTheForceLuke(char *path);
+ 
+ 
+ 
+ #endif /* __vol_salvage_h_ */
Index: openafs/src/vol/voldefs.h
diff -c openafs/src/vol/voldefs.h:1.4 openafs/src/vol/voldefs.h:1.5
*** openafs/src/vol/voldefs.h:1.4	Tue Jul 15 19:17:41 2003
--- openafs/src/vol/voldefs.h	Fri Mar 17 14:54:52 2006
***************
*** 25,30 ****
--- 25,33 ----
  #define ROVOL			1
  #define BACKVOL			2
  
+ /* maximum numbe of Vice partitions */
+ #define	VOLMAXPARTS	255
+ 
  /* All volumes will have a volume header name in this format */
  #if	defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
  /* Note that &lt;afs/param.h&gt; must have been included before we get here... */
Index: openafs/src/vol/volinodes.h
diff -c openafs/src/vol/volinodes.h:1.4 openafs/src/vol/volinodes.h:1.5
*** openafs/src/vol/volinodes.h:1.4	Tue Jul 15 19:17:41 2003
--- openafs/src/vol/volinodes.h	Fri Mar 17 14:54:52 2006
***************
*** 14,19 ****
--- 14,22 ----
  
   */
  
+ #ifndef __volinodes_h_
+ #define __volinodes_h_
+ 
  /* Used by vutil.c and salvager.c */
  
  private struct VolumeHeader tempHeader;
***************
*** 56,58 ****
--- 59,63 ----
  #define MAXINODETYPE VI_LINKTABLE
  
  Volume *VWaitAttachVolume();
+ 
+ #endif /* __volinodes_h_ */
Index: openafs/src/vol/volume.c
diff -c openafs/src/vol/volume.c:1.41 openafs/src/vol/volume.c:1.43
*** openafs/src/vol/volume.c:1.41	Mon May 30 06:49:30 2005
--- openafs/src/vol/volume.c	Mon Mar 20 12:29:57 2006
***************
*** 5,10 ****
--- 5,12 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /* 1/1/89: NB:  this stuff is all going to be replaced.  Don't take it too seriously */
***************
*** 20,26 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/volume.c,v 1.41 2005/05/30 10:49:30 jaltman Exp $");
  
  #include &lt;rx/xdr.h&gt;
  #include &lt;afs/afsint.h&gt;
--- 22,28 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/volume.c,v 1.43 2006/03/20 17:29:57 jaltman Exp $");
  
  #include &lt;rx/xdr.h&gt;
  #include &lt;afs/afsint.h&gt;
***************
*** 121,126 ****
--- 123,131 ----
  #ifdef AFS_NT40_ENV
  #include &lt;io.h&gt;
  #endif
+ #include "daemon_com.h"
+ #include "fssync.h"
+ #include "salvsync.h"
  #include "vnode.h"
  #include "volume.h"
  #include "partition.h"
***************
*** 130,140 ****
  #include "afs/assert.h"
  #endif /* AFS_PTHREAD_ENV */
  #include "vutils.h"
- #include "fssync.h"
  #ifndef AFS_NT40_ENV
  #include &lt;unistd.h&gt;
  #endif
  
  #ifdef O_LARGEFILE
  #define afs_stat	stat64
  #define afs_fstat	fstat64
--- 135,149 ----
  #include "afs/assert.h"
  #endif /* AFS_PTHREAD_ENV */
  #include "vutils.h"
  #ifndef AFS_NT40_ENV
+ #include &lt;dir/dir.h&gt;
  #include &lt;unistd.h&gt;
  #endif
  
+ #if !defined(offsetof)
+ #include &lt;stddef.h&gt;
+ #endif
+ 
  #ifdef O_LARGEFILE
  #define afs_stat	stat64
  #define afs_fstat	fstat64
***************
*** 147,160 ****
  
  #ifdef AFS_PTHREAD_ENV
  pthread_mutex_t vol_glock_mutex;
- pthread_mutex_t vol_attach_mutex;
- pthread_mutex_t vol_fsync_mutex;
  pthread_mutex_t vol_trans_mutex;
  pthread_cond_t vol_put_volume_cond;
  pthread_cond_t vol_sleep_cond;
  int vol_attach_threads = 1;
  #endif /* AFS_PTHREAD_ENV */
  
  #ifdef	AFS_OSF_ENV
  extern void *calloc(), *realloc();
  #endif
--- 156,171 ----
  
  #ifdef AFS_PTHREAD_ENV
  pthread_mutex_t vol_glock_mutex;
  pthread_mutex_t vol_trans_mutex;
  pthread_cond_t vol_put_volume_cond;
  pthread_cond_t vol_sleep_cond;
  int vol_attach_threads = 1;
  #endif /* AFS_PTHREAD_ENV */
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ pthread_mutex_t vol_salvsync_mutex;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  #ifdef	AFS_OSF_ENV
  extern void *calloc(), *realloc();
  #endif
***************
*** 162,173 ****
  /*@printflike@*/ extern void Log(const char *format, ...);
  
  /* Forward declarations */
! static Volume *attach2(Error * ec, char *path,
  		       register struct VolumeHeader *header,
! 		       struct DiskPartition *partp, int isbusy);
  static void FreeVolume(Volume * vp);
  static void VScanUpdateList(void);
! static void InitLRU(int howMany);
  static int GetVolumeHeader(register Volume * vp);
  static void ReleaseVolumeHeader(register struct volHeader *hd);
  static void FreeVolumeHeader(register Volume * vp);
--- 173,190 ----
  /*@printflike@*/ extern void Log(const char *format, ...);
  
  /* Forward declarations */
! static Volume *attach2(Error * ec, VolId vid, char *path,
  		       register struct VolumeHeader *header,
! 		       struct DiskPartition *partp, Volume * vp, 
! 		       int isbusy, int mode);
! static void ReallyFreeVolume(Volume * vp);
! #ifdef AFS_DEMAND_ATTACH_FS
  static void FreeVolume(Volume * vp);
+ #else /* !AFS_DEMAND_ATTACH_FS */
+ #define FreeVolume(vp) ReallyFreeVolume(vp)
  static void VScanUpdateList(void);
! #endif /* !AFS_DEMAND_ATTACH_FS */
! static void VInitVolumeHeaderCache(afs_uint32 howMany);
  static int GetVolumeHeader(register Volume * vp);
  static void ReleaseVolumeHeader(register struct volHeader *hd);
  static void FreeVolumeHeader(register Volume * vp);
***************
*** 175,196 ****
  static void DeleteVolumeFromHashTable(register Volume * vp);
  static int VHold(Volume * vp);
  static int VHold_r(Volume * vp);
! static void GetBitmap(Error * ec, Volume * vp, VnodeClass class);
  static void GetVolumePath(Error * ec, VolId volumeId, char **partitionp,
  			  char **namep);
  static void VReleaseVolumeHandles_r(Volume * vp);
  static void VCloseVolumeHandles_r(Volume * vp);
  
  int LogLevel;			/* Vice loglevel--not defined as extern so that it will be
  				 * defined when not linked with vice, XXXX */
  ProgramType programType;	/* The type of program using the package */
  
  
  #define VOLUME_BITMAP_GROWSIZE	16	/* bytes, =&gt; 128vnodes */
  					/* Must be a multiple of 4 (1 word) !! */
! #define VOLUME_HASH_TABLE_SIZE 128	/* Must be a power of 2!! */
! #define VOLUME_HASH(volumeId) (volumeId&amp;(VOLUME_HASH_TABLE_SIZE-1))
! private Volume *VolumeHashTable[VOLUME_HASH_TABLE_SIZE];
  
  #ifndef AFS_HAVE_FFS
  /* This macro is used where an ffs() call does not exist. Was in util/ffs.c */
--- 192,263 ----
  static void DeleteVolumeFromHashTable(register Volume * vp);
  static int VHold(Volume * vp);
  static int VHold_r(Volume * vp);
! static void VGetBitmap_r(Error * ec, Volume * vp, VnodeClass class);
  static void GetVolumePath(Error * ec, VolId volumeId, char **partitionp,
  			  char **namep);
  static void VReleaseVolumeHandles_r(Volume * vp);
  static void VCloseVolumeHandles_r(Volume * vp);
+ static void LoadVolumeHeader(Error * ec, Volume * vp);
+ static int VCheckOffline(register Volume * vp);
+ static int VCheckDetach(register Volume * vp);
+ static Volume * GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint, int flags);
+ static int VolumeExternalName_r(VolumeId volumeId, char * name, size_t len);
  
  int LogLevel;			/* Vice loglevel--not defined as extern so that it will be
  				 * defined when not linked with vice, XXXX */
  ProgramType programType;	/* The type of program using the package */
  
  
+ /* extended volume package statistics */
+ VolPkgStats VStats;
+ 
+ 
  #define VOLUME_BITMAP_GROWSIZE	16	/* bytes, =&gt; 128vnodes */
  					/* Must be a multiple of 4 (1 word) !! */
! 
! /* this parameter needs to be tunable at runtime.
!  * 128 was really inadequate for largish servers -- at 16384 volumes this
!  * puts average chain length at 128, thus an average 65 deref's to find a volptr.
!  * talk about bad spatial locality...
!  *
!  * an AVL or splay tree might work a lot better, but we'll just increase
!  * the default hash table size for now
!  */
! #define DEFAULT_VOLUME_HASH_SIZE 256   /* Must be a power of 2!! */
! #define DEFAULT_VOLUME_HASH_MASK (DEFAULT_VOLUME_HASH_SIZE-1)
! #define VOLUME_HASH(volumeId) (volumeId&amp;(VolumeHashTable.Mask))
! 
! /*
!  * turn volume hash chains into partially ordered lists.
!  * when the threshold is exceeded between two adjacent elements,
!  * perform a chain rebalancing operation.
!  *
!  * keep the threshold high in order to keep cache line invalidates
!  * low "enough" on SMPs
!  */
! #define VOLUME_HASH_REORDER_THRESHOLD 200
! 
! /*
!  * when possible, don't just reorder single elements, but reorder
!  * entire chains of elements at once.  a chain of elements that
!  * exceed the element previous to the pivot by at least CHAIN_THRESH 
!  * accesses are moved in front of the chain whose elements have at
!  * least CHAIN_THRESH less accesses than the pivot element
!  */
! #define VOLUME_HASH_REORDER_CHAIN_THRESH (VOLUME_HASH_REORDER_THRESHOLD / 2)
! 
! #include "rx/rx_queue.h"
! 
! 
! VolumeHashTable_t VolumeHashTable = {
!     DEFAULT_VOLUME_HASH_SIZE,
!     DEFAULT_VOLUME_HASH_MASK,
!     NULL
! };
! 
! 
! static void VInitVolumeHash(void);
! 
  
  #ifndef AFS_HAVE_FFS
  /* This macro is used where an ffs() call does not exist. Was in util/ffs.c */
***************
*** 211,217 ****
  #endif /* !AFS_HAVE_FFS */
  
  #ifdef AFS_PTHREAD_ENV
- #include "rx/rx_queue.h"
  typedef struct diskpartition_queue_t {
      struct rx_queue queue;
      struct DiskPartition * diskP;
--- 278,283 ----
***************
*** 224,232 ****
  static void * VInitVolumePackageThread(void * args);
  #endif /* AFS_PTHREAD_ENV */
  
! struct Lock vol_listLock;	/* Lock obtained when listing volumes:  prevents a volume from being missed if the volume is attached during a list volumes */
  
- extern struct Lock FSYNC_handler_lock;
  
  static int TimeZoneCorrection;	/* Number of seconds west of GMT */
  
--- 290,409 ----
  static void * VInitVolumePackageThread(void * args);
  #endif /* AFS_PTHREAD_ENV */
  
! static int VAttachVolumesByPartition(struct DiskPartition *diskP, 
! 				     int * nAttached, int * nUnattached);
! 
! 
! #ifdef AFS_DEMAND_ATTACH_FS
! /* demand attach fileserver extensions */
! 
! /* XXX
!  * in the future we will support serialization of VLRU state into the fs_state
!  * disk dumps
!  *
!  * these structures are the beginning of that effort
!  */
! struct VLRU_DiskHeader {
!     struct versionStamp stamp;            /* magic and structure version number */
!     afs_uint32 mtime;                     /* time of dump to disk */
!     afs_uint32 num_records;               /* number of VLRU_DiskEntry records */
! };
! 
! struct VLRU_DiskEntry {
!     afs_uint32 vid;                       /* volume ID */
!     afs_uint32 idx;                       /* generation */
!     afs_uint32 last_get;                  /* timestamp of last get */
! };
! 
! struct VLRU_StartupQueue {
!     struct VLRU_DiskEntry * entry;
!     int num_entries;
!     int next_idx;
! };
! 
! typedef struct vshutdown_thread_t {
!     struct rx_queue q;
!     pthread_mutex_t lock;
!     pthread_cond_t cv;
!     pthread_cond_t master_cv;
!     int n_threads;
!     int n_threads_complete;
!     int vol_remaining;
!     int schedule_version;
!     int pass;
!     byte n_parts;
!     byte n_parts_done_pass;
!     byte part_thread_target[VOLMAXPARTS+1];
!     byte part_done_pass[VOLMAXPARTS+1];
!     struct rx_queue * part_pass_head[VOLMAXPARTS+1];
!     int stats[4][VOLMAXPARTS+1];
! } vshutdown_thread_t;
! static void * VShutdownThread(void * args);
! 
! 
! static Volume * VAttachVolumeByVp_r(Error * ec, Volume * vp, int mode);
! static int VCheckFree(Volume * vp);
! 
! /* VByP List */
! static void AddVolumeToVByPList_r(Volume * vp);
! static void DeleteVolumeFromVByPList_r(Volume * vp);
! static void VVByPListBeginExclusive_r(struct DiskPartition * dp);
! static void VVByPListEndExclusive_r(struct DiskPartition * dp);
! static void VVByPListWait_r(struct DiskPartition * dp);
! 
! /* online salvager */
! static int VCheckSalvage(register Volume * vp);
! static int VUpdateSalvagePriority_r(Volume * vp);
! static int VScheduleSalvage_r(Volume * vp);
! static int VCancelSalvage_r(Volume * vp, int reason);
! 
! /* Volume hash table */
! static void VReorderHash_r(VolumeHashChainHead * head, Volume * pp, Volume * vp);
! static void VHashBeginExclusive_r(VolumeHashChainHead * head);
! static void VHashEndExclusive_r(VolumeHashChainHead * head);
! static void VHashWait_r(VolumeHashChainHead * head);
! 
! /* Volume state machine */
! static void VCreateReservation_r(Volume * vp);
! static void VCancelReservation_r(Volume * vp);
! static void VWaitStateChange_r(Volume * vp);
! static void VWaitExclusiveState_r(Volume * vp);
! static int IsExclusiveState(VolState state);
! static int IsErrorState(VolState state);
! static int IsValidState(VolState state);
! 
! /* shutdown */
! static int ShutdownVByPForPass_r(struct DiskPartition * dp, int pass);
! static int ShutdownVolumeWalk_r(struct DiskPartition * dp, int pass,
! 				struct rx_queue ** idx);
! static void ShutdownController(vshutdown_thread_t * params);
! static void ShutdownCreateSchedule(vshutdown_thread_t * params);
! 
! /* VLRU */
! static void VLRU_ComputeConstants(void);
! static void VInitVLRU(void);
! static void VLRU_Init_Node_r(volatile Volume * vp);
! static void VLRU_Add_r(volatile Volume * vp);
! static void VLRU_Delete_r(volatile Volume * vp);
! static void VLRU_UpdateAccess_r(volatile Volume * vp);
! static void * VLRU_ScannerThread(void * args);
! static void VLRU_Scan_r(int idx);
! static void VLRU_Promote_r(int idx);
! static void VLRU_Demote_r(int idx);
! static void VLRU_SwitchQueues(volatile Volume * vp, int new_idx, int append);
! 
! /* soft detach */
! static int VCheckSoftDetach(volatile Volume * vp, afs_uint32 thresh);
! static int VCheckSoftDetachCandidate(volatile Volume * vp, afs_uint32 thresh);
! static int VSoftDetachVolume_r(volatile Volume * vp, afs_uint32 thresh);
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
! 
! struct Lock vol_listLock;	/* Lock obtained when listing volumes:  
! 				 * prevents a volume from being missed 
! 				 * if the volume is attached during a 
! 				 * list volumes */
  
  
  static int TimeZoneCorrection;	/* Number of seconds west of GMT */
  
***************
*** 247,258 ****
  				 * vnode will be invalidated
  				 * access only with VOL_LOCK held */
  
- int VolumeCacheSize = 200, VolumeGets = 0, VolumeReplacements = 0, Vlooks = 0;
  
  
  int
! VInitVolumePackage(ProgramType pt, int nLargeVnodes, int nSmallVnodes,
! 		   int connect, int volcache)
  {
      int errors = 0;		/* Number of errors while finding vice partitions. */
      struct timeval tv;
--- 424,439 ----
  				 * vnode will be invalidated
  				 * access only with VOL_LOCK held */
  
  
  
+ 
+ /***************************************************/
+ /* Startup routines                                */
+ /***************************************************/
+ 
  int
! VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes, afs_uint32 nSmallVnodes,
! 		   int connect, afs_uint32 volcache)
  {
      int errors = 0;		/* Number of errors while finding vice partitions. */
      struct timeval tv;
***************
*** 260,269 ****
  
      programType = pt;
  
  #ifdef AFS_PTHREAD_ENV
      assert(pthread_mutex_init(&amp;vol_glock_mutex, NULL) == 0);
-     assert(pthread_mutex_init(&amp;vol_attach_mutex, NULL) == 0);
-     assert(pthread_mutex_init(&amp;vol_fsync_mutex, NULL) == 0);
      assert(pthread_mutex_init(&amp;vol_trans_mutex, NULL) == 0);
      assert(pthread_cond_init(&amp;vol_put_volume_cond, NULL) == 0);
      assert(pthread_cond_init(&amp;vol_sleep_cond, NULL) == 0);
--- 441,464 ----
  
      programType = pt;
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+     memset(&amp;VStats, 0, sizeof(VStats));
+     VStats.hdr_cache_size = 200;
+ #endif
+ 
+     VInitPartitionPackage();
+     VInitVolumeHash();
+     VInitVnHashByVolume();
+ #ifdef AFS_DEMAND_ATTACH_FS
+     if (programType == fileServer) {
+ 	VInitVLRU();
+     } else {
+ 	VLRU_SetOptions(VLRU_SET_ENABLED, 0);
+     }
+ #endif
+ 
  #ifdef AFS_PTHREAD_ENV
      assert(pthread_mutex_init(&amp;vol_glock_mutex, NULL) == 0);
      assert(pthread_mutex_init(&amp;vol_trans_mutex, NULL) == 0);
      assert(pthread_cond_init(&amp;vol_put_volume_cond, NULL) == 0);
      assert(pthread_cond_init(&amp;vol_sleep_cond, NULL) == 0);
***************
*** 271,295 ****
      IOMGR_Initialize();
  #endif /* AFS_PTHREAD_ENV */
      Lock_Init(&amp;vol_listLock);
!     Lock_Init(&amp;FSYNC_handler_lock);
      srandom(time(0));		/* For VGetVolumeInfo */
      gettimeofday(&amp;tv, &amp;tz);
      TimeZoneCorrection = tz.tz_minuteswest * 60;
  
      /* Ok, we have done enough initialization that fileserver can 
       * start accepting calls, even though the volumes may not be 
       * available just yet.
       */
      VInit = 1;
  
      if (programType == fileServer) {
- 	/* File server or "stand" */
  	FSYNC_fsInit();
      }
  
!     if (volcache &gt; VolumeCacheSize)
! 	VolumeCacheSize = volcache;
!     InitLRU(VolumeCacheSize);
  
      VInitVnodes(vLarge, nLargeVnodes);
      VInitVnodes(vSmall, nSmallVnodes);
--- 466,506 ----
      IOMGR_Initialize();
  #endif /* AFS_PTHREAD_ENV */
      Lock_Init(&amp;vol_listLock);
! 
      srandom(time(0));		/* For VGetVolumeInfo */
      gettimeofday(&amp;tv, &amp;tz);
      TimeZoneCorrection = tz.tz_minuteswest * 60;
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+     assert(pthread_mutex_init(&amp;vol_salvsync_mutex, NULL) == 0);
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
      /* Ok, we have done enough initialization that fileserver can 
       * start accepting calls, even though the volumes may not be 
       * available just yet.
       */
      VInit = 1;
  
+ #if defined(AFS_DEMAND_ATTACH_FS) &amp;&amp; defined(SALVSYNC_BUILD_SERVER)
+     if (programType == salvageServer) {
+ 	SALVSYNC_salvInit();
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ #ifdef FSSYNC_BUILD_SERVER
      if (programType == fileServer) {
  	FSYNC_fsInit();
      }
+ #endif
+ #if defined(AFS_DEMAND_ATTACH_FS) &amp;&amp; defined(SALVSYNC_BUILD_CLIENT)
+     if (programType == fileServer) {
+ 	/* establish a connection to the salvager at this point */
+ 	assert(VConnectSALV() != 0);
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
!     if (volcache &gt; VStats.hdr_cache_size)
! 	VStats.hdr_cache_size = volcache;
!     VInitVolumeHeaderCache(VStats.hdr_cache_size);
  
      VInitVnodes(vLarge, nLargeVnodes);
      VInitVnodes(vSmall, nSmallVnodes);
***************
*** 304,310 ****
  #ifdef AFS_PTHREAD_ENV
  	struct vinitvolumepackage_thread_t params;
  	struct diskpartition_queue_t * dpq;
! 	int i, len;
  	pthread_t tid;
  	pthread_attr_t attrs;
  
--- 515,521 ----
  #ifdef AFS_PTHREAD_ENV
  	struct vinitvolumepackage_thread_t params;
  	struct diskpartition_queue_t * dpq;
! 	int i, threads, parts;
  	pthread_t tid;
  	pthread_attr_t attrs;
  
***************
*** 313,341 ****
  	params.n_threads_complete = 0;
  
  	/* create partition work queue */
! 	for (len=0, diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next, len++) {
  	    dpq = (diskpartition_queue_t *) malloc(sizeof(struct diskpartition_queue_t));
  	    assert(dpq != NULL);
  	    dpq-&gt;diskP = diskP;
  	    queue_Prepend(&amp;params,dpq);
  	}
  
! 	assert(pthread_attr_init(&amp;attrs) == 0);
! 	assert(pthread_attr_setdetachstate(&amp;attrs, PTHREAD_CREATE_DETACHED) == 0);
  
! 	len = MIN(len, vol_attach_threads);
! 	
! 	VOL_LOCK;
! 	for (i=0; i &lt; len; i++) {
! 	    assert(pthread_create
! 		   (&amp;tid, &amp;attrs, &amp;VInitVolumePackageThread,
! 		    &amp;params) == 0);
! 	}
  
! 	while(params.n_threads_complete &lt; len) {
!   	    pthread_cond_wait(&amp;params.thread_done_cv,&amp;vol_glock_mutex);
  	}
- 	VOL_UNLOCK;
  
  	assert(pthread_cond_destroy(&amp;params.thread_done_cv) == 0);
  
--- 524,579 ----
  	params.n_threads_complete = 0;
  
  	/* create partition work queue */
! 	for (parts=0, diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next, parts++) {
  	    dpq = (diskpartition_queue_t *) malloc(sizeof(struct diskpartition_queue_t));
  	    assert(dpq != NULL);
  	    dpq-&gt;diskP = diskP;
  	    queue_Prepend(&amp;params,dpq);
  	}
  
! 	threads = MIN(parts, vol_attach_threads);
  
! 	if (threads &gt; 1) {
! 	    /* spawn off a bunch of initialization threads */
! 	    assert(pthread_attr_init(&amp;attrs) == 0);
! 	    assert(pthread_attr_setdetachstate(&amp;attrs, PTHREAD_CREATE_DETACHED) == 0);
! 
! 	    Log("VInitVolumePackage: beginning parallel fileserver startup\n");
! #ifdef AFS_DEMAND_ATTACH_FS
! 	    Log("VInitVolumePackage: using %d threads to pre-attach volumes on %d partitions\n",
! 		threads, parts);
! #else /* AFS_DEMAND_ATTACH_FS */
! 	    Log("VInitVolumePackage: using %d threads to attach volumes on %d partitions\n",
! 		threads, parts);
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
! 	    VOL_LOCK;
! 	    for (i=0; i &lt; threads; i++) {
! 		assert(pthread_create
! 		       (&amp;tid, &amp;attrs, &amp;VInitVolumePackageThread,
! 			&amp;params) == 0);
! 	    }
! 
! 	    while(params.n_threads_complete &lt; threads) {
! 		pthread_cond_wait(&amp;params.thread_done_cv,&amp;vol_glock_mutex);
! 	    }
! 	    VOL_UNLOCK;
! 
! 	    assert(pthread_attr_destroy(&amp;attrs) == 0);
! 	} else {
! 	    /* if we're only going to run one init thread, don't bother creating
! 	     * another LWP */
! 	    Log("VInitVolumePackage: beginning single-threaded fileserver startup\n");
! #ifdef AFS_DEMAND_ATTACH_FS
! 	    Log("VInitVolumePackage: using 1 thread to pre-attach volumes on %d partition(s)\n",
! 		parts);
! #else /* AFS_DEMAND_ATTACH_FS */
! 	    Log("VInitVolumePackage: using 1 thread to attach volumes on %d partition(s)\n",
! 		parts);
! #endif /* AFS_DEMAND_ATTACH_FS */
  
! 	    VInitVolumePackageThread(&amp;params);
  	}
  
  	assert(pthread_cond_destroy(&amp;params.thread_done_cv) == 0);
  
***************
*** 346,389 ****
  	/* Attach all the volumes in this partition */
  	for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
  	    int nAttached = 0, nUnattached = 0;
! 	    Log("Partition %s: attaching volumes\n", diskP-&gt;name);
! 	    dirp = opendir(VPartitionPath(diskP));
! 	    assert(dirp);
! 	    while ((dp = readdir(dirp))) {
! 		char *p;
! 		p = strrchr(dp-&gt;d_name, '.');
! 		if (p != NULL &amp;&amp; strcmp(p, VHDREXT) == 0) {
! 		    Error error;
! 		    Volume *vp;
! 		    vp = VAttachVolumeByName(&amp;error, diskP-&gt;name, dp-&gt;d_name,
! 					     V_VOLUPD);
! 		    (*(vp ? &amp;nAttached : &amp;nUnattached))++;
! 		    if (error == VOFFLINE)
! 			Log("Volume %d stays offline (/vice/offline/%s exists)\n", VolumeNumber(dp-&gt;d_name), dp-&gt;d_name);
! 		    else if (LogLevel &gt;= 5) {
! 			Log("Partition %s: attached volume %d (%s)\n",
! 			    diskP-&gt;name, VolumeNumber(dp-&gt;d_name),
! 			    dp-&gt;d_name);
! 		    }
! 		    if (vp) {
! 			VPutVolume(vp);
! 		    }
! 		}
! 	    }
! 	    Log("Partition %s: attached %d volumes; %d volumes not attached\n", diskP-&gt;name, nAttached, nUnattached);
! 	    closedir(dirp);
  	}
  #endif /* AFS_PTHREAD_ENV */
      }
  
      VInit = 2;			/* Initialized, and all volumes have been attached */
      if (programType == volumeUtility &amp;&amp; connect) {
  	if (!VConnectFS()) {
  	    Log("Unable to connect to file server; aborted\n");
- 	    Lock_Destroy(&amp;FSYNC_handler_lock);
  	    exit(1);
  	}
      }
      return 0;
  }
  
--- 584,611 ----
  	/* Attach all the volumes in this partition */
  	for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
  	    int nAttached = 0, nUnattached = 0;
! 	    assert(VAttachVolumesByPartition(diskP, &amp;nAttached, &amp;nUnattached) == 0);
  	}
  #endif /* AFS_PTHREAD_ENV */
      }
  
      VInit = 2;			/* Initialized, and all volumes have been attached */
+ #ifdef FSSYNC_BUILD_CLIENT
      if (programType == volumeUtility &amp;&amp; connect) {
  	if (!VConnectFS()) {
  	    Log("Unable to connect to file server; aborted\n");
  	    exit(1);
  	}
      }
+ #ifdef AFS_DEMAND_ATTACH_FS
+     else if (programType == salvageServer) {
+ 	if (!VConnectFS()) {
+ 	    Log("Unable to connect to file server; aborted\n");
+ 	    exit(1);
+ 	}
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ #endif /* FSSYNC_BUILD_CLIENT */
      return 0;
  }
  
***************
*** 412,443 ****
  	diskP = dpq-&gt;diskP;
  	free(dpq);
  
! 	Log("Partition %s: attaching volumes\n", diskP-&gt;name);
! 	dirp = opendir(VPartitionPath(diskP));
! 	assert(dirp);
! 	while ((dp = readdir(dirp))) {
! 	    char *p;
! 	    p = strrchr(dp-&gt;d_name, '.');
! 	    if (p != NULL &amp;&amp; strcmp(p, VHDREXT) == 0) {
! 	        Error error;
! 		Volume *vp;
! 		vp = VAttachVolumeByName(&amp;error, diskP-&gt;name, dp-&gt;d_name,
! 					 V_VOLUPD);
! 		(*(vp ? &amp;nAttached : &amp;nUnattached))++;
! 		if (error == VOFFLINE)
! 		    Log("Volume %d stays offline (/vice/offline/%s exists)\n", VolumeNumber(dp-&gt;d_name), dp-&gt;d_name);
! 		else if (LogLevel &gt;= 5) {
! 		    Log("Partition %s: attached volume %d (%s)\n",
! 			diskP-&gt;name, VolumeNumber(dp-&gt;d_name),
! 			dp-&gt;d_name);
! 		}
! 		if (vp) {
! 		    VPutVolume(vp);
! 		}
! 	    }
! 	}
! 	Log("Partition %s: attached %d volumes; %d volumes not attached\n", diskP-&gt;name, nAttached, nUnattached);
! 	closedir(dirp);
  	VOL_LOCK;
      }
  
--- 634,641 ----
  	diskP = dpq-&gt;diskP;
  	free(dpq);
  
! 	assert(VAttachVolumesByPartition(diskP, &amp;nAttached, &amp;nUnattached) == 0);
! 
  	VOL_LOCK;
      }
  
***************
*** 448,493 ****
  }
  #endif /* AFS_PTHREAD_ENV */
  
! /* This must be called by any volume utility which needs to run while the
!    file server is also running.  This is separated from VInitVolumePackage so
!    that a utility can fork--and each of the children can independently
!    initialize communication with the file server */
! int
! VConnectFS(void)
  {
!     int retVal;
!     VOL_LOCK;
!     retVal = VConnectFS_r();
!     VOL_UNLOCK;
!     return retVal;
  }
  
- int
- VConnectFS_r(void)
- {
-     int rc;
-     assert(VInit == 2 &amp;&amp; programType == volumeUtility);
-     rc = FSYNC_clientInit();
-     if (rc)
- 	VInit = 3;
-     return rc;
- }
  
! void
! VDisconnectFS_r(void)
! {
!     assert(programType == volumeUtility);
!     FSYNC_clientFinis();
!     VInit = 2;
! }
  
! void
! VDisconnectFS(void)
! {
!     VOL_LOCK;
!     VDisconnectFS_r();
!     VOL_UNLOCK;
! }
  
  void
  VShutdown_r(void)
--- 646,759 ----
  }
  #endif /* AFS_PTHREAD_ENV */
  
! /*
!  * attach all volumes on a given disk partition
!  */
! static int
! VAttachVolumesByPartition(struct DiskPartition *diskP, int * nAttached, int * nUnattached)
  {
!   DIR * dirp;
!   struct dirent * dp;
!   int ret = 0;
! 
!   Log("Partition %s: attaching volumes\n", diskP-&gt;name);
!   dirp = opendir(VPartitionPath(diskP));
!   if (!dirp) {
!     Log("opendir on Partition %s failed!\n", diskP-&gt;name);
!     return 1;
!   }
! 
!   while ((dp = readdir(dirp))) {
!     char *p;
!     p = strrchr(dp-&gt;d_name, '.');
!     if (p != NULL &amp;&amp; strcmp(p, VHDREXT) == 0) {
!       Error error;
!       Volume *vp;
! #ifdef AFS_DEMAND_ATTACH_FS
!       vp = VPreAttachVolumeByName(&amp;error, diskP-&gt;name, dp-&gt;d_name,
!                                   V_VOLUPD);
! #else /* AFS_DEMAND_ATTACH_FS */
!       vp = VAttachVolumeByName(&amp;error, diskP-&gt;name, dp-&gt;d_name,
! 			       V_VOLUPD);
! #endif /* AFS_DEMAND_ATTACH_FS */
!       (*(vp ? nAttached : nUnattached))++;
!       if (error == VOFFLINE)
! 	Log("Volume %d stays offline (/vice/offline/%s exists)\n", VolumeNumber(dp-&gt;d_name), dp-&gt;d_name);
!       else if (LogLevel &gt;= 5) {
! 	Log("Partition %s: attached volume %d (%s)\n",
! 	    diskP-&gt;name, VolumeNumber(dp-&gt;d_name),
! 	    dp-&gt;d_name);
!       }
! #if !defined(AFS_DEMAND_ATTACH_FS)
!       if (vp) {
! 	VPutVolume(vp);
!       }
! #endif /* AFS_DEMAND_ATTACH_FS */
!     }
!   }
! 
!   Log("Partition %s: attached %d volumes; %d volumes not attached\n", diskP-&gt;name, *nAttached, *nUnattached);
!   closedir(dirp);
!   return ret;
  }
  
  
! /***************************************************/
! /* Shutdown routines                               */
! /***************************************************/
  
! /*
!  * demand attach fs
!  * highly multithreaded volume package shutdown
!  *
!  * with the demand attach fileserver extensions,
!  * VShutdown has been modified to be multithreaded.
!  * In order to achieve optimal use of many threads,
!  * the shutdown code involves one control thread and
!  * n shutdown worker threads.  The control thread
!  * periodically examines the number of volumes available
!  * for shutdown on each partition, and produces a worker
!  * thread allocation schedule.  The idea is to eliminate
!  * redundant scheduling computation on the workers by
!  * having a single master scheduler.
!  *
!  * The scheduler's objectives are:
!  * (1) fairness
!  *   each partition with volumes remaining gets allocated
!  *   at least 1 thread (assuming sufficient threads)
!  * (2) performance
!  *   threads are allocated proportional to the number of
!  *   volumes remaining to be offlined.  This ensures that
!  *   the OS I/O scheduler has many requests to elevator
!  *   seek on partitions that will (presumably) take the
!  *   longest amount of time (from now) to finish shutdown
!  * (3) keep threads busy
!  *   when there are extra threads, they are assigned to
!  *   partitions using a simple round-robin algorithm
!  *
!  * In the future, we may wish to add the ability to adapt
!  * to the relative performance patterns of each disk
!  * partition.
!  *
!  *
!  * demand attach fs
!  * multi-step shutdown process
!  *
!  * demand attach shutdown is a four-step process. Each
!  * shutdown "pass" shuts down increasingly more difficult
!  * volumes.  The main purpose is to achieve better cache
!  * utilization during shutdown.
!  *
!  * pass 0
!  *   shutdown volumes in the unattached, pre-attached
!  *   and error states
!  * pass 1
!  *   shutdown attached volumes with cached volume headers
!  * pass 2
!  *   shutdown all volumes in non-exclusive states
!  * pass 3
!  *   shutdown all remaining volumes
!  */
  
  void
  VShutdown_r(void)
***************
*** 495,530 ****
      int i;
      register Volume *vp, *np;
      register afs_int32 code;
  
      Log("VShutdown:  shutting down on-line volumes...\n");
!     for (i = 0; i &lt; VOLUME_HASH_TABLE_SIZE; i++) {
  	/* try to hold first volume in the hash table */
! 	for (vp = VolumeHashTable[i]; vp; vp = vp-&gt;hashNext) {
  	    code = VHold_r(vp);
! 	    if (code == 0)
! 		break;		/* got it */
! 	    /* otherwise we go around again, trying another volume */
! 	}
! 	while (vp) {
! 	    if (LogLevel &gt;= 5)
! 		Log("VShutdown:  Attempting to take volume %u offline.\n",
! 		    vp-&gt;hashid);
! 	    /* first compute np before releasing vp, in case vp disappears
! 	     * after releasing.  Hold it, so it doesn't disapear.  If we
! 	     * can't hold it, try the next one in the chain.  Invariant
! 	     * at the top of this loop is that vp is held (has extra ref count).
! 	     */
! 	    for (np = vp-&gt;hashNext; np; np = np-&gt;hashNext) {
! 		code = VHold_r(np);
! 		if (code == 0)
! 		    break;	/* got it */
  	    }
- 	    /* next, take the volume offline (drops reference count) */
- 	    VOffline_r(vp, "File server was shut down");
- 	    vp = np;		/* next guy to try */
  	}
      }
      Log("VShutdown:  complete.\n");
  }
  
  void
--- 761,899 ----
      int i;
      register Volume *vp, *np;
      register afs_int32 code;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     struct DiskPartition * diskP;
+     struct diskpartition_queue_t * dpq;
+     vshutdown_thread_t params;
+     pthread_t tid;
+     pthread_attr_t attrs;
+ 
+     memset(&amp;params, 0, sizeof(vshutdown_thread_t));
+ 
+     for (params.n_parts=0, diskP = DiskPartitionList;
+ 	 diskP; diskP = diskP-&gt;next, params.n_parts++);
+ 
+     Log("VShutdown:  shutting down on-line volumes on %d partition%s...\n", 
+ 	params.n_parts, params.n_parts &gt; 1 ? "s" : "");
+ 
+     if (vol_attach_threads &gt; 1) {
+ 	/* prepare for parallel shutdown */
+ 	params.n_threads = vol_attach_threads;
+ 	assert(pthread_mutex_init(&amp;params.lock, NULL) == 0);
+ 	assert(pthread_cond_init(&amp;params.cv, NULL) == 0);
+ 	assert(pthread_cond_init(&amp;params.master_cv, NULL) == 0);
+ 	assert(pthread_attr_init(&amp;attrs) == 0);
+ 	assert(pthread_attr_setdetachstate(&amp;attrs, PTHREAD_CREATE_DETACHED) == 0);
+ 	queue_Init(&amp;params);
+ 
+ 	/* setup the basic partition information structures for
+ 	 * parallel shutdown */
+ 	for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
+ 	    /* XXX debug */
+ 	    struct rx_queue * qp, * nqp;
+ 	    Volume * vp;
+ 	    int count = 0;
+ 
+ 	    VVByPListWait_r(diskP);
+ 	    VVByPListBeginExclusive_r(diskP);
+ 
+ 	    /* XXX debug */
+ 	    for (queue_Scan(&amp;diskP-&gt;vol_list, qp, nqp, rx_queue)) {
+ 		vp = (Volume *)((char *)qp - offsetof(Volume, vol_list));
+ 		if (vp-&gt;header)
+ 		    count++;
+ 	    }
+ 	    Log("VShutdown: partition %s has %d volumes with attached headers\n",
+ 		VPartitionPath(diskP), count);
+ 		
+ 
+ 	    /* build up the pass 0 shutdown work queue */
+ 	    dpq = (struct diskpartition_queue_t *) malloc(sizeof(struct diskpartition_queue_t));
+ 	    assert(dpq != NULL);
+ 	    dpq-&gt;diskP = diskP;
+ 	    queue_Prepend(&amp;params, dpq);
+ 
+ 	    params.part_pass_head[diskP-&gt;device] = queue_First(&amp;diskP-&gt;vol_list, rx_queue);
+ 	}
+ 
+ 	Log("VShutdown:  beginning parallel fileserver shutdown\n");
+ 	Log("VShutdown:  using %d threads to offline volumes on %d partition%s\n",
+ 	    vol_attach_threads, params.n_parts, params.n_parts &gt; 1 ? "s" : "" );
+ 
+ 	/* do pass 0 shutdown */
+ 	assert(pthread_mutex_lock(&amp;params.lock) == 0);
+ 	for (i=0; i &lt; params.n_threads; i++) {
+ 	    assert(pthread_create
+ 		   (&amp;tid, &amp;attrs, &amp;VShutdownThread,
+ 		    &amp;params) == 0);
+ 	}
+ 	
+ 	/* wait for all the pass 0 shutdowns to complete */
+ 	while (params.n_threads_complete &lt; params.n_threads) {
+ 	    assert(pthread_cond_wait(&amp;params.master_cv, &amp;params.lock) == 0);
+ 	}
+ 	params.n_threads_complete = 0;
+ 	params.pass = 1;
+ 	assert(pthread_cond_broadcast(&amp;params.cv) == 0);
+ 	assert(pthread_mutex_unlock(&amp;params.lock) == 0);
+ 
+ 	Log("VShutdown:  pass 0 completed using the 1 thread per partition algorithm\n");
+ 	Log("VShutdown:  starting passes 1 through 3 using finely-granular mp-fast algorithm\n");
+ 
+ 	/* run the parallel shutdown scheduler. it will drop the glock internally */
+ 	ShutdownController(&amp;params);
+ 	
+ 	/* wait for all the workers to finish pass 3 and terminate */
+ 	while (params.pass &lt; 4) {
+ 	    assert(pthread_cond_wait(&amp;params.cv, &amp;vol_glock_mutex) == 0);
+ 	}
+ 	
+ 	assert(pthread_attr_destroy(&amp;attrs) == 0);
+ 	assert(pthread_cond_destroy(&amp;params.cv) == 0);
+ 	assert(pthread_cond_destroy(&amp;params.master_cv) == 0);
+ 	assert(pthread_mutex_destroy(&amp;params.lock) == 0);
+ 
+ 	/* drop the VByPList exclusive reservations */
+ 	for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
+ 	    VVByPListEndExclusive_r(diskP);
+ 	    Log("VShutdown:  %s stats : (pass[0]=%d, pass[1]=%d, pass[2]=%d, pass[3]=%d)\n",
+ 		VPartitionPath(diskP),
+ 		params.stats[0][diskP-&gt;device],
+ 		params.stats[1][diskP-&gt;device],
+ 		params.stats[2][diskP-&gt;device],
+ 		params.stats[3][diskP-&gt;device]);
+ 	}
+ 
+ 	Log("VShutdown:  shutdown finished using %d threads\n", params.n_threads);
+     } else {
+ 	/* if we're only going to run one shutdown thread, don't bother creating
+ 	 * another LWP */
+ 	Log("VShutdown:  beginning single-threaded fileserver shutdown\n");
+ 
+ 	for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
+ 	    VShutdownByPartition_r(diskP);
+ 	}
+     }
  
+     Log("VShutdown:  complete.\n");
+ #else /* AFS_DEMAND_ATTACH_FS */
      Log("VShutdown:  shutting down on-line volumes...\n");
!     for (i = 0; i &lt; VolumeHashTable.Size; i++) {
  	/* try to hold first volume in the hash table */
! 	for (queue_Scan(&amp;VolumeHashTable.Table[i],vp,np,Volume)) {
  	    code = VHold_r(vp);
! 	    if (code == 0) {
! 		if (LogLevel &gt;= 5)
! 		    Log("VShutdown:  Attempting to take volume %u offline.\n",
! 			vp-&gt;hashid);
! 		
! 		/* next, take the volume offline (drops reference count) */
! 		VOffline_r(vp, "File server was shut down");
  	    }
  	}
      }
      Log("VShutdown:  complete.\n");
+ #endif /* AFS_DEMAND_ATTACH_FS */
  }
  
  void
***************
*** 535,600 ****
      VOL_UNLOCK;
  }
  
! 
  static void
! ReadHeader(Error * ec, IHandle_t * h, char *to, int size, bit32 magic,
! 	   bit32 version)
  {
!     struct versionStamp *vsn;
!     FdHandle_t *fdP;
  
!     *ec = 0;
!     if (h == NULL) {
! 	*ec = VSALVAGE;
! 	return;
      }
  
!     fdP = IH_OPEN(h);
!     if (fdP == NULL) {
! 	*ec = VSALVAGE;
  	return;
      }
  
!     if (FDH_SEEK(fdP, 0, SEEK_SET) &lt; 0) {
! 	*ec = VSALVAGE;
! 	FDH_REALLYCLOSE(fdP);
! 	return;
      }
!     vsn = (struct versionStamp *)to;
!     if (FDH_READ(fdP, to, size) != size || vsn-&gt;magic != magic) {
! 	*ec = VSALVAGE;
! 	FDH_REALLYCLOSE(fdP);
! 	return;
      }
-     FDH_CLOSE(fdP);
  
!     /* Check is conditional, in case caller wants to inspect version himself */
!     if (version &amp;&amp; vsn-&gt;version != version) {
! 	*ec = VSALVAGE;
      }
  }
  
! /* VolumeHeaderToDisk
!  * Allows for storing 64 bit inode numbers in on-disk volume header
!  * file.
!  */
! void
! VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h)
  {
  
!     memset((char *)dh, 0, sizeof(VolumeDiskHeader_t));
!     dh-&gt;stamp = h-&gt;stamp;
!     dh-&gt;id = h-&gt;id;
!     dh-&gt;parent = h-&gt;parent;
  
! #ifdef AFS_64BIT_IOPS_ENV
!     dh-&gt;volumeInfo_lo = (afs_int32) h-&gt;volumeInfo &amp; 0xffffffff;
!     dh-&gt;volumeInfo_hi = (afs_int32) (h-&gt;volumeInfo &gt;&gt; 32) &amp; 0xffffffff;
!     dh-&gt;smallVnodeIndex_lo = (afs_int32) h-&gt;smallVnodeIndex &amp; 0xffffffff;
!     dh-&gt;smallVnodeIndex_hi =
! 	(afs_int32) (h-&gt;smallVnodeIndex &gt;&gt; 32) &amp; 0xffffffff;
!     dh-&gt;largeVnodeIndex_lo = (afs_int32) h-&gt;largeVnodeIndex &amp; 0xffffffff;
!     dh-&gt;largeVnodeIndex_hi =
  	(afs_int32) (h-&gt;largeVnodeIndex &gt;&gt; 32) &amp; 0xffffffff;
      dh-&gt;linkTable_lo = (afs_int32) h-&gt;linkTable &amp; 0xffffffff;
      dh-&gt;linkTable_hi = (afs_int32) (h-&gt;linkTable &gt;&gt; 32) &amp; 0xffffffff;
--- 904,1489 ----
      VOL_UNLOCK;
  }
  
! #ifdef AFS_DEMAND_ATTACH_FS
! /*
!  * demand attach fs
!  * shutdown control thread
!  */
  static void
! ShutdownController(vshutdown_thread_t * params)
  {
!     /* XXX debug */
!     struct DiskPartition * diskP;
!     Device id;
!     vshutdown_thread_t shadow;
  
!     ShutdownCreateSchedule(params);
! 
!     while ((params-&gt;pass &lt; 4) &amp;&amp;
! 	   (params-&gt;n_threads_complete &lt; params-&gt;n_threads)) {
! 	/* recompute schedule once per second */
! 
! 	memcpy(&amp;shadow, params, sizeof(vshutdown_thread_t));
! 
! 	VOL_UNLOCK;
! 	/* XXX debug */
! 	Log("ShutdownController:  schedule version=%d, vol_remaining=%d, pass=%d\n",
! 	    shadow.schedule_version, shadow.vol_remaining, shadow.pass);
! 	Log("ShutdownController:  n_threads_complete=%d, n_parts_done_pass=%d\n",
! 	    shadow.n_threads_complete, shadow.n_parts_done_pass);
! 	for (diskP = DiskPartitionList; diskP; diskP=diskP-&gt;next) {
! 	    id = diskP-&gt;device;
! 	    Log("ShutdownController:  part[%d] : (len=%d, thread_target=%d, done_pass=%d, pass_head=%p)\n",
! 		id, 
! 		diskP-&gt;vol_list.len,
! 		shadow.part_thread_target[id], 
! 		shadow.part_done_pass[id], 
! 		shadow.part_pass_head[id]);
! 	}
! 
! 	sleep(1);
! 	VOL_LOCK;
! 
! 	ShutdownCreateSchedule(params);
      }
+ }
  
! /* create the shutdown thread work schedule.
!  * this scheduler tries to implement fairness
!  * by allocating at least 1 thread to each 
!  * partition with volumes to be shutdown,
!  * and then it attempts to allocate remaining
!  * threads based upon the amount of work left
!  */
! static void
! ShutdownCreateSchedule(vshutdown_thread_t * params)
! {
!     struct DiskPartition * diskP;
!     int sum, thr_workload, thr_left;
!     int part_residue[VOLMAXPARTS+1];
!     Device id;
! 
!     /* compute the total number of outstanding volumes */
!     sum = 0;
!     for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
! 	sum += diskP-&gt;vol_list.len;
!     }
!     
!     params-&gt;schedule_version++;
!     params-&gt;vol_remaining = sum;
! 
!     if (!sum)
  	return;
+ 
+     /* compute average per-thread workload */
+     thr_workload = sum / params-&gt;n_threads;
+     if (sum % params-&gt;n_threads)
+ 	thr_workload++;
+ 
+     thr_left = params-&gt;n_threads;
+     memset(&amp;part_residue, 0, sizeof(part_residue));
+ 
+     /* for fairness, give every partition with volumes remaining
+      * at least one thread */
+     for (diskP = DiskPartitionList; diskP &amp;&amp; thr_left; diskP = diskP-&gt;next) {
+ 	id = diskP-&gt;device;
+ 	if (diskP-&gt;vol_list.len) {
+ 	    params-&gt;part_thread_target[id] = 1;
+ 	    thr_left--;
+ 	} else {
+ 	    params-&gt;part_thread_target[id] = 0;
+ 	}
      }
  
!     if (thr_left &amp;&amp; thr_workload) {
! 	/* compute length-weighted workloads */
! 	int delta;
! 
! 	for (diskP = DiskPartitionList; diskP &amp;&amp; thr_left; diskP = diskP-&gt;next) {
! 	    id = diskP-&gt;device;
! 	    delta = (diskP-&gt;vol_list.len / thr_workload) -
! 		params-&gt;part_thread_target[id];
! 	    if (delta &lt; 0) {
! 		continue;
! 	    }
! 	    if (delta &lt; thr_left) {
! 		params-&gt;part_thread_target[id] += delta;
! 		thr_left -= delta;
! 	    } else {
! 		params-&gt;part_thread_target[id] += thr_left;
! 		thr_left = 0;
! 		break;
! 	    }
! 	}
      }
! 
!     if (thr_left) {
! 	/* try to assign any leftover threads to partitions that
! 	 * had volume lengths closer to needing thread_target+1 */
! 	int max_residue, max_id;
! 
! 	/* compute the residues */
! 	for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
! 	    id = diskP-&gt;device;
! 	    part_residue[id] = diskP-&gt;vol_list.len - 
! 		(params-&gt;part_thread_target[id] * thr_workload);
! 	}
! 
! 	/* now try to allocate remaining threads to partitions with the
! 	 * highest residues */
! 	while (thr_left) {
! 	    max_residue = 0;
! 	    for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
! 		id = diskP-&gt;device;
! 		if (part_residue[id] &gt; max_residue) {
! 		    max_residue = part_residue[id];
! 		    max_id = id;
! 		}
! 	    }
! 
! 	    if (!max_residue) {
! 		break;
! 	    }
! 
! 	    params-&gt;part_thread_target[max_id]++;
! 	    thr_left--;
! 	    part_residue[max_id] = 0;
! 	}
      }
  
!     if (thr_left) {
! 	/* punt and give any remaining threads equally to each partition */
! 	int alloc;
! 	if (thr_left &gt;= params-&gt;n_parts) {
! 	    alloc = thr_left / params-&gt;n_parts;
! 	    for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
! 		id = diskP-&gt;device;
! 		params-&gt;part_thread_target[id] += alloc;
! 		thr_left -= alloc;
! 	    }
! 	}
! 
! 	/* finish off the last of the threads */
! 	for (diskP = DiskPartitionList; thr_left &amp;&amp; diskP; diskP = diskP-&gt;next) {
! 	    id = diskP-&gt;device;
! 	    params-&gt;part_thread_target[id]++;
! 	    thr_left--;
! 	}
      }
  }
  
! /* worker thread for parallel shutdown */
! static void *
! VShutdownThread(void * args)
  {
+     struct rx_queue *qp;
+     Volume * vp;
+     vshutdown_thread_t * params;
+     int part, code, found, pass, schedule_version_save, count;
+     struct DiskPartition *diskP;
+     struct diskpartition_queue_t * dpq;
+     Device id;
  
!     params = (vshutdown_thread_t *) args;
  
!     /* acquire the shutdown pass 0 lock */
!     assert(pthread_mutex_lock(&amp;params-&gt;lock) == 0);
! 
!     /* if there's still pass 0 work to be done,
!      * get a work entry, and do a pass 0 shutdown */
!     if (queue_IsNotEmpty(params)) {
! 	dpq = queue_First(params, diskpartition_queue_t);
! 	queue_Remove(dpq);
! 	assert(pthread_mutex_unlock(&amp;params-&gt;lock) == 0);
! 	diskP = dpq-&gt;diskP;
! 	free(dpq);
! 	id = diskP-&gt;device;
! 
! 	count = 0;
! 	while (ShutdownVolumeWalk_r(diskP, 0, &amp;params-&gt;part_pass_head[id]))
! 	    count++;
! 	params-&gt;stats[0][diskP-&gt;device] = count;
! 	assert(pthread_mutex_lock(&amp;params-&gt;lock) == 0);
!     }
! 
!     params-&gt;n_threads_complete++;
!     if (params-&gt;n_threads_complete == params-&gt;n_threads) {
!       /* notify control thread that all workers have completed pass 0 */
!       assert(pthread_cond_signal(&amp;params-&gt;master_cv) == 0);
!     }
!     while (params-&gt;pass == 0) {
!       assert(pthread_cond_wait(&amp;params-&gt;cv, &amp;params-&gt;lock) == 0);
!     }
! 
!     /* switch locks */
!     assert(pthread_mutex_unlock(&amp;params-&gt;lock) == 0);
!     VOL_LOCK;
! 
!     pass = params-&gt;pass;
!     assert(pass &gt; 0);
! 
!     /* now escalate through the more complicated shutdowns */
!     while (pass &lt;= 3) {
! 	schedule_version_save = params-&gt;schedule_version;
! 	found = 0;
! 	/* find a disk partition to work on */
! 	for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
! 	    id = diskP-&gt;device;
! 	    if (params-&gt;part_thread_target[id] &amp;&amp; !params-&gt;part_done_pass[id]) {
! 		params-&gt;part_thread_target[id]--;
! 		found = 1;
! 		break;
! 	    }
! 	}
! 	
! 	if (!found) {
! 	    /* hmm. for some reason the controller thread couldn't find anything for 
! 	     * us to do. let's see if there's anything we can do */
! 	    for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
! 		id = diskP-&gt;device;
! 		if (diskP-&gt;vol_list.len &amp;&amp; !params-&gt;part_done_pass[id]) {
! 		    found = 1;
! 		    break;
! 		} else if (!params-&gt;part_done_pass[id]) {
! 		    params-&gt;part_done_pass[id] = 1;
! 		    params-&gt;n_parts_done_pass++;
! 		    if (pass == 3) {
! 			Log("VShutdown:  done shutting down volumes on partition %s.\n",
! 			    VPartitionPath(diskP));
! 		    }
! 		}
! 	    }
! 	}
! 	
! 	/* do work on this partition until either the controller
! 	 * creates a new schedule, or we run out of things to do
! 	 * on this partition */
! 	if (found) {
! 	    count = 0;
! 	    while (!params-&gt;part_done_pass[id] &amp;&amp;
! 		   (schedule_version_save == params-&gt;schedule_version)) {
! 		/* ShutdownVolumeWalk_r will drop the glock internally */
! 		if (!ShutdownVolumeWalk_r(diskP, pass, &amp;params-&gt;part_pass_head[id])) {
! 		    if (!params-&gt;part_done_pass[id]) {
! 			params-&gt;part_done_pass[id] = 1;
! 			params-&gt;n_parts_done_pass++;
! 			if (pass == 3) {
! 			    Log("VShutdown:  done shutting down volumes on partition %s.\n",
! 				VPartitionPath(diskP));
! 			}
! 		    }
! 		    break;
! 		}
! 		count++;
! 	    }
! 
! 	    params-&gt;stats[pass][id] += count;
! 	} else {
! 	    /* ok, everyone is done this pass, proceed */
! 
! 	    /* barrier lock */
! 	    params-&gt;n_threads_complete++;
! 	    while (params-&gt;pass == pass) {
! 		if (params-&gt;n_threads_complete == params-&gt;n_threads) {
! 		    /* we are the last thread to complete, so we will
! 		     * reinitialize worker pool state for the next pass */
! 		    params-&gt;n_threads_complete = 0;
! 		    params-&gt;n_parts_done_pass = 0;
! 		    params-&gt;pass++;
! 		    for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
! 			id = diskP-&gt;device;
! 			params-&gt;part_done_pass[id] = 0;
! 			params-&gt;part_pass_head[id] = queue_First(&amp;diskP-&gt;vol_list, rx_queue);
! 		    }
! 
! 		    /* compute a new thread schedule before releasing all the workers */
! 		    ShutdownCreateSchedule(params);
! 
! 		    /* wake up all the workers */
! 		    assert(pthread_cond_broadcast(&amp;params-&gt;cv) == 0);
! 
! 		    VOL_UNLOCK;
! 		    Log("VShutdown:  pass %d completed using %d threads on %d partitions\n",
! 			pass, params-&gt;n_threads, params-&gt;n_parts);
! 		    VOL_LOCK;
! 		} else {
! 		    assert(pthread_cond_wait(&amp;params-&gt;cv, &amp;vol_glock_mutex) == 0);
! 		}
! 	    }
! 	    pass = params-&gt;pass;
! 	}
! 	
! 	/* for fairness */
! 	VOL_UNLOCK;
! 	pthread_yield();
! 	VOL_LOCK;
!     }
! 
!     VOL_UNLOCK;
! 
!     return NULL;
! }
! 
! /* shut down all volumes on a given disk partition 
!  *
!  * note that this function will not allow mp-fast
!  * shutdown of a partition */
! int
! VShutdownByPartition_r(struct DiskPartition * dp)
! {
!     int pass, retVal;
!     int pass_stats[4];
!     int total;
! 
!     /* wait for other exclusive ops to finish */
!     VVByPListWait_r(dp);
! 
!     /* begin exclusive access */
!     VVByPListBeginExclusive_r(dp);
! 
!     /* pick the low-hanging fruit first,
!      * then do the complicated ones last 
!      * (has the advantage of keeping
!      *  in-use volumes up until the bitter end) */
!     for (pass = 0, total=0; pass &lt; 4; pass++) {
! 	pass_stats[pass] = ShutdownVByPForPass_r(dp, pass);
! 	total += pass_stats[pass];
!     }
! 
!     /* end exclusive access */
!     VVByPListEndExclusive_r(dp);
! 
!     Log("VShutdownByPartition:  shut down %d volumes on %s (pass[0]=%d, pass[1]=%d, pass[2]=%d, pass[3]=%d)\n",
! 	total, VPartitionPath(dp), pass_stats[0], pass_stats[1], pass_stats[2], pass_stats[3]);
! 
!     return retVal;
! }
! 
! /* internal shutdown functionality
!  *
!  * for multi-pass shutdown:
!  * 0 to only "shutdown" {pre,un}attached and error state volumes
!  * 1 to also shutdown attached volumes w/ volume header loaded
!  * 2 to also shutdown attached volumes w/o volume header loaded
!  * 3 to also shutdown exclusive state volumes 
!  *
!  * caller MUST hold exclusive access on the hash chain
!  * because we drop vol_glock_mutex internally
!  * 
!  * this function is reentrant for passes 1--3 
!  * (e.g. multiple threads can cooperate to 
!  *  shutdown a partition mp-fast)
!  *
!  * pass 0 is not scaleable because the volume state data is
!  * synchronized by vol_glock mutex, and the locking overhead
!  * is too high to drop the lock long enough to do linked list
!  * traversal
!  */
! static int
! ShutdownVByPForPass_r(struct DiskPartition * dp, int pass)
! {
!     struct rx_queue * q = queue_First(&amp;dp-&gt;vol_list, rx_queue);
!     register int i = 0;
! 
!     while (ShutdownVolumeWalk_r(dp, pass, &amp;q))
! 	i++;
! 
!     return i;
! }
! 
! /* conditionally shutdown one volume on partition dp
!  * returns 1 if a volume was shutdown in this pass,
!  * 0 otherwise */
! static int
! ShutdownVolumeWalk_r(struct DiskPartition * dp, int pass,
! 		     struct rx_queue ** idx)
! {
!     struct rx_queue *qp, *nqp;
!     Volume * vp;
! 
!     qp = *idx;
! 
!     for (queue_ScanFrom(&amp;dp-&gt;vol_list, qp, qp, nqp, rx_queue)) {
! 	vp = (Volume *) (((char *)qp) - offsetof(Volume, vol_list));
! 	
! 	switch (pass) {
! 	case 0:
! 	    if ((V_attachState(vp) != VOL_STATE_UNATTACHED) &amp;&amp;
! 		(V_attachState(vp) != VOL_STATE_ERROR) &amp;&amp;
! 		(V_attachState(vp) != VOL_STATE_PREATTACHED)) {
! 		break;
! 	    }
! 	case 1:
! 	    if ((V_attachState(vp) == VOL_STATE_ATTACHED) &amp;&amp;
! 		(vp-&gt;header == NULL)) {
! 		break;
! 	    }
! 	case 2:
! 	    if (IsExclusiveState(V_attachState(vp))) {
! 		break;
! 	    }
! 	case 3:
! 	    *idx = nqp;
! 	    DeleteVolumeFromVByPList_r(vp);
! 	    VShutdownVolume_r(vp);
! 	    vp = NULL;
! 	    return 1;
! 	}
!     }
! 
!     return 0;
! }
! 
! /*
!  * shutdown a specific volume
!  */
! /* caller MUST NOT hold a heavyweight ref on vp */
! int
! VShutdownVolume_r(Volume * vp)
! {
!     int code;
! 
!     VCreateReservation_r(vp);
! 
!     if (LogLevel &gt;= 5) {
! 	Log("VShutdownVolume_r:  vid=%u, device=%d, state=%hu\n",
! 	    vp-&gt;hashid, vp-&gt;partition-&gt;device, V_attachState(vp));
!     }
! 
!     /* wait for other blocking ops to finish */
!     VWaitExclusiveState_r(vp);
! 
!     assert(IsValidState(V_attachState(vp)));
!     
!     switch(V_attachState(vp)) {
!     case VOL_STATE_SALVAGING:
! 	/* make sure salvager knows we don't want
! 	 * the volume back */
! 	VCancelSalvage_r(vp, SALVSYNC_SHUTDOWN);
!     case VOL_STATE_PREATTACHED:
!     case VOL_STATE_ERROR:
! 	VChangeState_r(vp, VOL_STATE_UNATTACHED);
!     case VOL_STATE_UNATTACHED:
! 	break;
!     case VOL_STATE_GOING_OFFLINE:
!     case VOL_STATE_SHUTTING_DOWN:
!     case VOL_STATE_ATTACHED:
! 	code = VHold_r(vp);
! 	if (!code) {
! 	    if (LogLevel &gt;= 5)
! 		Log("VShutdown:  Attempting to take volume %u offline.\n",
! 		    vp-&gt;hashid);
! 
! 	    /* take the volume offline (drops reference count) */
! 	    VOffline_r(vp, "File server was shut down");
! 	}
! 	break;
!     }
!     
!     VCancelReservation_r(vp);
!     vp = NULL;
!     return 0;
! }
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
! 
! /***************************************************/
! /* Header I/O routines                             */
! /***************************************************/
! 
! /* open a descriptor for the inode (h),
!  * read in an on-disk structure into buffer (to) of size (size),
!  * verify versionstamp in structure has magic (magic) and
!  * optionally verify version (version) if (version) is nonzero
!  */
! static void
! ReadHeader(Error * ec, IHandle_t * h, char *to, int size, bit32 magic,
! 	   bit32 version)
! {
!     struct versionStamp *vsn;
!     FdHandle_t *fdP;
! 
!     *ec = 0;
!     if (h == NULL) {
! 	*ec = VSALVAGE;
! 	return;
!     }
! 
!     fdP = IH_OPEN(h);
!     if (fdP == NULL) {
! 	*ec = VSALVAGE;
! 	return;
!     }
! 
!     if (FDH_SEEK(fdP, 0, SEEK_SET) &lt; 0) {
! 	*ec = VSALVAGE;
! 	FDH_REALLYCLOSE(fdP);
! 	return;
!     }
!     vsn = (struct versionStamp *)to;
!     if (FDH_READ(fdP, to, size) != size || vsn-&gt;magic != magic) {
! 	*ec = VSALVAGE;
! 	FDH_REALLYCLOSE(fdP);
! 	return;
!     }
!     FDH_CLOSE(fdP);
! 
!     /* Check is conditional, in case caller wants to inspect version himself */
!     if (version &amp;&amp; vsn-&gt;version != version) {
! 	*ec = VSALVAGE;
!     }
! }
! 
! void
! WriteVolumeHeader_r(Error * ec, Volume * vp)
! {
!     IHandle_t *h = V_diskDataHandle(vp);
!     FdHandle_t *fdP;
! 
!     *ec = 0;
! 
!     fdP = IH_OPEN(h);
!     if (fdP == NULL) {
! 	*ec = VSALVAGE;
! 	return;
!     }
!     if (FDH_SEEK(fdP, 0, SEEK_SET) &lt; 0) {
! 	*ec = VSALVAGE;
! 	FDH_REALLYCLOSE(fdP);
! 	return;
!     }
!     if (FDH_WRITE(fdP, (char *)&amp;V_disk(vp), sizeof(V_disk(vp)))
! 	!= sizeof(V_disk(vp))) {
! 	*ec = VSALVAGE;
! 	FDH_REALLYCLOSE(fdP);
! 	return;
!     }
!     FDH_CLOSE(fdP);
! }
! 
! /* VolumeHeaderToDisk
!  * Allows for storing 64 bit inode numbers in on-disk volume header
!  * file.
!  */
! /* convert in-memory representation of a volume header to the
!  * on-disk representation of a volume header */
! void
! VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h)
! {
! 
!     memset((char *)dh, 0, sizeof(VolumeDiskHeader_t));
!     dh-&gt;stamp = h-&gt;stamp;
!     dh-&gt;id = h-&gt;id;
!     dh-&gt;parent = h-&gt;parent;
! 
! #ifdef AFS_64BIT_IOPS_ENV
!     dh-&gt;volumeInfo_lo = (afs_int32) h-&gt;volumeInfo &amp; 0xffffffff;
!     dh-&gt;volumeInfo_hi = (afs_int32) (h-&gt;volumeInfo &gt;&gt; 32) &amp; 0xffffffff;
!     dh-&gt;smallVnodeIndex_lo = (afs_int32) h-&gt;smallVnodeIndex &amp; 0xffffffff;
!     dh-&gt;smallVnodeIndex_hi =
! 	(afs_int32) (h-&gt;smallVnodeIndex &gt;&gt; 32) &amp; 0xffffffff;
!     dh-&gt;largeVnodeIndex_lo = (afs_int32) h-&gt;largeVnodeIndex &amp; 0xffffffff;
!     dh-&gt;largeVnodeIndex_hi =
  	(afs_int32) (h-&gt;largeVnodeIndex &gt;&gt; 32) &amp; 0xffffffff;
      dh-&gt;linkTable_lo = (afs_int32) h-&gt;linkTable &amp; 0xffffffff;
      dh-&gt;linkTable_hi = (afs_int32) (h-&gt;linkTable &gt;&gt; 32) &amp; 0xffffffff;
***************
*** 607,614 ****
  }
  
  /* DiskToVolumeHeader
!  * Reads volume header file from disk, convering 64 bit inodes
!  * if required. Makes the assumption that AFS has *always* 
   * zero'd the volume header file so that high parts of inode
   * numbers are 0 in older (SGI EFS) volume header files.
   */
--- 1496,1505 ----
  }
  
  /* DiskToVolumeHeader
!  * Converts an on-disk representation of a volume header to
!  * the in-memory representation of a volume header.
!  *
!  * Makes the assumption that AFS has *always* 
   * zero'd the volume header file so that high parts of inode
   * numbers are 0 in older (SGI EFS) volume header files.
   */
***************
*** 642,768 ****
  }
  
  
! void
! WriteVolumeHeader_r(ec, vp)
!      Error *ec;
!      Volume *vp;
! {
!     IHandle_t *h = V_diskDataHandle(vp);
!     FdHandle_t *fdP;
! 
!     *ec = 0;
! 
!     fdP = IH_OPEN(h);
!     if (fdP == NULL) {
! 	*ec = VSALVAGE;
! 	return;
!     }
!     if (FDH_SEEK(fdP, 0, SEEK_SET) &lt; 0) {
! 	*ec = VSALVAGE;
! 	FDH_REALLYCLOSE(fdP);
! 	return;
!     }
!     if (FDH_WRITE(fdP, (char *)&amp;V_disk(vp), sizeof(V_disk(vp)))
! 	!= sizeof(V_disk(vp))) {
! 	*ec = VSALVAGE;
! 	FDH_REALLYCLOSE(fdP);
! 	return;
!     }
!     FDH_CLOSE(fdP);
! }
  
! /* Attach an existing volume, given its pathname, and return a
!    pointer to the volume header information.  The volume also
!    normally goes online at this time.  An offline volume
!    must be reattached to make it go online */
  Volume *
! VAttachVolumeByName(Error * ec, char *partition, char *name, int mode)
  {
!     Volume *retVal;
!     VATTACH_LOCK;
      VOL_LOCK;
!     retVal = VAttachVolumeByName_r(ec, partition, name, mode);
      VOL_UNLOCK;
!     VATTACH_UNLOCK;
!     return retVal;
  }
  
  Volume *
! VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
  {
!     register Volume *vp;
      int fd, n;
      struct afs_stat status;
-     struct VolumeDiskHeader diskHeader;
-     struct VolumeHeader iheader;
      struct DiskPartition *partp;
      char path[64];
      int isbusy = 0;
      *ec = 0;
!     if (programType == volumeUtility) {
! 	assert(VInit == 3);
! 	VLockPartition_r(partition);
      }
!     if (programType == fileServer) {
! 	vp = VGetVolume_r(ec, VolumeNumber(name));
! 	if (vp) {
! 	    if (V_inUse(vp))
! 		return vp;
! 	    if (vp-&gt;specialStatus == VBUSY)
! 		isbusy = 1;
! 	    VDetachVolume_r(ec, vp);
! 	    if (*ec) {
! 		Log("VAttachVolume: Error detaching volume (%s)\n", name);
! 	    }
  	}
      }
  
      if (!(partp = VGetPartition_r(partition, 0))) {
  	*ec = VNOVOL;
  	Log("VAttachVolume: Error getting partition (%s)\n", partition);
  	goto done;
      }
  
      *ec = 0;
      strcpy(path, VPartitionPath(partp));
      strcat(path, "/");
      strcat(path, name);
-     VOL_UNLOCK;
      if ((fd = afs_open(path, O_RDONLY)) == -1 || afs_fstat(fd, &amp;status) == -1) {
  	Log("VAttachVolume: Failed to open %s (errno %d)\n", path, errno);
  	if (fd &gt; -1)
  	    close(fd);
- 	VOL_LOCK;
  	*ec = VNOVOL;
  	goto done;
      }
      n = read(fd, &amp;diskHeader, sizeof(diskHeader));
      close(fd);
-     VOL_LOCK;
      if (n != sizeof(diskHeader)
  	|| diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
  	Log("VAttachVolume: Error reading volume header %s\n", path);
  	*ec = VSALVAGE;
  	goto done;
      }
      if (diskHeader.stamp.version != VOLUMEHEADERVERSION) {
  	Log("VAttachVolume: Volume %s, version number is incorrect; volume needs salvaged\n", path);
  	*ec = VSALVAGE;
  	goto done;
      }
  
      DiskToVolumeHeader(&amp;iheader, &amp;diskHeader);
      if (programType == volumeUtility &amp;&amp; mode != V_SECRETLY &amp;&amp; mode != V_PEEK) {
! 	if (FSYNC_askfs(iheader.id, partition, FSYNC_NEEDVOLUME, mode)
! 	    == FSYNC_DENIED) {
  	    Log("VAttachVolume: attach of volume %u apparently denied by file server\n", iheader.id);
  	    *ec = VNOVOL;	/* XXXX */
  	    goto done;
  	}
      }
  
!     vp = attach2(ec, path, &amp;iheader, partp, isbusy);
      if (programType == volumeUtility &amp;&amp; vp) {
  	/* duplicate computation in fssync.c about whether the server
  	 * takes the volume offline or not.  If the volume isn't
  	 * offline, we must not return it when we detach the volume,
--- 1533,1904 ----
  }
  
  
! /***************************************************/
! /* Volume Attachment routines                      */
! /***************************************************/
  
! #ifdef AFS_DEMAND_ATTACH_FS
! /* pre-attach a volume given its path 
!  *
!  * a pre-attached volume will only have its partition
!  * and hashid fields initialized
!  *
!  * at first call to VGetVolume, the volume will be
!  * fully attached
!  */
  Volume *
! VPreAttachVolumeByName(Error * ec, char *partition, char *name, int mode)
  {
!     Volume * vp;
      VOL_LOCK;
!     vp = VPreAttachVolumeByName_r(ec, partition, name, mode);
      VOL_UNLOCK;
!     return vp;
  }
  
  Volume *
! VPreAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
  {
!     register Volume *vp = NULL;
      int fd, n;
      struct afs_stat status;
      struct DiskPartition *partp;
      char path[64];
      int isbusy = 0;
+     VolId volumeId;
      *ec = 0;
! 
!     assert(programType == fileServer);
! 
!     if (!(partp = VGetPartition_r(partition, 0))) {
! 	*ec = VNOVOL;
! 	Log("VPreAttachVolume:  Error getting partition (%s)\n", partition);
! 	return NULL;
      }
! 
!     volumeId = VolumeNumber(name);
! 
!     vp = VLookupVolume_r(ec, volumeId, NULL);
!     if (*ec) {
! 	return NULL;
!     }
! 
!     return VPreAttachVolumeById_r(ec, partp, vp, volumeId);
! }
! 
! /* pre-attach a volume given its partition and volume id
!  *
!  * if vp == NULL, then a new vp is created
!  * if vp != NULL, then we assumed it is already on the hash chain
!  */
! Volume * 
! VPreAttachVolumeById_r(Error * ec, struct DiskPartition * partp, 
! 		       Volume * vp, int vid)
! {
!     Volume *nvp = NULL;
! 
!     *ec = 0;
! 
!     /* check to see if pre-attach already happened */
!     if (vp &amp;&amp; 
! 	(V_attachState(vp) != VOL_STATE_UNATTACHED) &amp;&amp; 
! 	!IsErrorState(V_attachState(vp))) {
! 	goto done;
!     } else if (vp) {
! 	/* we're re-attaching a volume; clear out some old state */
! 	memset(&amp;vp-&gt;salvage, 0, sizeof(struct VolumeOnlineSalvage));
!     } else {
! 	/* if we need to allocate a new Volume struct,
! 	 * go ahead and drop the vol glock, otherwise
! 	 * do the basic setup synchronised, as it's
! 	 * probably not worth dropping the lock */
! 	VOL_UNLOCK;
! 
! 	/* allocate the volume structure */
! 	vp = nvp = (Volume *) malloc(sizeof(Volume));
! 	assert(vp != NULL);
! 	memset(vp, 0, sizeof(Volume));
! 	assert(pthread_cond_init(&amp;V_attachCV(vp), NULL) == 0);
!     }
! 
!     /* link the volume with its associated vice partition */
!     vp-&gt;device = partp-&gt;device;
!     vp-&gt;partition = partp;
!     vp-&gt;hashid = vid;
! 
!     /* if we dropped the lock, reacquire the lock,
!      * check for pre-attach races, and then add
!      * the volume to the hash table */
!     if (nvp) {
! 	VOL_LOCK;
! 	nvp = VLookupVolume_r(ec, vid, NULL);
! 	if (*ec) {
! 	    free(vp);
! 	    vp = NULL;
! 	    goto done;
! 	} else if (nvp) { /* race detected */
! 	    free(vp);
! 	    vp = nvp;
! 	    goto done;
! 	} else {
! 	  /* hack to make up for VChangeState_r() decrementing 
! 	   * the old state counter */
! 	  VStats.state_levels[0]++;
  	}
      }
  
+     /* put pre-attached volume onto the hash table
+      * and bring it up to the pre-attached state */
+     AddVolumeToHashTable(vp, vp-&gt;hashid);
+     AddVolumeToVByPList_r(vp);
+     VLRU_Init_Node_r(vp);
+     VChangeState_r(vp, VOL_STATE_PREATTACHED);
+ 
+     if (LogLevel &gt;= 5)
+ 	Log("VPreAttachVolumeById_r:  volume %u pre-attached\n", vp-&gt;hashid);
+ 
+   done:
+     if (*ec)
+ 	return NULL;
+     else
+ 	return vp;
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ /* Attach an existing volume, given its pathname, and return a
+    pointer to the volume header information.  The volume also
+    normally goes online at this time.  An offline volume
+    must be reattached to make it go online */
+ Volume *
+ VAttachVolumeByName(Error * ec, char *partition, char *name, int mode)
+ {
+     Volume *retVal;
+     VOL_LOCK;
+     retVal = VAttachVolumeByName_r(ec, partition, name, mode);
+     VOL_UNLOCK;
+     return retVal;
+ }
+ 
+ Volume *
+ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
+ {
+     register Volume *vp = NULL, *svp = NULL;
+     int fd, n;
+     struct afs_stat status;
+     struct VolumeDiskHeader diskHeader;
+     struct VolumeHeader iheader;
+     struct DiskPartition *partp;
+     char path[64];
+     int isbusy = 0;
+     VolId volumeId;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     VolumeStats stats_save;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+     *ec = 0;
+    
+     volumeId = VolumeNumber(name);
+ 
      if (!(partp = VGetPartition_r(partition, 0))) {
  	*ec = VNOVOL;
  	Log("VAttachVolume: Error getting partition (%s)\n", partition);
  	goto done;
      }
  
+     if (programType == volumeUtility) {
+ 	assert(VInit == 3);
+ 	VLockPartition_r(partition);
+     } else if (programType == fileServer) {
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	/* lookup the volume in the hash table */
+ 	vp = VLookupVolume_r(ec, volumeId, NULL);
+ 	if (*ec) {
+ 	    return NULL;
+ 	}
+ 
+ 	if (vp) {
+ 	    /* save any counters that are supposed to
+ 	     * be monotonically increasing over the
+ 	     * lifetime of the fileserver */
+ 	    memcpy(&amp;stats_save, &amp;vp-&gt;stats, sizeof(VolumeStats));
+ 	} else {
+ 	    memset(&amp;stats_save, 0, sizeof(VolumeStats));
+ 	}
+ 
+ 	/* if there's something in the hash table, and it's not
+ 	 * in the pre-attach state, then we may need to detach
+ 	 * it before proceeding */
+ 	if (vp &amp;&amp; (V_attachState(vp) != VOL_STATE_PREATTACHED)) {
+ 	    VCreateReservation_r(vp);
+ 	    VWaitExclusiveState_r(vp);
+ 
+ 	    /* at this point state must be one of:
+ 	     *   UNATTACHED,
+ 	     *   ATTACHED,
+ 	     *   SHUTTING_DOWN,
+ 	     *   GOING_OFFLINE,
+ 	     *   SALVAGING,
+ 	     *   ERROR
+ 	     */
+ 
+ 	    if (vp-&gt;specialStatus == VBUSY)
+ 		isbusy = 1;
+ 	    
+ 	    /* if it's already attached, see if we can return it */
+ 	    if (V_attachState(vp) == VOL_STATE_ATTACHED) {
+ 		VGetVolumeByVp_r(ec, vp);
+ 		if (V_inUse(vp)) {
+ 		    VCancelReservation_r(vp);
+ 		    return vp;
+ 		}
+ 
+ 		/* otherwise, we need to detach, and attempt to re-attach */
+ 		VDetachVolume_r(ec, vp);
+ 		if (*ec) {
+ 		    Log("VAttachVolume: Error detaching old volume instance (%s)\n", name);
+ 		}
+ 	    } else {
+ 		/* if it isn't fully attached, delete from the hash tables,
+ 		   and let the refcounter handle the rest */
+ 		DeleteVolumeFromHashTable(vp);
+ 		DeleteVolumeFromVByPList_r(vp);
+ 	    }
+ 
+ 	    VCancelReservation_r(vp);
+ 	    vp = NULL;
+ 	}
+ 
+ 	/* pre-attach volume if it hasn't been done yet */
+ 	if (!vp || 
+ 	    (V_attachState(vp) == VOL_STATE_UNATTACHED) ||
+ 	    (V_attachState(vp) == VOL_STATE_ERROR)) {
+ 	    svp = vp;
+ 	    vp = VPreAttachVolumeById_r(ec, partp, vp, volumeId);
+ 	    if (*ec) {
+ 		return NULL;
+ 	    }
+ 	}
+ 
+ 	assert(vp != NULL);
+ 
+ 	/* handle pre-attach races 
+ 	 *
+ 	 * multiple threads can race to pre-attach a volume,
+ 	 * but we can't let them race beyond that
+ 	 * 
+ 	 * our solution is to let the first thread to bring
+ 	 * the volume into an exclusive state win; the other
+ 	 * threads just wait until it finishes bringing the
+ 	 * volume online, and then they do a vgetvolumebyvp
+ 	 */
+ 	if (svp &amp;&amp; (svp != vp)) {
+ 	    /* wait for other exclusive ops to finish */
+ 	    VCreateReservation_r(vp);
+ 	    VWaitExclusiveState_r(vp);
+ 
+ 	    /* get a heavyweight ref, kill the lightweight ref, and return */
+ 	    VGetVolumeByVp_r(ec, vp);
+ 	    VCancelReservation_r(vp);
+ 	    return vp;
+ 	}
+ 
+ 	/* at this point, we are chosen as the thread to do
+ 	 * demand attachment for this volume. all other threads
+ 	 * doing a getvolume on vp-&gt;hashid will block until we finish */
+ 
+ 	/* make sure any old header cache entries are invalidated
+ 	 * before proceeding */
+ 	FreeVolumeHeader(vp);
+ 
+ 	VChangeState_r(vp, VOL_STATE_ATTACHING);
+ 
+ 	/* restore any saved counters */
+ 	memcpy(&amp;vp-&gt;stats, &amp;stats_save, sizeof(VolumeStats));
+ #else /* AFS_DEMAND_ATTACH_FS */
+ 	vp = VGetVolume_r(ec, volumeId);
+ 	if (vp) {
+ 	    if (V_inUse(vp))
+ 		return vp;
+ 	    if (vp-&gt;specialStatus == VBUSY)
+ 		isbusy = 1;
+ 	    VDetachVolume_r(ec, vp);
+ 	    if (*ec) {
+ 		Log("VAttachVolume: Error detaching volume (%s)\n", name);
+ 	    }
+ 	    vp = NULL;
+ 	}
+ #endif /* AFS_DEMAND_ATTACH_FS */
+     }
+ 
      *ec = 0;
      strcpy(path, VPartitionPath(partp));
+ 
+     VOL_UNLOCK;
+ 
      strcat(path, "/");
      strcat(path, name);
      if ((fd = afs_open(path, O_RDONLY)) == -1 || afs_fstat(fd, &amp;status) == -1) {
  	Log("VAttachVolume: Failed to open %s (errno %d)\n", path, errno);
  	if (fd &gt; -1)
  	    close(fd);
  	*ec = VNOVOL;
+ 	VOL_LOCK;
  	goto done;
      }
      n = read(fd, &amp;diskHeader, sizeof(diskHeader));
      close(fd);
      if (n != sizeof(diskHeader)
  	|| diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
  	Log("VAttachVolume: Error reading volume header %s\n", path);
  	*ec = VSALVAGE;
+ 	VOL_LOCK;
  	goto done;
      }
      if (diskHeader.stamp.version != VOLUMEHEADERVERSION) {
  	Log("VAttachVolume: Volume %s, version number is incorrect; volume needs salvaged\n", path);
  	*ec = VSALVAGE;
+ 	VOL_LOCK;
  	goto done;
      }
  
      DiskToVolumeHeader(&amp;iheader, &amp;diskHeader);
+ #ifdef FSSYNC_BUILD_CLIENT
      if (programType == volumeUtility &amp;&amp; mode != V_SECRETLY &amp;&amp; mode != V_PEEK) {
!         VOL_LOCK;
! 	if (FSYNC_VolOp(iheader.id, partition, FSYNC_VOL_NEEDVOLUME, mode, NULL)
! 	    != SYNC_OK) {
  	    Log("VAttachVolume: attach of volume %u apparently denied by file server\n", iheader.id);
  	    *ec = VNOVOL;	/* XXXX */
  	    goto done;
  	}
+ 	VOL_UNLOCK;
+     }
+ #endif
+ 
+     if (!vp) {
+       vp = (Volume *) calloc(1, sizeof(Volume));
+       assert(vp != NULL);
+       vp-&gt;device = partp-&gt;device;
+       vp-&gt;partition = partp;
+ #ifdef AFS_DEMAND_ATTACH_FS
+       assert(pthread_cond_init(&amp;V_attachCV(vp), NULL) == 0);
+ #endif /* AFS_DEMAND_ATTACH_FS */
      }
  
!     /* attach2 is entered without any locks, and returns
!      * with vol_glock_mutex held */
!     vp = attach2(ec, volumeId, path, &amp;iheader, partp, vp, isbusy, mode);
! 
      if (programType == volumeUtility &amp;&amp; vp) {
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	/* for dafs, we should tell the fileserver, except for V_PEEK
+          * where we know it is not necessary */
+ 	if (mode == V_PEEK) {
+ 	    vp-&gt;needsPutBack = 0;
+ 	} else {
+ 	    vp-&gt;needsPutBack = 1;
+ 	}
+ #else /* !AFS_DEMAND_ATTACH_FS */
  	/* duplicate computation in fssync.c about whether the server
  	 * takes the volume offline or not.  If the volume isn't
  	 * offline, we must not return it when we detach the volume,
***************
*** 772,777 ****
--- 1908,1914 ----
  	    vp-&gt;needsPutBack = 0;
  	else
  	    vp-&gt;needsPutBack = 1;
+ #endif /* !AFS_DEMAND_ATTACH_FS */
      }
      /* OK, there's a problem here, but one that I don't know how to
       * fix right now, and that I don't think should arise often.
***************
*** 784,793 ****
       * for all of that to happen, but if it does, probably the right
       * fix is for the server to allow the return of readonly volumes
       * that it doesn't think are really checked out. */
      if (programType == volumeUtility &amp;&amp; vp == NULL &amp;&amp;
  	mode != V_SECRETLY &amp;&amp; mode != V_PEEK) {
! 	FSYNC_askfs(iheader.id, partition, FSYNC_ON, 0);
!     } else if (programType == fileServer &amp;&amp; vp) {
  	V_needsCallback(vp) = 0;
  #ifdef	notdef
  	if (VInit &gt;= 2 &amp;&amp; V_BreakVolumeCallbacks) {
--- 1921,1933 ----
       * for all of that to happen, but if it does, probably the right
       * fix is for the server to allow the return of readonly volumes
       * that it doesn't think are really checked out. */
+ #ifdef FSSYNC_BUILD_CLIENT
      if (programType == volumeUtility &amp;&amp; vp == NULL &amp;&amp;
  	mode != V_SECRETLY &amp;&amp; mode != V_PEEK) {
! 	FSYNC_VolOp(iheader.id, partition, FSYNC_VOL_ON, 0, NULL);
!     } else 
! #endif
!     if (programType == fileServer &amp;&amp; vp) {
  	V_needsCallback(vp) = 0;
  #ifdef	notdef
  	if (VInit &gt;= 2 &amp;&amp; V_BreakVolumeCallbacks) {
***************
*** 795,801 ****
  	    (*V_BreakVolumeCallbacks) (V_id(vp));
  	}
  #endif
! 	VUpdateVolume_r(ec, vp);
  	if (*ec) {
  	    Log("VAttachVolume: Error updating volume\n");
  	    if (vp)
--- 1935,1941 ----
  	    (*V_BreakVolumeCallbacks) (V_id(vp));
  	}
  #endif
! 	VUpdateVolume_r(ec, vp, 0);
  	if (*ec) {
  	    Log("VAttachVolume: Error updating volume\n");
  	    if (vp)
***************
*** 803,809 ****
  	    goto done;
  	}
  	if (VolumeWriteable(vp) &amp;&amp; V_dontSalvage(vp) == 0) {
! 	    /* This is a hack: by temporarily settint the incore
  	     * dontSalvage flag ON, the volume will be put back on the
  	     * Update list (with dontSalvage OFF again).  It will then
  	     * come back in N minutes with DONT_SALVAGE eventually
--- 1943,1950 ----
  	    goto done;
  	}
  	if (VolumeWriteable(vp) &amp;&amp; V_dontSalvage(vp) == 0) {
! #ifndef AFS_DEMAND_ATTACH_FS
! 	    /* This is a hack: by temporarily setting the incore
  	     * dontSalvage flag ON, the volume will be put back on the
  	     * Update list (with dontSalvage OFF again).  It will then
  	     * come back in N minutes with DONT_SALVAGE eventually
***************
*** 812,817 ****
--- 1953,1959 ----
  	     * offline without DONT SALVAGE having been set also
  	     * eventually get it set */
  	    V_dontSalvage(vp) = DONT_SALVAGE;
+ #endif /* !AFS_DEMAND_ATTACH_FS */
  	    VAddToVolumeUpdateList_r(ec, vp);
  	    if (*ec) {
  		Log("VAttachVolume: Error adding volume to update list\n");
***************
*** 828,852 ****
      if (programType == volumeUtility) {
  	VUnlockPartition_r(partition);
      }
!     if (*ec)
  	return NULL;
!     else
  	return vp;
  }
  
! private Volume *
! attach2(Error * ec, char *path, register struct VolumeHeader * header,
! 	struct DiskPartition * partp, int isbusy)
  {
!     register Volume *vp;
  
!     VOL_UNLOCK;
  
!     vp = (Volume *) calloc(1, sizeof(Volume));
      assert(vp != NULL);
      vp-&gt;specialStatus = (byte) (isbusy ? VBUSY : 0);
-     vp-&gt;device = partp-&gt;device;
-     vp-&gt;partition = partp;
      IH_INIT(vp-&gt;vnodeIndex[vLarge].handle, partp-&gt;device, header-&gt;parent,
  	    header-&gt;largeVnodeIndex);
      IH_INIT(vp-&gt;vnodeIndex[vSmall].handle, partp-&gt;device, header-&gt;parent,
--- 1970,2165 ----
      if (programType == volumeUtility) {
  	VUnlockPartition_r(partition);
      }
!     if (*ec) {
! #ifdef AFS_DEMAND_ATTACH_FS
! 	if (vp) {
! 	    V_attachState(vp) = VOL_STATE_ERROR;
! 	    assert(pthread_cond_broadcast(&amp;V_attachCV(vp)) == 0);
! 	}
! #endif /* AFS_DEMAND_ATTACH_FS */
  	return NULL;
!     } else {
  	return vp;
+     }
  }
  
! #ifdef AFS_DEMAND_ATTACH_FS
! /* VAttachVolumeByVp_r
!  *
!  * finish attaching a volume that is
!  * in a less than fully attached state
!  */
! /* caller MUST hold a ref count on vp */
! static Volume *
! VAttachVolumeByVp_r(Error * ec, Volume * vp, int mode)
  {
!     char name[VMAXPATHLEN];
!     int fd, n, reserve = 0;
!     struct afs_stat status;
!     struct VolumeDiskHeader diskHeader;
!     struct VolumeHeader iheader;
!     struct DiskPartition *partp;
!     char path[64];
!     int isbusy = 0;
!     VolId volumeId;
!     Volume * nvp;
!     VolumeStats stats_save;
!     *ec = 0;
  
!     /* volume utility should never call AttachByVp */
!     assert(programType == fileServer);
!    
!     volumeId = vp-&gt;hashid;
!     partp = vp-&gt;partition;
!     VolumeExternalName_r(volumeId, name, sizeof(name));
! 
! 
!     /* if another thread is performing a blocking op, wait */
!     VWaitExclusiveState_r(vp);
! 
!     memcpy(&amp;stats_save, &amp;vp-&gt;stats, sizeof(VolumeStats));
! 
!     /* if it's already attached, see if we can return it */
!     if (V_attachState(vp) == VOL_STATE_ATTACHED) {
! 	VGetVolumeByVp_r(ec, vp);
! 	if (V_inUse(vp)) {
! 	    return vp;
! 	} else {
! 	    if (vp-&gt;specialStatus == VBUSY)
! 		isbusy = 1;
! 	    VDetachVolume_r(ec, vp);
! 	    if (*ec) {
! 		Log("VAttachVolume: Error detaching volume (%s)\n", name);
! 	    }
! 	    vp = NULL;
! 	}
!     }
  
!     /* pre-attach volume if it hasn't been done yet */
!     if (!vp || 
! 	(V_attachState(vp) == VOL_STATE_UNATTACHED) ||
! 	(V_attachState(vp) == VOL_STATE_ERROR)) {
! 	nvp = VPreAttachVolumeById_r(ec, partp, vp, volumeId);
! 	if (*ec) {
! 	    return NULL;
! 	}
! 	if (nvp != vp) {
! 	    reserve = 1;
! 	    VCreateReservation_r(nvp);
! 	    vp = nvp;
! 	}
!     }
!     
      assert(vp != NULL);
+     VChangeState_r(vp, VOL_STATE_ATTACHING);
+ 
+     /* restore monotonically increasing stats */
+     memcpy(&amp;vp-&gt;stats, &amp;stats_save, sizeof(VolumeStats));
+ 
+     *ec = 0;
+ 
+ 
+     /* compute path to disk header, 
+      * read in header, 
+      * and verify magic and version stamps */
+     strcpy(path, VPartitionPath(partp));
+ 
+     VOL_UNLOCK;
+ 
+     strcat(path, "/");
+     strcat(path, name);
+     if ((fd = afs_open(path, O_RDONLY)) == -1 || afs_fstat(fd, &amp;status) == -1) {
+ 	Log("VAttachVolume: Failed to open %s (errno %d)\n", path, errno);
+ 	if (fd &gt; -1)
+ 	    close(fd);
+ 	*ec = VNOVOL;
+ 	VOL_LOCK;
+ 	goto done;
+     }
+     n = read(fd, &amp;diskHeader, sizeof(diskHeader));
+     close(fd);
+     if (n != sizeof(diskHeader)
+ 	|| diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
+ 	Log("VAttachVolume: Error reading volume header %s\n", path);
+ 	*ec = VSALVAGE;
+ 	VOL_LOCK;
+ 	goto done;
+     }
+     if (diskHeader.stamp.version != VOLUMEHEADERVERSION) {
+ 	Log("VAttachVolume: Volume %s, version number is incorrect; volume needs salvaged\n", path);
+ 	*ec = VSALVAGE;
+ 	VOL_LOCK;
+ 	goto done;
+     }
+ 
+     /* convert on-disk header format to in-memory header format */
+     DiskToVolumeHeader(&amp;iheader, &amp;diskHeader);
+ 
+     /* do volume attach
+      *
+      * NOTE: attach2 is entered without any locks, and returns
+      * with vol_glock_mutex held */
+     vp = attach2(ec, volumeId, path, &amp;iheader, partp, vp, isbusy, mode);
+ 
+     if (*ec || vp == NULL) {
+ 	goto done;
+     }
+ 
+     V_needsCallback(vp) = 0;
+     VUpdateVolume_r(ec, vp, 0);
+     if (*ec) {
+ 	Log("VAttachVolume: Error updating volume %u\n", vp-&gt;hashid);
+ 	VPutVolume_r(vp);
+ 	goto done;
+     }
+     if (VolumeWriteable(vp) &amp;&amp; V_dontSalvage(vp) == 0) {
+ #ifndef AFS_DEMAND_ATTACH_FS
+ 	/* This is a hack: by temporarily setting the incore
+ 	 * dontSalvage flag ON, the volume will be put back on the
+ 	 * Update list (with dontSalvage OFF again).  It will then
+ 	 * come back in N minutes with DONT_SALVAGE eventually
+ 	 * set.  This is the way that volumes that have never had
+ 	 * it set get it set; or that volumes that have been
+ 	 * offline without DONT SALVAGE having been set also
+ 	 * eventually get it set */
+ 	V_dontSalvage(vp) = DONT_SALVAGE;
+ #endif /* !AFS_DEMAND_ATTACH_FS */
+ 	VAddToVolumeUpdateList_r(ec, vp);
+ 	if (*ec) {
+ 	    Log("VAttachVolume: Error adding volume %u to update list\n", vp-&gt;hashid);
+ 	    if (vp)
+ 		VPutVolume_r(vp);
+ 	    goto done;
+ 	}
+     }
+     if (LogLevel)
+ 	Log("VOnline:  volume %u (%s) attached and online\n", V_id(vp),
+ 	    V_name(vp));
+   done:
+     if (reserve) {
+ 	VCancelReservation_r(nvp);
+ 	reserve = 0;
+     }
+     if (*ec &amp;&amp; (*ec != VOFFLINE) &amp;&amp; (*ec != VSALVAGE)) {
+ 	if (vp &amp;&amp; !IsErrorState(V_attachState(vp))) {
+ 	    VChangeState_r(vp, VOL_STATE_ERROR);
+ 	}
+ 	return NULL;
+     } else {
+ 	return vp;
+     }
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ /*
+  * called without any locks held
+  * returns with vol_glock_mutex held
+  */
+ private Volume * 
+ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * header,
+ 	struct DiskPartition * partp, register Volume * vp, int isbusy, int mode)
+ {
      vp-&gt;specialStatus = (byte) (isbusy ? VBUSY : 0);
      IH_INIT(vp-&gt;vnodeIndex[vLarge].handle, partp-&gt;device, header-&gt;parent,
  	    header-&gt;largeVnodeIndex);
      IH_INIT(vp-&gt;vnodeIndex[vSmall].handle, partp-&gt;device, header-&gt;parent,
***************
*** 857,864 ****
--- 2170,2184 ----
      vp-&gt;shuttingDown = 0;
      vp-&gt;goingOffline = 0;
      vp-&gt;nUsers = 1;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     vp-&gt;stats.last_attach = FT_ApproxTime();
+     vp-&gt;stats.attaches++;
+ #endif
  
      VOL_LOCK;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     IncUInt64(&amp;VStats.attaches);
+ #endif
      vp-&gt;cacheCheck = ++VolumeCacheCheck;
      /* just in case this ever rolls over */
      if (!vp-&gt;cacheCheck)
***************
*** 866,878 ****
--- 2186,2259 ----
      GetVolumeHeader(vp);
      VOL_UNLOCK;
  
+ #if defined(AFS_DEMAND_ATTACH_FS) &amp;&amp; defined(FSSYNC_BUILD_CLIENT)
+     /* demand attach changes the V_PEEK mechanism
+      *
+      * we can now suck the current disk data structure over
+      * the fssync interface without going to disk
+      *
+      * (technically, we don't need to restrict this feature
+      *  to demand attach fileservers.  However, I'm trying
+      *  to limit the number of common code changes)
+      */
+     if (programType != fileServer &amp;&amp; mode == V_PEEK) {
+ 	SYNC_response res;
+ 	res.payload.len = sizeof(VolumeDiskData);
+ 	res.payload.buf = &amp;vp-&gt;header-&gt;diskstuff;
+ 
+ 	if (FSYNC_VolOp(volumeId,
+ 			VPartitionPath(partp),
+ 			FSYNC_VOL_QUERY_HDR,
+ 			FSYNC_WHATEVER,
+ 			&amp;res) == SYNC_OK) {
+ 	    goto disk_header_loaded;
+ 	}
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS &amp;&amp; FSSYNC_BUILD_CLIENT */
      (void)ReadHeader(ec, V_diskDataHandle(vp), (char *)&amp;V_disk(vp),
  		     sizeof(V_disk(vp)), VOLUMEINFOMAGIC, VOLUMEINFOVERSION);
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+     /* update stats */
      VOL_LOCK;
+     IncUInt64(&amp;VStats.hdr_loads);
+     IncUInt64(&amp;vp-&gt;stats.hdr_loads);
+     VOL_UNLOCK;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+     
      if (*ec) {
  	Log("VAttachVolume: Error reading diskDataHandle vol header %s; error=%u\n", path, *ec);
      }
+ 
+  disk_header_loaded:
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     if (!*ec) {
+ 
+ 	/* check for pending volume operations */
+ 	if (vp-&gt;pending_vol_op) {
+ 	    /* see if the pending volume op requires exclusive access */
+ 	    if (!VVolOpLeaveOnline_r(vp, vp-&gt;pending_vol_op)) {
+ 		/* mark the volume down */
+ 		*ec = VOFFLINE;
+ 		VChangeState_r(vp, VOL_STATE_UNATTACHED);
+ 		if (V_offlineMessage(vp)[0] == '\0')
+ 		    strlcpy(V_offlineMessage(vp),
+ 			    "A volume utility is running.", 
+ 			    sizeof(V_offlineMessage(vp)));
+ 		V_offlineMessage(vp)[sizeof(V_offlineMessage(vp)) - 1] = '\0';
+ 
+ 		/* check to see if we should set the specialStatus flag */
+ 		if (VVolOpSetVBusy_r(vp, vp-&gt;pending_vol_op)) {
+ 		    vp-&gt;specialStatus = VBUSY;
+ 		}
+ 	    }
+ 	}
+ 
+ 	V_attachFlags(vp) |= VOL_HDR_LOADED;
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
      if (!*ec) {
  	struct IndexFileHeader iHead;
  
***************
*** 887,951 ****
  	    V_stat_initialized(vp) = 1;
  	}
  #endif /* OPENAFS_VOL_STATS */
! 	VOL_UNLOCK;
  	(void)ReadHeader(ec, vp-&gt;vnodeIndex[vSmall].handle,
  			 (char *)&amp;iHead, sizeof(iHead),
  			 SMALLINDEXMAGIC, SMALLINDEXVERSION);
! 	VOL_LOCK;
  	if (*ec) {
  	    Log("VAttachVolume: Error reading smallVnode vol header %s; error=%u\n", path, *ec);
  	}
      }
      if (!*ec) {
  	struct IndexFileHeader iHead;
! 	VOL_UNLOCK;
  	(void)ReadHeader(ec, vp-&gt;vnodeIndex[vLarge].handle,
  			 (char *)&amp;iHead, sizeof(iHead),
  			 LARGEINDEXMAGIC, LARGEINDEXVERSION);
! 	VOL_LOCK;
  	if (*ec) {
  	    Log("VAttachVolume: Error reading largeVnode vol header %s; error=%u\n", path, *ec);
  	}
      }
  #ifdef AFS_NAMEI_ENV
      if (!*ec) {
  	struct versionStamp stamp;
! 	VOL_UNLOCK;
  	(void)ReadHeader(ec, V_linkHandle(vp), (char *)&amp;stamp,
  			 sizeof(stamp), LINKTABLEMAGIC, LINKTABLEVERSION);
! 	VOL_LOCK;
  	if (*ec) {
  	    Log("VAttachVolume: Error reading namei vol header %s; error=%u\n", path, *ec);
  	}
      }
! #endif
      if (*ec) {
  	Log("VAttachVolume: Error attaching volume %s; volume needs salvage; error=%u\n", path, *ec);
  	FreeVolume(vp);
  	return NULL;
      }
      if (V_needsSalvaged(vp)) {
  	if (vp-&gt;specialStatus)
  	    vp-&gt;specialStatus = 0;
! 	Log("VAttachVolume: volume salvage flag is ON for %s; volume needs salvage\n", path);
! 	*ec = VSALVAGE;
  	FreeVolume(vp);
  	return NULL;
      }
      if (programType == fileServer) {
  #ifndef FAST_RESTART
  	if (V_inUse(vp) &amp;&amp; VolumeWriteable(vp)) {
  	    if (!V_needsSalvaged(vp)) {
  		V_needsSalvaged(vp) = 1;
! 		VUpdateVolume_r(ec, vp);
  	    }
! 	    FreeVolume(vp);
  	    Log("VAttachVolume: volume %s needs to be salvaged; not attached.\n", path);
  	    *ec = VSALVAGE;
  	    return NULL;
  	}
  #endif /* FAST_RESTART */
  	if (V_destroyMe(vp) == DESTROY_ME) {
  	    FreeVolume(vp);
  	    Log("VAttachVolume: volume %s is junk; it should be destroyed at next salvage\n", path);
  	    *ec = VNOVOL;
--- 2268,2384 ----
  	    V_stat_initialized(vp) = 1;
  	}
  #endif /* OPENAFS_VOL_STATS */
! 
  	(void)ReadHeader(ec, vp-&gt;vnodeIndex[vSmall].handle,
  			 (char *)&amp;iHead, sizeof(iHead),
  			 SMALLINDEXMAGIC, SMALLINDEXVERSION);
! 
  	if (*ec) {
  	    Log("VAttachVolume: Error reading smallVnode vol header %s; error=%u\n", path, *ec);
  	}
      }
+ 
      if (!*ec) {
  	struct IndexFileHeader iHead;
! 
  	(void)ReadHeader(ec, vp-&gt;vnodeIndex[vLarge].handle,
  			 (char *)&amp;iHead, sizeof(iHead),
  			 LARGEINDEXMAGIC, LARGEINDEXVERSION);
! 
  	if (*ec) {
  	    Log("VAttachVolume: Error reading largeVnode vol header %s; error=%u\n", path, *ec);
  	}
      }
+ 
  #ifdef AFS_NAMEI_ENV
      if (!*ec) {
  	struct versionStamp stamp;
! 
  	(void)ReadHeader(ec, V_linkHandle(vp), (char *)&amp;stamp,
  			 sizeof(stamp), LINKTABLEMAGIC, LINKTABLEVERSION);
! 
  	if (*ec) {
  	    Log("VAttachVolume: Error reading namei vol header %s; error=%u\n", path, *ec);
  	}
      }
! #endif /* AFS_NAMEI_ENV */
! 
! #if defined(AFS_DEMAND_ATTACH_FS)
!     if (*ec &amp;&amp; ((*ec != VOFFLINE) || (V_attachState(vp) != VOL_STATE_UNATTACHED))) {
!         VOL_LOCK;
! 	if (programType == fileServer) {
! 	    VRequestSalvage_r(vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
! 	    vp-&gt;nUsers = 0;
! 	    *ec = VSALVAGING;
! 	} else {
! 	    Log("VAttachVolume: Error attaching volume %s; volume needs salvage; error=%u\n", path, *ec);
! 	    FreeVolume(vp);
! 	    *ec = VSALVAGE;
! 	}
! 	return NULL;
!     } else if (*ec) {
! 	/* volume operation in progress */
! 	VOL_LOCK;
! 	return NULL;
!     }
! #else /* AFS_DEMAND_ATTACH_FS */
      if (*ec) {
  	Log("VAttachVolume: Error attaching volume %s; volume needs salvage; error=%u\n", path, *ec);
+         VOL_LOCK;
  	FreeVolume(vp);
  	return NULL;
      }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
      if (V_needsSalvaged(vp)) {
  	if (vp-&gt;specialStatus)
  	    vp-&gt;specialStatus = 0;
!         VOL_LOCK;
! #if defined(AFS_DEMAND_ATTACH_FS)
! 	if (programType == fileServer) {
! 	    VRequestSalvage_r(vp, SALVSYNC_NEEDED, VOL_SALVAGE_INVALIDATE_HEADER);
! 	    vp-&gt;nUsers = 0;
! 	    *ec = VSALVAGING;
! 	} else {
! 	    Log("VAttachVolume: volume salvage flag is ON for %s; volume needs salvage\n", path);
! 	    FreeVolume(vp);
! 	    *ec = VSALVAGE;
! 	}
! #else /* AFS_DEMAND_ATTACH_FS */
  	FreeVolume(vp);
+ 	*ec = VSALVAGE;
+ #endif /* AFS_DEMAND_ATTACH_FS */
  	return NULL;
      }
+ 
+     VOL_LOCK;
      if (programType == fileServer) {
  #ifndef FAST_RESTART
  	if (V_inUse(vp) &amp;&amp; VolumeWriteable(vp)) {
  	    if (!V_needsSalvaged(vp)) {
  		V_needsSalvaged(vp) = 1;
! 		VUpdateVolume_r(ec, vp, 0);
  	    }
! #if defined(AFS_DEMAND_ATTACH_FS)
! 	    VRequestSalvage_r(vp, SALVSYNC_NEEDED, VOL_SALVAGE_INVALIDATE_HEADER);
! 	    vp-&gt;nUsers = 0;
! 	    *ec = VSALVAGING;
! #else /* AFS_DEMAND_ATTACH_FS */
  	    Log("VAttachVolume: volume %s needs to be salvaged; not attached.\n", path);
+ 	    FreeVolume(vp);
  	    *ec = VSALVAGE;
+ #endif /* AFS_DEMAND_ATTACH_FS */
  	    return NULL;
  	}
  #endif /* FAST_RESTART */
+ 
  	if (V_destroyMe(vp) == DESTROY_ME) {
+ #if defined(AFS_DEMAND_ATTACH_FS)
+ 	    /* schedule a salvage so the volume goes away on disk */
+ 	    VRequestSalvage_r(vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
+ 	    VChangeState_r(vp, VOL_STATE_ERROR);
+ 	    vp-&gt;nUsers = 0;
+ #endif /* AFS_DEMAND_ATTACH_FS */
  	    FreeVolume(vp);
  	    Log("VAttachVolume: volume %s is junk; it should be destroyed at next salvage\n", path);
  	    *ec = VNOVOL;
***************
*** 953,970 ****
  	}
      }
  
-     AddVolumeToHashTable(vp, V_id(vp));
      vp-&gt;nextVnodeUnique = V_uniquifier(vp);
      vp-&gt;vnodeIndex[vSmall].bitmap = vp-&gt;vnodeIndex[vLarge].bitmap = NULL;
  #ifndef BITMAP_LATER
      if (programType == fileServer &amp;&amp; VolumeWriteable(vp)) {
  	int i;
  	for (i = 0; i &lt; nVNODECLASSES; i++) {
! 	    VOL_UNLOCK;
! 	    GetBitmap(ec, vp, i);
! 	    VOL_LOCK;
  	    if (*ec) {
  		FreeVolume(vp);
  		Log("VAttachVolume: error getting bitmap for volume (%s)\n",
  		    path);
  		return NULL;
--- 2386,2406 ----
  	}
      }
  
      vp-&gt;nextVnodeUnique = V_uniquifier(vp);
      vp-&gt;vnodeIndex[vSmall].bitmap = vp-&gt;vnodeIndex[vLarge].bitmap = NULL;
  #ifndef BITMAP_LATER
      if (programType == fileServer &amp;&amp; VolumeWriteable(vp)) {
  	int i;
  	for (i = 0; i &lt; nVNODECLASSES; i++) {
! 	    VGetBitmap_r(ec, vp, i);
  	    if (*ec) {
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 		VRequestSalvage_r(vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
+ 		vp-&gt;nUsers = 0;
+ 		*ec = VSALVAGING;
+ #else /* AFS_DEMAND_ATTACH_FS */
  		FreeVolume(vp);
+ #endif /* AFS_DEMAND_ATTACH_FS */
  		Log("VAttachVolume: error getting bitmap for volume (%s)\n",
  		    path);
  		return NULL;
***************
*** 982,987 ****
--- 2418,2429 ----
  	}
      }
  
+     AddVolumeToHashTable(vp, V_id(vp));
+ #ifdef AFS_DEMAND_ATTACH_FS
+     AddVolumeToVByPList_r(vp);
+     VLRU_Add_r(vp);
+     VChangeState_r(vp, VOL_STATE_ATTACHED);
+ #endif
      return vp;
  }
  
***************
*** 994,1004 ****
  VAttachVolume(Error * ec, VolumeId volumeId, int mode)
  {
      Volume *retVal;
-     VATTACH_LOCK;
      VOL_LOCK;
      retVal = VAttachVolume_r(ec, volumeId, mode);
      VOL_UNLOCK;
-     VATTACH_UNLOCK;
      return retVal;
  }
  
--- 2436,2444 ----
***************
*** 1028,1048 ****
   * we still guarantee we won't context swap, but the ref count won't be
   * incremented (otherwise we'd violate the invariant).
   */
  static int
  VHold_r(register Volume * vp)
  {
      Error error;
  
!     if (vp-&gt;nUsers == 0 &amp;&amp; !GetVolumeHeader(vp)) {
! 	VolumeReplacements++;
! 	ReadHeader(&amp;error, V_diskDataHandle(vp), (char *)&amp;V_disk(vp),
! 		   sizeof(V_disk(vp)), VOLUMEINFOMAGIC, VOLUMEINFOVERSION);
! 	if (error)
! 	    return error;
      }
      vp-&gt;nUsers++;
      return 0;
  }
  
  static int
  VHold(register Volume * vp)
--- 2468,2506 ----
   * we still guarantee we won't context swap, but the ref count won't be
   * incremented (otherwise we'd violate the invariant).
   */
+ /* NOTE: with the demand attach fileserver extensions, the global lock
+  * is dropped within VHold */
+ #ifdef AFS_DEMAND_ATTACH_FS
  static int
  VHold_r(register Volume * vp)
  {
      Error error;
  
!     VCreateReservation_r(vp);
!     VWaitExclusiveState_r(vp);
! 
!     LoadVolumeHeader(&amp;error, vp);
!     if (error) {
! 	VCancelReservation_r(vp);
! 	return error;
      }
      vp-&gt;nUsers++;
+     VCancelReservation_r(vp);
+     return 0;
+ }
+ #else /* AFS_DEMAND_ATTACH_FS */
+ static int
+ VHold_r(register Volume * vp)
+ {
+     Error error;
+ 
+     LoadVolumeHeader(&amp;error, vp);
+     if (error)
+ 	return error;
+     vp-&gt;nUsers++;
      return 0;
  }
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
  static int
  VHold(register Volume * vp)
***************
*** 1054,1112 ****
      return retVal;
  }
  
- void
- VTakeOffline_r(register Volume * vp)
- {
-     assert(vp-&gt;nUsers &gt; 0);
-     assert(programType == fileServer);
-     vp-&gt;goingOffline = 1;
-     V_needsSalvaged(vp) = 1;
- }
  
! void
! VTakeOffline(register Volume * vp)
! {
!     VOL_LOCK;
!     VTakeOffline_r(vp);
!     VOL_UNLOCK;
! }
  
  void
  VPutVolume_r(register Volume * vp)
  {
      assert(--vp-&gt;nUsers &gt;= 0);
      if (vp-&gt;nUsers == 0) {
  	ReleaseVolumeHeader(vp-&gt;header);
! 	if (vp-&gt;goingOffline) {
! 	    Error error;
! 	    assert(programType == fileServer);
! 	    vp-&gt;goingOffline = 0;
! 	    V_inUse(vp) = 0;
! 	    VUpdateVolume_r(&amp;error, vp);
! 	    VCloseVolumeHandles_r(vp);
! 	    if (LogLevel) {
! 		Log("VOffline: Volume %u (%s) is now offline", V_id(vp),
! 		    V_name(vp));
! 		if (V_offlineMessage(vp)[0])
! 		    Log(" (%s)", V_offlineMessage(vp));
! 		Log("\n");
! 	    }
! #ifdef AFS_PTHREAD_ENV
! 	    assert(pthread_cond_broadcast(&amp;vol_put_volume_cond) == 0);
! #else /* AFS_PTHREAD_ENV */
! 	    LWP_NoYieldSignal(VPutVolume);
! #endif /* AFS_PTHREAD_ENV */
! 	}
! 	if (vp-&gt;shuttingDown) {
! 	    VReleaseVolumeHandles_r(vp);
! 	    FreeVolume(vp);
! 	    if (programType == fileServer)
! #ifdef AFS_PTHREAD_ENV
! 		assert(pthread_cond_broadcast(&amp;vol_put_volume_cond) == 0);
! #else /* AFS_PTHREAD_ENV */
! 		LWP_NoYieldSignal(VPutVolume);
! #endif /* AFS_PTHREAD_ENV */
  	}
      }
  }
  
--- 2512,2537 ----
      return retVal;
  }
  
  
! /***************************************************/
! /* get and put volume routines                     */
! /***************************************************/
  
  void
  VPutVolume_r(register Volume * vp)
  {
      assert(--vp-&gt;nUsers &gt;= 0);
      if (vp-&gt;nUsers == 0) {
+ 	VCheckOffline(vp);
  	ReleaseVolumeHeader(vp-&gt;header);
! #ifdef AFS_DEMAND_ATTACH_FS
! 	if (!VCheckDetach(vp)) {
! 	    VCheckSalvage(vp);
! 	    VCheckFree(vp);
  	}
+ #else /* AFS_DEMAND_ATTACH_FS */
+ 	VCheckDetach(vp);
+ #endif /* AFS_DEMAND_ATTACH_FS */
      }
  }
  
***************
*** 1118,1132 ****
      VOL_UNLOCK;
  }
  
  /* Get a pointer to an attached volume.  The pointer is returned regardless
     of whether or not the volume is in service or on/off line.  An error
     code, however, is returned with an indication of the volume's status */
  Volume *
! VGetVolume(Error * ec, VolId volumeId)
  {
      Volume *retVal;
      VOL_LOCK;
!     retVal = VGetVolume_r(ec, volumeId);
      VOL_UNLOCK;
      return retVal;
  }
--- 2543,2558 ----
      VOL_UNLOCK;
  }
  
+ 
  /* Get a pointer to an attached volume.  The pointer is returned regardless
     of whether or not the volume is in service or on/off line.  An error
     code, however, is returned with an indication of the volume's status */
  Volume *
! VGetVolume(Error * ec, Error * client_ec, VolId volumeId)
  {
      Volume *retVal;
      VOL_LOCK;
!     retVal = GetVolume(ec, client_ec, volumeId, NULL, 0);
      VOL_UNLOCK;
      return retVal;
  }
***************
*** 1134,1155 ****
  Volume *
  VGetVolume_r(Error * ec, VolId volumeId)
  {
!     Volume *vp;
!     unsigned short V0 = 0, V1 = 0, V2 = 0, V3 = 0, V4 = 0, V5 = 0, V6 =
  	0, V7 = 0, V8 = 0, V9 = 0;
      unsigned short V10 = 0, V11 = 0, V12 = 0, V13 = 0, V14 = 0, V15 = 0;
  
      for (;;) {
  	*ec = 0;
! 	V0++;
! 	for (vp = VolumeHashTable[VOLUME_HASH(volumeId)];
! 	     vp &amp;&amp; vp-&gt;hashid != volumeId; vp = vp-&gt;hashNext)
! 	    Vlooks++;
  
  	if (!vp) {
! 	    V1++;
  	    if (VInit &lt; 2) {
! 		V2++;
  		/* Until we have reached an initialization level of 2
  		 * we don't know whether this volume exists or not.
  		 * We can't sleep and retry later because before a volume
--- 2560,2628 ----
  Volume *
  VGetVolume_r(Error * ec, VolId volumeId)
  {
!     return GetVolume(ec, NULL, volumeId, NULL, 0);
! }
! 
! /* try to get a volume we've previously looked up */
! /* for demand attach fs, caller MUST NOT hold a ref count on vp */
! Volume * 
! VGetVolumeByVp_r(Error * ec, Volume * vp)
! {
!     return GetVolume(ec, NULL, vp-&gt;hashid, vp, 0);
! }
! 
! /* private interface for getting a volume handle
!  * volumeId must be provided.
!  * hint is an optional parameter to speed up hash lookups
!  * flags is not used at this time
!  */
! /* for demand attach fs, caller MUST NOT hold a ref count on hint */
! static Volume *
! GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint, int flags)
! {
!     Volume *vp = hint;
!     /* pull this profiling/debugging code out of regular builds */
! #ifdef notdef
! #define VGET_CTR_INC(x) x++
!     unsigned short V0 = 0, V1 = 0, V2 = 0, V3 = 0, V5 = 0, V6 =
  	0, V7 = 0, V8 = 0, V9 = 0;
      unsigned short V10 = 0, V11 = 0, V12 = 0, V13 = 0, V14 = 0, V15 = 0;
+ #else
+ #define VGET_CTR_INC(x)
+ #endif
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     Volume *avp, * rvp = hint;
+ 
+     if (rvp) {
+ 	VCreateReservation_r(rvp);
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
      for (;;) {
  	*ec = 0;
! 	if (client_ec)
! 	    *client_ec = 0;
! 	VGET_CTR_INC(V0);
! 
! 	vp = VLookupVolume_r(ec, volumeId, vp);
! 	if (*ec) {
! 	    vp = NULL;
! 	    break;
! 	}
! 
! #ifdef AFS_DEMAND_ATTACH_FS
! 	if (rvp &amp;&amp; (rvp != vp)) {
! 	    /* break reservation on old vp */
! 	    VCancelReservation_r(rvp);
! 	    rvp = NULL;
! 	}
! #endif /* AFS_DEMAND_ATTACH_FS */
  
  	if (!vp) {
! 	    VGET_CTR_INC(V1);
  	    if (VInit &lt; 2) {
! 		VGET_CTR_INC(V2);
  		/* Until we have reached an initialization level of 2
  		 * we don't know whether this volume exists or not.
  		 * We can't sleep and retry later because before a volume
***************
*** 1164,1262 ****
  	    break;
  	}
  
! 	V3++;
! 	VolumeGets++;
! 	if (vp-&gt;nUsers == 0 &amp;&amp; !GetVolumeHeader(vp)) {
! 	    V5++;
! 	    VolumeReplacements++;
! 	    ReadHeader(ec, V_diskDataHandle(vp), (char *)&amp;V_disk(vp),
! 		       sizeof(V_disk(vp)), VOLUMEINFOMAGIC,
! 		       VOLUMEINFOVERSION);
  	    if (*ec) {
! 		V6++;
! 		/* Only log the error if it was a totally unexpected error.  Simply
! 		 * a missing inode is likely to be caused by the volume being deleted */
! 		if (errno != ENXIO || LogLevel)
! 		    Log("Volume %u: couldn't reread volume header\n",
! 			vp-&gt;hashid);
  		FreeVolume(vp);
  		vp = NULL;
- 		break;
  	    }
  	}
! 	V7++;
  	if (vp-&gt;shuttingDown) {
! 	    V8++;
  	    *ec = VNOVOL;
  	    vp = NULL;
  	    break;
  	}
  	if (programType == fileServer) {
! 	    V9++;
  	    if (vp-&gt;goingOffline) {
! 		V10++;
! #ifdef AFS_PTHREAD_ENV
! 		pthread_cond_wait(&amp;vol_put_volume_cond, &amp;vol_glock_mutex);
  #else /* AFS_PTHREAD_ENV */
  		LWP_WaitProcess(VPutVolume);
  #endif /* AFS_PTHREAD_ENV */
  		continue;
  	    }
  	    if (vp-&gt;specialStatus) {
! 		V11++;
  		*ec = vp-&gt;specialStatus;
  	    } else if (V_inService(vp) == 0 || V_blessed(vp) == 0) {
! 		V12++;
  		*ec = VNOVOL;
  	    } else if (V_inUse(vp) == 0) {
! 		V13++;
  		*ec = VOFFLINE;
  	    } else {
! 		V14++;
  	    }
  	}
  	break;
      }
!     V15++;
      /* if no error, bump nUsers */
!     if (vp)
  	vp-&gt;nUsers++;
  
      assert(vp || *ec);
      return vp;
  }
  
  
! /* For both VForceOffline and VOffline, we close all relevant handles.
!  * For VOffline, if we re-attach the volume, the files may possible be
!  * different than before. 
!  */
! static void
! VReleaseVolumeHandles_r(Volume * vp)
  {
!     DFlushVolume(V_id(vp));
!     VReleaseVnodeFiles_r(vp);
  
!     /* Too time consuming and unnecessary for the volserver */
!     if (programType != volumeUtility) {
! 	IH_CONDSYNC(vp-&gt;vnodeIndex[vLarge].handle);
! 	IH_CONDSYNC(vp-&gt;vnodeIndex[vSmall].handle);
! 	IH_CONDSYNC(vp-&gt;diskDataHandle);
! #ifdef AFS_NT40_ENV
! 	IH_CONDSYNC(vp-&gt;linkHandle);
! #endif /* AFS_NT40_ENV */
!     }
  
!     IH_RELEASE(vp-&gt;vnodeIndex[vLarge].handle);
!     IH_RELEASE(vp-&gt;vnodeIndex[vSmall].handle);
!     IH_RELEASE(vp-&gt;diskDataHandle);
!     IH_RELEASE(vp-&gt;linkHandle);
  }
  
  /* Force the volume offline, set the salvage flag.  No further references to
   * the volume through the volume package will be honored. */
  void
! VForceOffline_r(Volume * vp)
  {
      Error error;
      if (!V_inUse(vp))
--- 2637,2891 ----
  	    break;
  	}
  
! 	VGET_CTR_INC(V3);
! 	IncUInt64(&amp;VStats.hdr_gets);
! 	
! #ifdef AFS_DEMAND_ATTACH_FS
! 	/* block if someone else is performing an exclusive op on this volume */
! 	if (rvp != vp) {
! 	    rvp = vp;
! 	    VCreateReservation_r(rvp);
! 	}
! 	VWaitExclusiveState_r(vp);
! 
! 	/* short circuit with VNOVOL in the following circumstances:
! 	 *
! 	 *   VOL_STATE_ERROR
! 	 *   VOL_STATE_SHUTTING_DOWN
! 	 */
! 	if ((V_attachState(vp) == VOL_STATE_ERROR) ||
! 	    (V_attachState(vp) == VOL_STATE_SHUTTING_DOWN)) {
! 	    *ec = VNOVOL;
! 	    vp = NULL;
! 	    break;
! 	}
! 
! 	/* allowable states:
! 	 *   UNATTACHED
! 	 *   PREATTACHED
! 	 *   ATTACHED
! 	 *   GOING_OFFLINE
! 	 *   SALVAGING
! 	 */
! 
! 	if (vp-&gt;salvage.requested) {
! 	    VUpdateSalvagePriority_r(vp);
! 	}
! 
! 	if (V_attachState(vp) == VOL_STATE_PREATTACHED) {
! 	    avp = VAttachVolumeByVp_r(ec, vp, 0);
! 	    if (avp) {
! 		if (vp != avp) {
! 		    /* VAttachVolumeByVp_r can return a pointer
! 		     * != the vp passed to it under certain
! 		     * conditions; make sure we don't leak
! 		     * reservations if that happens */
! 		    vp = avp;
! 		    VCancelReservation_r(rvp);
! 		    rvp = avp;
! 		    VCreateReservation_r(rvp);
! 		}
! 		VPutVolume_r(avp);
! 	    }
  	    if (*ec) {
! 		int endloop = 0;
! 		switch (*ec) {
! 		case VSALVAGING:
! 		    break;
! 		case VOFFLINE:
! 		    if (!vp-&gt;pending_vol_op) {
! 			endloop = 1;
! 		    }
! 		    break;
! 		default:
! 		    *ec = VNOVOL;
! 		    endloop = 1;
! 		}
! 		if (endloop) {
! 		    vp = NULL;
! 		    break;
! 		}
! 	    }
! 	}
! 
! 	if ((V_attachState(vp) == VOL_STATE_SALVAGING) ||
! 	    (*ec == VSALVAGING)) {
! 	    if (client_ec) {
! 		/* see CheckVnode() in afsfileprocs.c for an explanation
! 		 * of this error code logic */
! 		afs_uint32 now = FT_ApproxTime();
! 		if ((vp-&gt;stats.last_salvage + (10 * 60)) &gt;= now) {
! 		    *client_ec = VBUSY;
! 		} else {
! 		    *client_ec = VRESTARTING;
! 		}
! 	    }
! 	    *ec = VSALVAGING;
! 	    vp = NULL;
! 	    break;
! 	}
! 
! 	if (vp-&gt;pending_vol_op &amp;&amp; !VVolOpLeaveOnline_r(vp, vp-&gt;pending_vol_op)) {
! 	    if (client_ec) {
! 		/* see CheckVnode() in afsfileprocs.c for an explanation
! 		 * of this error code logic */
! 		afs_uint32 now = FT_ApproxTime();
! 		if ((vp-&gt;stats.last_vol_op + (10 * 60)) &gt;= now) {
! 		    *client_ec = VBUSY;
! 		} else {
! 		    *client_ec = VRESTARTING;
! 		}
! 	    }
! 	    *ec = VOFFLINE;
! 	    vp = NULL;
! 	    break;
! 	}
! 
! 	if (V_attachState(vp) == VOL_STATE_UNATTACHED) {
! 	    *ec = VOFFLINE;
! 	    vp = NULL;
! 	    break;
! 	}
! #endif /* AFS_DEMAND_ATTACH_FS */
! 	
! 	LoadVolumeHeader(ec, vp);
! 	if (*ec) {
! 	    VGET_CTR_INC(V6);
! 	    /* Only log the error if it was a totally unexpected error.  Simply
! 	     * a missing inode is likely to be caused by the volume being deleted */
! 	    if (errno != ENXIO || LogLevel)
! 		Log("Volume %u: couldn't reread volume header\n",
! 		    vp-&gt;hashid);
! #ifdef AFS_DEMAND_ATTACH_FS
! 	    if (programType == fileServer) {
! 		VRequestSalvage_r(vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
! 		*ec = VSALVAGING;
! 	    } else {
  		FreeVolume(vp);
  		vp = NULL;
  	    }
+ #else /* AFS_DEMAND_ATTACH_FS */
+ 	    FreeVolume(vp);
+ 	    vp = NULL;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 	    break;
  	}
! 
! 	VGET_CTR_INC(V7);
  	if (vp-&gt;shuttingDown) {
! 	    VGET_CTR_INC(V8);
  	    *ec = VNOVOL;
  	    vp = NULL;
  	    break;
  	}
+ 
  	if (programType == fileServer) {
! 	    VGET_CTR_INC(V9);
  	    if (vp-&gt;goingOffline) {
! 		VGET_CTR_INC(V10);
! #ifdef AFS_DEMAND_ATTACH_FS
! 		/* wait for the volume to go offline */
! 		if (V_attachState(vp) == VOL_STATE_GOING_OFFLINE) {
! 		    VWaitStateChange_r(vp);
! 		}
! #elif defined(AFS_PTHREAD_ENV)
! 		assert(pthread_cond_wait(&amp;vol_put_volume_cond, &amp;vol_glock_mutex) == 0);
  #else /* AFS_PTHREAD_ENV */
  		LWP_WaitProcess(VPutVolume);
  #endif /* AFS_PTHREAD_ENV */
  		continue;
  	    }
  	    if (vp-&gt;specialStatus) {
! 		VGET_CTR_INC(V11);
  		*ec = vp-&gt;specialStatus;
  	    } else if (V_inService(vp) == 0 || V_blessed(vp) == 0) {
! 		VGET_CTR_INC(V12);
  		*ec = VNOVOL;
  	    } else if (V_inUse(vp) == 0) {
! 		VGET_CTR_INC(V13);
  		*ec = VOFFLINE;
  	    } else {
! 		VGET_CTR_INC(V14);
  	    }
  	}
  	break;
      }
!     VGET_CTR_INC(V15);
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     /* if no error, bump nUsers */
!     if (vp) {
! 	vp-&gt;nUsers++;
! 	VLRU_UpdateAccess_r(vp);
!     }
!     if (rvp) {
! 	VCancelReservation_r(rvp);
! 	rvp = NULL;
!     }
!     if (client_ec &amp;&amp; !*client_ec) {
! 	*client_ec = *ec;
!     }
! #else /* AFS_DEMAND_ATTACH_FS */
      /* if no error, bump nUsers */
!     if (vp) {
  	vp-&gt;nUsers++;
+     }
+     if (client_ec) {
+ 	*client_ec = *ec;
+     }
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
      assert(vp || *ec);
      return vp;
  }
  
  
! /***************************************************/
! /* Volume offline/detach routines                  */
! /***************************************************/
! 
! /* caller MUST hold a heavyweight ref on vp */
! #ifdef AFS_DEMAND_ATTACH_FS
! void
! VTakeOffline_r(register Volume * vp)
  {
!     assert(vp-&gt;nUsers &gt; 0);
!     assert(programType == fileServer);
  
!     VCreateReservation_r(vp);
!     VWaitExclusiveState_r(vp);
  
!     vp-&gt;goingOffline = 1;
!     V_needsSalvaged(vp) = 1;
! 
!     VRequestSalvage_r(vp, SALVSYNC_ERROR, 0);
!     VCancelReservation_r(vp);
! }
! #else /* AFS_DEMAND_ATTACH_FS */
! void
! VTakeOffline_r(register Volume * vp)
! {
!     assert(vp-&gt;nUsers &gt; 0);
!     assert(programType == fileServer);
! 
!     vp-&gt;goingOffline = 1;
!     V_needsSalvaged(vp) = 1;
! }
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
! void
! VTakeOffline(register Volume * vp)
! {
!     VOL_LOCK;
!     VTakeOffline_r(vp);
!     VOL_UNLOCK;
  }
  
  /* Force the volume offline, set the salvage flag.  No further references to
   * the volume through the volume package will be honored. */
+ /* for demand attach, caller MUST hold ref count on vp */
  void
! VForceOffline_r(Volume * vp, int flags)
  {
      Error error;
      if (!V_inUse(vp))
***************
*** 1267,1273 ****
      V_inUse(vp) = 0;
      vp-&gt;goingOffline = 0;
      V_needsSalvaged(vp) = 1;
!     VUpdateVolume_r(&amp;error, vp);
  #ifdef AFS_PTHREAD_ENV
      assert(pthread_cond_broadcast(&amp;vol_put_volume_cond) == 0);
  #else /* AFS_PTHREAD_ENV */
--- 2896,2912 ----
      V_inUse(vp) = 0;
      vp-&gt;goingOffline = 0;
      V_needsSalvaged(vp) = 1;
!     if (!(flags &amp; VOL_FORCEOFF_NOUPDATE)) {
! 	VUpdateVolume_r(&amp;error, vp, VOL_UPDATE_WAIT | VOL_UPDATE_NOFORCEOFF);
!     }
! #ifdef AFS_DEMAND_ATTACH_FS
! #ifdef SALVSYNC_BUILD_CLIENT
!     if (programType == fileServer) {
! 	VRequestSalvage_r(vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
!     }
! #endif
!     VChangeState_r(vp, VOL_STATE_ERROR);
! #endif /* AFS_DEMAND_ATTACH_FS */
  #ifdef AFS_PTHREAD_ENV
      assert(pthread_cond_broadcast(&amp;vol_put_volume_cond) == 0);
  #else /* AFS_PTHREAD_ENV */
***************
*** 1275,1288 ****
  #endif /* AFS_PTHREAD_ENV */
  
      VReleaseVolumeHandles_r(vp);
- 
  }
  
  void
  VForceOffline(Volume * vp)
  {
      VOL_LOCK;
!     VForceOffline_r(vp);
      VOL_UNLOCK;
  }
  
--- 2914,2926 ----
  #endif /* AFS_PTHREAD_ENV */
  
      VReleaseVolumeHandles_r(vp);
  }
  
  void
  VForceOffline(Volume * vp)
  {
      VOL_LOCK;
!     VForceOffline_r(vp, 0);
      VOL_UNLOCK;
  }
  
***************
*** 1295,1300 ****
--- 2933,2939 ----
  {
      Error error;
      VolumeId vid = V_id(vp);
+ 
      assert(programType != volumeUtility);
      if (!V_inUse(vp)) {
  	VPutVolume_r(vp);
***************
*** 1303,1313 ****
--- 2942,2965 ----
      if (V_offlineMessage(vp)[0] == '\0')
  	strncpy(V_offlineMessage(vp), message, sizeof(V_offlineMessage(vp)));
      V_offlineMessage(vp)[sizeof(V_offlineMessage(vp)) - 1] = '\0';
+ 
      vp-&gt;goingOffline = 1;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     VChangeState_r(vp, VOL_STATE_GOING_OFFLINE);
+     VCreateReservation_r(vp);
+     VPutVolume_r(vp);
+ 
+     /* wait for the volume to go offline */
+     if (V_attachState(vp) == VOL_STATE_GOING_OFFLINE) {
+ 	VWaitStateChange_r(vp);
+     }
+     VCancelReservation_r(vp);
+ #else /* AFS_DEMAND_ATTACH_FS */
      VPutVolume_r(vp);
      vp = VGetVolume_r(&amp;error, vid);	/* Wait for it to go offline */
      if (vp)			/* In case it was reattached... */
  	VPutVolume_r(vp);
+ #endif /* AFS_DEMAND_ATTACH_FS */
  }
  
  void
***************
*** 1318,1353 ****
      VOL_UNLOCK;
  }
  
- /* For VDetachVolume, we close all cached file descriptors, but keep
-  * the Inode handles in case we need to read from a busy volume.
-  */
- static void
- VCloseVolumeHandles_r(Volume * vp)
- {
-     DFlushVolume(V_id(vp));
-     VCloseVnodeFiles_r(vp);
- 
-     /* Too time consuming and unnecessary for the volserver */
-     if (programType != volumeUtility) {
- 	IH_CONDSYNC(vp-&gt;vnodeIndex[vLarge].handle);
- 	IH_CONDSYNC(vp-&gt;vnodeIndex[vSmall].handle);
- 	IH_CONDSYNC(vp-&gt;diskDataHandle);
- #ifdef AFS_NT40_ENV
- 	IH_CONDSYNC(vp-&gt;linkHandle);
- #endif /* AFS_NT40_ENV */
-     }
- 
-     IH_REALLYCLOSE(vp-&gt;vnodeIndex[vLarge].handle);
-     IH_REALLYCLOSE(vp-&gt;vnodeIndex[vSmall].handle);
-     IH_REALLYCLOSE(vp-&gt;diskDataHandle);
-     IH_REALLYCLOSE(vp-&gt;linkHandle);
- }
- 
  /* This gets used for the most part by utility routines that don't want
   * to keep all the volume headers around.  Generally, the file server won't
   * call this routine, because then the offline message in the volume header
!  * (or other information) will still be available to clients. For NAMEI, also
!  * close the file handles.
   */
  void
  VDetachVolume_r(Error * ec, Volume * vp)
--- 2970,2981 ----
      VOL_UNLOCK;
  }
  
  /* This gets used for the most part by utility routines that don't want
   * to keep all the volume headers around.  Generally, the file server won't
   * call this routine, because then the offline message in the volume header
!  * (or other information) won't be available to clients. For NAMEI, also
!  * close the file handles.  However, the fileserver does call this during
!  * an attach following a volume operation.
   */
  void
  VDetachVolume_r(Error * ec, Volume * vp)
***************
*** 1365,1373 ****
--- 2993,3010 ----
      volume = V_id(vp);
      DeleteVolumeFromHashTable(vp);
      vp-&gt;shuttingDown = 1;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     DeleteVolumeFromVByPList_r(vp);
+     VLRU_Delete_r(vp);
+     VChangeState_r(vp, VOL_STATE_SHUTTING_DOWN);
+ #endif /* AFS_DEMAND_ATTACH_FS */
      VPutVolume_r(vp);
      /* Will be detached sometime in the future--this is OK since volume is offline */
  
+     /* XXX the following code should really be moved to VCheckDetach() since the volume
+      * is not technically detached until the refcounts reach zero
+      */
+ #ifdef FSSYNC_BUILD_CLIENT
      if (programType == volumeUtility &amp;&amp; notifyServer) {
  	/* 
  	 * Note:  The server is not notified in the case of a bogus volume 
***************
*** 1378,1396 ****
  	 * would be two instances of the same volume, one of them bogus, 
  	 * which the file server would attempt to put on line 
  	 */
! 	if (useDone)
  	    /* don't put online */
! 	    FSYNC_askfs(volume, tpartp-&gt;name, FSYNC_DONE, 0);
! 	else {
  	    /* fs can use it again */
! 	    FSYNC_askfs(volume, tpartp-&gt;name, FSYNC_ON, 0);
  	    /* Dettaching it so break all callbacks on it */
  	    if (V_BreakVolumeCallbacks) {
  		Log("volume %u detached; breaking all call backs\n", volume);
  		(*V_BreakVolumeCallbacks) (volume);
  	    }
  	}
      }
  }
  
  void
--- 3015,3040 ----
  	 * would be two instances of the same volume, one of them bogus, 
  	 * which the file server would attempt to put on line 
  	 */
! 	if (useDone) {
  	    /* don't put online */
! 	    FSYNC_VolOp(volume, tpartp-&gt;name, FSYNC_VOL_DONE, 0, NULL);
! 	} else {
  	    /* fs can use it again */
! 	    FSYNC_VolOp(volume, tpartp-&gt;name, FSYNC_VOL_ON, 0, NULL);
! 
! 	    /* XXX this code path is only hit by volume utilities, thus
! 	     * V_BreakVolumeCallbacks will always be NULL.  if we really
! 	     * want to break callbacks in this path we need to use FSYNC_VolOp() */
! #ifdef notdef
  	    /* Dettaching it so break all callbacks on it */
  	    if (V_BreakVolumeCallbacks) {
  		Log("volume %u detached; breaking all call backs\n", volume);
  		(*V_BreakVolumeCallbacks) (volume);
  	    }
+ #endif
  	}
      }
+ #endif /* FSSYNC_BUILD_CLIENT */
  }
  
  void
***************
*** 1402,1535 ****
  }
  
  
! VnodeId
! VAllocBitmapEntry_r(Error * ec, Volume * vp, register struct vnodeIndex
! 		    *index)
  {
!     register byte *bp, *ep;
!     *ec = 0;
!     /* This test is probably redundant */
!     if (!VolumeWriteable(vp)) {
! 	*ec = (bit32) VREADONLY;
! 	return 0;
!     }
! #ifdef BITMAP_LATER
!     if ((programType == fileServer) &amp;&amp; !index-&gt;bitmap) {
! 	int i;
! 	int wasVBUSY = 0;
! 	if (vp-&gt;specialStatus == VBUSY) {
! 	    if (vp-&gt;goingOffline) {	/* vos dump waiting for the volume to
! 					 * go offline. We probably come here
! 					 * from AddNewReadableResidency */
! 		wasVBUSY = 1;
! 	    } else {
! 		VOL_UNLOCK;
! 		while (vp-&gt;specialStatus == VBUSY)
! #ifdef AFS_PTHREAD_ENV
! 		    sleep(2);
! #else /* AFS_PTHREAD_ENV */
! 		    IOMGR_Sleep(2);
! #endif /* AFS_PTHREAD_ENV */
! 		VOL_LOCK;
! 	    }
! 	}
! 	if (!index-&gt;bitmap) {
! 	    vp-&gt;specialStatus = VBUSY;	/* Stop anyone else from using it. */
! 	    for (i = 0; i &lt; nVNODECLASSES; i++) {
! 		VOL_UNLOCK;
! 		GetBitmap(ec, vp, i);
! 		VOL_LOCK;
! 		if (*ec) {
! 		    vp-&gt;specialStatus = 0;
! 		    vp-&gt;shuttingDown = 1;	/* Let who has it free it. */
! 		    return NULL;
! 		}
! 	    }
! 	    if (!wasVBUSY)
! 		vp-&gt;specialStatus = 0;	/* Allow others to have access. */
! 	}
!     }
! #endif /* BITMAP_LATER */
!     bp = index-&gt;bitmap + index-&gt;bitmapOffset;
!     ep = index-&gt;bitmap + index-&gt;bitmapSize;
!     while (bp &lt; ep) {
! 	if ((*(bit32 *) bp) != (bit32) 0xffffffff) {
! 	    int o;
! 	    index-&gt;bitmapOffset = (afs_uint32) (bp - index-&gt;bitmap);
! 	    while (*bp == 0xff)
! 		bp++;
! 	    o = ffs(~*bp) - 1;	/* ffs is documented in BSTRING(3) */
! 	    *bp |= (1 &lt;&lt; o);
! 	    return (VnodeId) ((bp - index-&gt;bitmap) * 8 + o);
! 	}
! 	bp += sizeof(bit32) /* i.e. 4 */ ;
      }
-     /* No bit map entry--must grow bitmap */
-     bp = (byte *)
- 	realloc(index-&gt;bitmap, index-&gt;bitmapSize + VOLUME_BITMAP_GROWSIZE);
-     assert(bp != NULL);
-     index-&gt;bitmap = bp;
-     bp += index-&gt;bitmapSize;
-     memset(bp, 0, VOLUME_BITMAP_GROWSIZE);
-     index-&gt;bitmapOffset = index-&gt;bitmapSize;
-     index-&gt;bitmapSize += VOLUME_BITMAP_GROWSIZE;
-     *bp = 1;
-     return index-&gt;bitmapOffset * 8;
- }
  
! VnodeId
! VAllocBitmapEntry(Error * ec, Volume * vp, register struct vnodeIndex * index)
! {
!     VnodeId retVal;
      VOL_LOCK;
!     retVal = VAllocBitmapEntry_r(ec, vp, index);
!     VOL_UNLOCK;
!     return retVal;
  }
  
! void
! VFreeBitMapEntry_r(Error * ec, register struct vnodeIndex *index,
! 		   unsigned bitNumber)
  {
!     unsigned int offset;
!     *ec = 0;
! #ifdef BITMAP_LATER
!     if (!index-&gt;bitmap)
! 	return;
! #endif /* BITMAP_LATER */
!     offset = bitNumber &gt;&gt; 3;
!     if (offset &gt;= index-&gt;bitmapSize) {
! 	*ec = VNOVNODE;
! 	return;
      }
-     if (offset &lt; index-&gt;bitmapOffset)
- 	index-&gt;bitmapOffset = offset &amp; ~3;	/* Truncate to nearest bit32 */
-     *(index-&gt;bitmap + offset) &amp;= ~(1 &lt;&lt; (bitNumber &amp; 0x7));
- }
  
! void
! VFreeBitMapEntry(Error * ec, register struct vnodeIndex *index,
! 		 unsigned bitNumber)
! {
      VOL_LOCK;
!     VFreeBitMapEntry_r(ec, index, bitNumber);
!     VOL_UNLOCK;
  }
  
  void
! VUpdateVolume_r(Error * ec, Volume * vp)
  {
      *ec = 0;
      if (programType == fileServer)
  	V_uniquifier(vp) =
  	    (V_inUse(vp) ? V_nextVnodeUnique(vp) +
  	     200 : V_nextVnodeUnique(vp));
!     /*printf("Writing volume header for '%s'\n", V_name(vp)); */
      WriteVolumeHeader_r(ec, vp);
      if (*ec) {
  	Log("VUpdateVolume: error updating volume header, volume %u (%s)\n",
  	    V_id(vp), V_name(vp));
! 	VForceOffline_r(vp);
      }
  }
  
--- 3046,3193 ----
  }
  
  
! /***************************************************/
! /* Volume fd/inode handle closing routines         */
! /***************************************************/
! 
! /* For VDetachVolume, we close all cached file descriptors, but keep
!  * the Inode handles in case we need to read from a busy volume.
!  */
! /* for demand attach, caller MUST hold ref count on vp */
! static void
! VCloseVolumeHandles_r(Volume * vp)
  {
! #ifdef AFS_DEMAND_ATTACH_FS
!     VolState state_save;
! 
!     state_save = VChangeState_r(vp, VOL_STATE_OFFLINING);
! #endif
! 
!     /* demand attach fs
!      *
!      * XXX need to investigate whether we can perform
!      * DFlushVolume outside of vol_glock_mutex... 
!      *
!      * VCloseVnodeFiles_r drops the glock internally */
!     DFlushVolume(V_id(vp));
!     VCloseVnodeFiles_r(vp);
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     VOL_UNLOCK;
! #endif
! 
!     /* Too time consuming and unnecessary for the volserver */
!     if (programType != volumeUtility) {
! 	IH_CONDSYNC(vp-&gt;vnodeIndex[vLarge].handle);
! 	IH_CONDSYNC(vp-&gt;vnodeIndex[vSmall].handle);
! 	IH_CONDSYNC(vp-&gt;diskDataHandle);
! #ifdef AFS_NT40_ENV
! 	IH_CONDSYNC(vp-&gt;linkHandle);
! #endif /* AFS_NT40_ENV */
      }
  
!     IH_REALLYCLOSE(vp-&gt;vnodeIndex[vLarge].handle);
!     IH_REALLYCLOSE(vp-&gt;vnodeIndex[vSmall].handle);
!     IH_REALLYCLOSE(vp-&gt;diskDataHandle);
!     IH_REALLYCLOSE(vp-&gt;linkHandle);
! 
! #ifdef AFS_DEMAND_ATTACH_FS
      VOL_LOCK;
!     VChangeState_r(vp, state_save);
! #endif
  }
  
! /* For both VForceOffline and VOffline, we close all relevant handles.
!  * For VOffline, if we re-attach the volume, the files may possible be
!  * different than before. 
!  */
! /* for demand attach, caller MUST hold a ref count on vp */
! static void
! VReleaseVolumeHandles_r(Volume * vp)
  {
! #ifdef AFS_DEMAND_ATTACH_FS
!     VolState state_save;
! 
!     state_save = VChangeState_r(vp, VOL_STATE_DETACHING);
! #endif
! 
!     /* XXX need to investigate whether we can perform
!      * DFlushVolume outside of vol_glock_mutex... */
!     DFlushVolume(V_id(vp));
! 
!     VReleaseVnodeFiles_r(vp); /* releases the glock internally */
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     VOL_UNLOCK;
! #endif
! 
!     /* Too time consuming and unnecessary for the volserver */
!     if (programType != volumeUtility) {
! 	IH_CONDSYNC(vp-&gt;vnodeIndex[vLarge].handle);
! 	IH_CONDSYNC(vp-&gt;vnodeIndex[vSmall].handle);
! 	IH_CONDSYNC(vp-&gt;diskDataHandle);
! #ifdef AFS_NT40_ENV
! 	IH_CONDSYNC(vp-&gt;linkHandle);
! #endif /* AFS_NT40_ENV */
      }
  
!     IH_RELEASE(vp-&gt;vnodeIndex[vLarge].handle);
!     IH_RELEASE(vp-&gt;vnodeIndex[vSmall].handle);
!     IH_RELEASE(vp-&gt;diskDataHandle);
!     IH_RELEASE(vp-&gt;linkHandle);
! 
! #ifdef AFS_DEMAND_ATTACH_FS
      VOL_LOCK;
!     VChangeState_r(vp, state_save);
! #endif
  }
  
+ 
+ /***************************************************/
+ /* Volume write and fsync routines                 */
+ /***************************************************/
+ 
  void
! VUpdateVolume_r(Error * ec, Volume * vp, int flags)
  {
+ #ifdef AFS_DEMAND_ATTACH_FS
+     VolState state_save;
+ 
+     if (flags &amp; VOL_UPDATE_WAIT) {
+ 	VCreateReservation_r(vp);
+ 	VWaitExclusiveState_r(vp);
+     }
+ #endif
+ 
      *ec = 0;
      if (programType == fileServer)
  	V_uniquifier(vp) =
  	    (V_inUse(vp) ? V_nextVnodeUnique(vp) +
  	     200 : V_nextVnodeUnique(vp));
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     state_save = VChangeState_r(vp, VOL_STATE_UPDATING);
!     VOL_UNLOCK;
! #endif
! 
      WriteVolumeHeader_r(ec, vp);
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+     VOL_LOCK;
+     VChangeState_r(vp, state_save);
+     if (flags &amp; VOL_UPDATE_WAIT) {
+ 	VCancelReservation_r(vp);
+     }
+ #endif
+ 
      if (*ec) {
  	Log("VUpdateVolume: error updating volume header, volume %u (%s)\n",
  	    V_id(vp), V_name(vp));
! 	/* try to update on-disk header, 
! 	 * while preventing infinite recursion */
! 	if (!(flags &amp; VOL_UPDATE_NOFORCEOFF)) {
! 	    VForceOffline_r(vp, VOL_FORCEOFF_NOUPDATE);
! 	}
      }
  }
  
***************
*** 1537,1558 ****
  VUpdateVolume(Error * ec, Volume * vp)
  {
      VOL_LOCK;
!     VUpdateVolume_r(ec, vp);
      VOL_UNLOCK;
  }
  
  void
! VSyncVolume_r(Error * ec, Volume * vp)
  {
      FdHandle_t *fdP;
!     VUpdateVolume_r(ec, vp);
!     if (!ec) {
! 	int code;
  	fdP = IH_OPEN(V_diskDataHandle(vp));
  	assert(fdP != NULL);
  	code = FDH_SYNC(fdP);
  	assert(code == 0);
  	FDH_CLOSE(fdP);
      }
  }
  
--- 3195,3232 ----
  VUpdateVolume(Error * ec, Volume * vp)
  {
      VOL_LOCK;
!     VUpdateVolume_r(ec, vp, VOL_UPDATE_WAIT);
      VOL_UNLOCK;
  }
  
  void
! VSyncVolume_r(Error * ec, Volume * vp, int flags)
  {
      FdHandle_t *fdP;
!     int code;
! #ifdef AFS_DEMAND_ATTACH_FS
!     VolState state_save;
! #endif
! 
!     if (flags &amp; VOL_SYNC_WAIT) {
! 	VUpdateVolume_r(ec, vp, VOL_UPDATE_WAIT);
!     } else {
! 	VUpdateVolume_r(ec, vp, 0);
!     }
!     if (!*ec) {
! #ifdef AFS_DEMAND_ATTACH_FS
! 	state_save = VChangeState_r(vp, VOL_STATE_UPDATING);
! 	VOL_UNLOCK;
! #endif
  	fdP = IH_OPEN(V_diskDataHandle(vp));
  	assert(fdP != NULL);
  	code = FDH_SYNC(fdP);
  	assert(code == 0);
  	FDH_CLOSE(fdP);
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	VOL_LOCK;
+ 	VChangeState_r(vp, state_save);
+ #endif
      }
  }
  
***************
*** 1560,1926 ****
  VSyncVolume(Error * ec, Volume * vp)
  {
      VOL_LOCK;
!     VSyncVolume_r(ec, vp);
      VOL_UNLOCK;
  }
  
  static void
  FreeVolume(Volume * vp)
  {
      int i;
      if (!vp)
  	return;
      for (i = 0; i &lt; nVNODECLASSES; i++)
  	if (vp-&gt;vnodeIndex[i].bitmap)
  	    free(vp-&gt;vnodeIndex[i].bitmap);
      FreeVolumeHeader(vp);
      DeleteVolumeFromHashTable(vp);
      free(vp);
  }
  
! static void
! GetBitmap(Error * ec, Volume * vp, VnodeClass class)
  {
!     StreamHandle_t *file;
!     int nVnodes;
!     int size;
!     struct VnodeClassInfo *vcp = &amp;VnodeClassInfo[class];
!     struct vnodeIndex *vip = &amp;vp-&gt;vnodeIndex[class];
!     struct VnodeDiskObject *vnode;
!     unsigned int unique = 0;
!     FdHandle_t *fdP;
! #ifdef BITMAP_LATER
!     byte *BitMap = 0;
! #endif /* BITMAP_LATER */
  
!     *ec = 0;
  
!     fdP = IH_OPEN(vip-&gt;handle);
!     assert(fdP != NULL);
!     file = FDH_FDOPEN(fdP, "r");
!     assert(file != NULL);
!     vnode = (VnodeDiskObject *) malloc(vcp-&gt;diskSize);
!     assert(vnode != NULL);
!     size = OS_SIZE(fdP-&gt;fd_fd);
!     assert(size != -1);
!     nVnodes = (size &lt;= vcp-&gt;diskSize ? 0 : size - vcp-&gt;diskSize)
! 	&gt;&gt; vcp-&gt;logSize;
!     vip-&gt;bitmapSize = ((nVnodes / 8) + 10) / 4 * 4;	/* The 10 is a little extra so
! 							 * a few files can be created in this volume,
! 							 * the whole thing is rounded up to nearest 4
! 							 * bytes, because the bit map allocator likes
! 							 * it that way */
! #ifdef BITMAP_LATER
!     BitMap = (byte *) calloc(1, vip-&gt;bitmapSize);
!     assert(BitMap != NULL);
! #else /* BITMAP_LATER */
!     vip-&gt;bitmap = (byte *) calloc(1, vip-&gt;bitmapSize);
!     assert(vip-&gt;bitmap != NULL);
!     vip-&gt;bitmapOffset = 0;
! #endif /* BITMAP_LATER */
!     if (STREAM_SEEK(file, vcp-&gt;diskSize, 0) != -1) {
! 	int bitNumber = 0;
! 	for (bitNumber = 0; bitNumber &lt; nVnodes + 100; bitNumber++) {
! 	    if (STREAM_READ(vnode, vcp-&gt;diskSize, 1, file) != 1)
! 		break;
! 	    if (vnode-&gt;type != vNull) {
! 		if (vnode-&gt;vnodeMagic != vcp-&gt;magic) {
! 		    Log("GetBitmap: addled vnode index in volume %s; volume needs salvage\n", V_name(vp));
! 		    *ec = VSALVAGE;
! 		    break;
! 		}
! #ifdef BITMAP_LATER
! 		*(BitMap + (bitNumber &gt;&gt; 3)) |= (1 &lt;&lt; (bitNumber &amp; 0x7));
! #else /* BITMAP_LATER */
! 		*(vip-&gt;bitmap + (bitNumber &gt;&gt; 3)) |= (1 &lt;&lt; (bitNumber &amp; 0x7));
! #endif /* BITMAP_LATER */
! 		if (unique &lt;= vnode-&gt;uniquifier)
! 		    unique = vnode-&gt;uniquifier + 1;
! 	    }
! #ifndef AFS_PTHREAD_ENV
! 	    if ((bitNumber &amp; 0x00ff) == 0x0ff) {	/* every 256 iterations */
! 		IOMGR_Poll();
! 	    }
! #endif /* !AFS_PTHREAD_ENV */
  	}
      }
!     if (vp-&gt;nextVnodeUnique &lt; unique) {
! 	Log("GetBitmap: bad volume uniquifier for volume %s; volume needs salvage\n", V_name(vp));
! 	*ec = VSALVAGE;
      }
!     /* Paranoia, partly justified--I think fclose after fdopen
!      * doesn't seem to close fd.  In any event, the documentation
!      * doesn't specify, so it's safer to close it twice.
!      */
!     STREAM_CLOSE(file);
!     FDH_CLOSE(fdP);
!     free(vnode);
! #ifdef BITMAP_LATER
!     /* There may have been a racing condition with some other thread, both
!      * creating the bitmaps for this volume. If the other thread was faster
!      * the pointer to bitmap should already be filled and we can free ours.
!      */
!     if (vip-&gt;bitmap == NULL) {
! 	vip-&gt;bitmap = BitMap;
! 	vip-&gt;bitmapOffset = 0;
!     } else
! 	free((byte *) BitMap);
! #endif /* BITMAP_LATER */
  }
  
! static void
! GetVolumePath(Error * ec, VolId volumeId, char **partitionp, char **namep)
  {
!     static char partition[VMAXPATHLEN], name[VMAXPATHLEN];
!     char path[VMAXPATHLEN];
!     int found = 0;
!     struct DiskPartition *dp;
  
!     *ec = 0;
!     name[0] = '/';
!     (void)afs_snprintf(&amp;name[1], (sizeof name) - 1, VFORMAT, volumeId);
!     for (dp = DiskPartitionList; dp; dp = dp-&gt;next) {
! 	struct afs_stat status;
! 	strcpy(path, VPartitionPath(dp));
! 	strcat(path, name);
! 	if (afs_stat(path, &amp;status) == 0) {
! 	    strcpy(partition, dp-&gt;name);
! 	    found = 1;
! 	    break;
  	}
      }
!     if (!found) {
! 	*ec = VNOVOL;
! 	*partitionp = *namep = NULL;
!     } else {
! 	*partitionp = partition;
! 	*namep = name;
      }
  }
  
! int
! VolumeNumber(char *name)
  {
!     if (*name == '/')
! 	name++;
!     return atoi(name + 1);
  }
  
! char *
! VolumeExternalName(VolumeId volumeId)
  {
!     static char name[VMAXPATHLEN];
!     (void)afs_snprintf(name, sizeof name, VFORMAT, volumeId);
!     return name;
  }
  
! #if OPENAFS_VOL_STATS
! #define OneDay	(86400)		/* 24 hours' worth of seconds */
! #else
! #define OneDay	(24*60*60)	/* 24 hours */
! #endif /* OPENAFS_VOL_STATS */
  
- #define Midnight(date) ((date-TimeZoneCorrection)/OneDay*OneDay+TimeZoneCorrection)
  
! /*------------------------------------------------------------------------
!  * [export] VAdjustVolumeStatistics
!  *
!  * Description:
!  *	If we've passed midnight, we need to update all the day use
!  *	statistics as well as zeroing the detailed volume statistics
!  *	(if we are implementing them).
!  *
!  * Arguments:
!  *	vp : Pointer to the volume structure describing the lucky
!  *		volume being considered for update.
!  *
!  * Returns:
!  *	0 (always!)
!  *
!  * Environment:
!  *	Nothing interesting.
!  *
!  * Side Effects:
!  *	As described.
!  *------------------------------------------------------------------------*/
  
  int
! VAdjustVolumeStatistics_r(register Volume * vp)
  {
!     unsigned int now = FT_ApproxTime();
  
!     if (now - V_dayUseDate(vp) &gt; OneDay) {
! 	register ndays, i;
  
! 	ndays = (now - V_dayUseDate(vp)) / OneDay;
! 	for (i = 6; i &gt; ndays - 1; i--)
! 	    V_weekUse(vp)[i] = V_weekUse(vp)[i - ndays];
! 	for (i = 0; i &lt; ndays - 1 &amp;&amp; i &lt; 7; i++)
! 	    V_weekUse(vp)[i] = 0;
! 	if (ndays &lt;= 7)
! 	    V_weekUse(vp)[ndays - 1] = V_dayUse(vp);
! 	V_dayUse(vp) = 0;
! 	V_dayUseDate(vp) = Midnight(now);
  
! #if OPENAFS_VOL_STATS
! 	/*
! 	 * All we need to do is bzero the entire VOL_STATS_BYTES of
! 	 * the detailed volume statistics area.
! 	 */
! 	memset((char *)(V_stat_area(vp)), 0, VOL_STATS_BYTES);
! #endif /* OPENAFS_VOL_STATS */
      }
  
!     /*It's been more than a day of collection */
!     /*
!      * Always return happily.
!      */
!     return (0);
! }				/*VAdjustVolumeStatistics */
  
  int
! VAdjustVolumeStatistics(register Volume * vp)
  {
!     int retVal;
!     VOL_LOCK;
!     retVal = VAdjustVolumeStatistics_r(vp);
!     VOL_UNLOCK;
!     return retVal;
  }
  
! void
! VBumpVolumeUsage_r(register Volume * vp)
  {
!     unsigned int now = FT_ApproxTime();
!     if (now - V_dayUseDate(vp) &gt; OneDay)
! 	VAdjustVolumeStatistics_r(vp);
!     /*
!      * Save the volume header image to disk after every 128 bumps to dayUse.
!      */
!     if ((V_dayUse(vp)++ &amp; 127) == 0) {
! 	Error error;
! 	VUpdateVolume_r(&amp;error, vp);
      }
  }
  
! void
! VBumpVolumeUsage(register Volume * vp)
  {
!     VOL_LOCK;
!     VBumpVolumeUsage_r(vp);
!     VOL_UNLOCK;
  }
  
! void
! VSetDiskUsage_r(void)
  {
!     static int FifteenMinuteCounter = 0;
  
!     while (VInit &lt; 2) {
! 	/* NOTE: Don't attempt to access the partitions list until the
! 	 * initialization level indicates that all volumes are attached,
! 	 * which implies that all partitions are initialized. */
! #ifdef AFS_PTHREAD_ENV
! 	sleep(10);
! #else /* AFS_PTHREAD_ENV */
! 	IOMGR_Sleep(10);
! #endif /* AFS_PTHREAD_ENV */
!     }
  
!     VResetDiskUsage_r();
!     if (++FifteenMinuteCounter == 3) {
! 	FifteenMinuteCounter = 0;
! 	VScanUpdateList();
      }
  }
  
! void
! VSetDiskUsage(void)
  {
!     VOL_LOCK;
!     VSetDiskUsage_r();
!     VOL_UNLOCK;
! }
  
! /* The number of minutes that a volume hasn't been updated before the
!  * "Dont salvage" flag in the volume header will be turned on */
! #define SALVAGE_INTERVAL	(10*60)
  
! static VolumeId *UpdateList;	/* Pointer to array of Volume ID's */
! static int nUpdatedVolumes;	/* Updated with entry in UpdateList, salvage after crash flag on */
! static int updateSize;		/* number of entries possible */
! #define UPDATE_LIST_SIZE 100	/* size increment */
  
! void
! VAddToVolumeUpdateList_r(Error * ec, Volume * vp)
  {
!     *ec = 0;
!     vp-&gt;updateTime = FT_ApproxTime();
!     if (V_dontSalvage(vp) == 0)
! 	return;
!     V_dontSalvage(vp) = 0;
!     VSyncVolume_r(ec, vp);
!     if (*ec)
! 	return;
!     if (!UpdateList) {
! 	updateSize = UPDATE_LIST_SIZE;
! 	UpdateList = (VolumeId *) malloc(sizeof(VolumeId) * updateSize);
!     } else {
! 	if (nUpdatedVolumes == updateSize) {
! 	    updateSize += UPDATE_LIST_SIZE;
! 	    UpdateList =
! 		(VolumeId *) realloc(UpdateList,
! 				     sizeof(VolumeId) * updateSize);
  	}
      }
!     assert(UpdateList != NULL);
!     UpdateList[nUpdatedVolumes++] = V_id(vp);
  }
  
! static void
! VScanUpdateList(void)
! {
      register int i, gap;
      register Volume *vp;
      Error error;
      afs_uint32 now = FT_ApproxTime();
      /* Be careful with this code, since it works with interleaved calls to AddToVolumeUpdateList */
      for (i = gap = 0; i &lt; nUpdatedVolumes; i++) {
  	vp = VGetVolume_r(&amp;error, UpdateList[i - gap] = UpdateList[i]);
  	if (error) {
  	    gap++;
  	} else if (vp-&gt;nUsers == 1 &amp;&amp; now - vp-&gt;updateTime &gt; SALVAGE_INTERVAL) {
  	    V_dontSalvage(vp) = DONT_SALVAGE;
! 	    VUpdateVolume_r(&amp;error, vp);	/* No need to fsync--not critical */
  	    gap++;
  	}
! 	if (vp)
  	    VPutVolume_r(vp);
! #ifndef AFS_PTHREAD_ENV
! 	IOMGR_Poll();
! #endif /* !AFS_PTHREAD_ENV */
      }
!     nUpdatedVolumes -= gap;
  }
  
  /***************************************************/
! /* Add on routines to manage a volume header cache */
  /***************************************************/
  
! static struct volHeader *volumeLRU;
  
  /* Allocate a bunch of headers; string them together */
  static void
! InitLRU(int howMany)
  {
      register struct volHeader *hp;
      if (programType != fileServer)
  	return;
      hp = (struct volHeader *)(calloc(howMany, sizeof(struct volHeader)));
      while (howMany--)
  	ReleaseVolumeHeader(hp++);
  }
  
  /* Get a volume header from the LRU list; update the old one if necessary */
  /* Returns 1 if there was already a header, which is removed from the LRU list */
  static int
--- 3234,5474 ----
  VSyncVolume(Error * ec, Volume * vp)
  {
      VOL_LOCK;
!     VSyncVolume_r(ec, vp, VOL_SYNC_WAIT);
      VOL_UNLOCK;
  }
  
+ 
+ /***************************************************/
+ /* Volume dealloaction routines                    */
+ /***************************************************/
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
  static void
  FreeVolume(Volume * vp)
  {
+     /* free the heap space, iff it's safe.
+      * otherwise, pull it out of the hash table, so it
+      * will get deallocated when all refs to it go away */
+     if (!VCheckFree(vp)) {
+ 	DeleteVolumeFromHashTable(vp);
+ 	DeleteVolumeFromVByPList_r(vp);
+ 
+ 	/* make sure we invalidate the header cache entry */
+ 	FreeVolumeHeader(vp);
+     }
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ static void
+ ReallyFreeVolume(Volume * vp)
+ {
      int i;
      if (!vp)
  	return;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     /* debug */
+     VChangeState_r(vp, VOL_STATE_FREED);
+     if (vp-&gt;pending_vol_op)
+ 	free(vp-&gt;pending_vol_op);
+ #endif /* AFS_DEMAND_ATTACH_FS */
      for (i = 0; i &lt; nVNODECLASSES; i++)
  	if (vp-&gt;vnodeIndex[i].bitmap)
  	    free(vp-&gt;vnodeIndex[i].bitmap);
      FreeVolumeHeader(vp);
+ #ifndef AFS_DEMAND_ATTACH_FS
      DeleteVolumeFromHashTable(vp);
+ #endif /* AFS_DEMAND_ATTACH_FS */
      free(vp);
  }
  
! /* check to see if we should shutdown this volume
!  * returns 1 if volume was freed, 0 otherwise */
! #ifdef AFS_DEMAND_ATTACH_FS
! static int
! VCheckDetach(register Volume * vp)
  {
!     int ret = 0;
  
!     if (vp-&gt;nUsers || vp-&gt;nWaiters)
! 	return ret;
  
!     if (vp-&gt;shuttingDown) {
! 	ret = 1;
! 	VReleaseVolumeHandles_r(vp);
! 	VCheckSalvage(vp);
! 	ReallyFreeVolume(vp);
! 	if (programType == fileServer) {
! 	    assert(pthread_cond_broadcast(&amp;vol_put_volume_cond) == 0);
  	}
      }
!     return ret;
! }
! #else /* AFS_DEMAND_ATTACH_FS */
! static int
! VCheckDetach(register Volume * vp)
! {
!     int ret = 0;
! 
!     if (vp-&gt;nUsers)
! 	return ret;
! 
!     if (vp-&gt;shuttingDown) {
! 	ret = 1;
! 	VReleaseVolumeHandles_r(vp);
! 	ReallyFreeVolume(vp);
! 	if (programType == fileServer) {
! #if defined(AFS_PTHREAD_ENV)
! 	    assert(pthread_cond_broadcast(&amp;vol_put_volume_cond) == 0);
! #else /* AFS_PTHREAD_ENV */
! 	    LWP_NoYieldSignal(VPutVolume);
! #endif /* AFS_PTHREAD_ENV */
! 	}
      }
!     return ret;
  }
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
! /* check to see if we should offline this volume
!  * return 1 if volume went offline, 0 otherwise */
! #ifdef AFS_DEMAND_ATTACH_FS
! static int
! VCheckOffline(register Volume * vp)
  {
!     Volume * rvp = NULL;
!     int ret = 0;
  
!     if (vp-&gt;goingOffline &amp;&amp; !vp-&gt;nUsers) {
! 	Error error;
! 	assert(programType == fileServer);
! 	assert((V_attachState(vp) != VOL_STATE_ATTACHED) &amp;&amp;
! 	       (V_attachState(vp) != VOL_STATE_FREED) &amp;&amp;
! 	       (V_attachState(vp) != VOL_STATE_PREATTACHED) &amp;&amp;
! 	       (V_attachState(vp) != VOL_STATE_UNATTACHED));
! 
! 	/* valid states:
! 	 *
! 	 * VOL_STATE_GOING_OFFLINE
! 	 * VOL_STATE_SHUTTING_DOWN
! 	 * IsErrorState(V_attachState(vp))
! 	 * IsExclusiveState(V_attachState(vp))
! 	 */
! 
! 	VCreateReservation_r(vp);
! 	VChangeState_r(vp, VOL_STATE_OFFLINING);
! 
! 	ret = 1;
! 	/* must clear the goingOffline flag before we drop the glock */
! 	vp-&gt;goingOffline = 0;
! 	V_inUse(vp) = 0;
! 
! 	VLRU_Delete_r(vp);
! 
! 	/* perform async operations */
! 	VUpdateVolume_r(&amp;error, vp, 0);
! 	VCloseVolumeHandles_r(vp);
! 
! 	/* invalidate the volume header cache entry */
! 	FreeVolumeHeader(vp);
! 
! 	if (LogLevel) {
! 	    Log("VOffline: Volume %u (%s) is now offline", V_id(vp),
! 		V_name(vp));
! 	    if (V_offlineMessage(vp)[0])
! 		Log(" (%s)", V_offlineMessage(vp));
! 	    Log("\n");
! 	}
! 
! 	/* if nothing changed state to error or salvaging,
! 	 * drop state to unattached */
! 	if (!IsErrorState(V_attachState(vp))) {
! 	    VChangeState_r(vp, VOL_STATE_UNATTACHED);
  	}
+ 	VCancelReservation_r(vp);
      }
!     return ret;
! }
! #else /* AFS_DEMAND_ATTACH_FS */
! static int
! VCheckOffline(register Volume * vp)
! {
!     Volume * rvp = NULL;
!     int ret = 0;
! 
!     if (vp-&gt;goingOffline &amp;&amp; !vp-&gt;nUsers) {
! 	Error error;
! 	assert(programType == fileServer);
! 
! 	ret = 1;
! 	vp-&gt;goingOffline = 0;
! 	V_inUse(vp) = 0;
! 	VUpdateVolume_r(&amp;error, vp, 0);
! 	VCloseVolumeHandles_r(vp);
! 	FreeVolumeHeader(vp);
! 	if (LogLevel) {
! 	    Log("VOffline: Volume %u (%s) is now offline", V_id(vp),
! 		V_name(vp));
! 	    if (V_offlineMessage(vp)[0])
! 		Log(" (%s)", V_offlineMessage(vp));
! 	    Log("\n");
! 	}
! #ifdef AFS_PTHREAD_ENV
! 	assert(pthread_cond_broadcast(&amp;vol_put_volume_cond) == 0);
! #else /* AFS_PTHREAD_ENV */
! 	LWP_NoYieldSignal(VPutVolume);
! #endif /* AFS_PTHREAD_ENV */
      }
+     return ret;
  }
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
! /***************************************************/
! /* demand attach fs ref counting routines          */
! /***************************************************/
! 
! #ifdef AFS_DEMAND_ATTACH_FS
! /* the following two functions handle reference counting for
!  * asynchronous operations on volume structs.
!  *
!  * their purpose is to prevent a VDetachVolume or VShutdown
!  * from free()ing the Volume struct during an async i/o op */
! 
! /* register with the async volume op ref counter */
! static void
! VCreateReservation_r(Volume * vp)
  {
!     vp-&gt;nWaiters++;
  }
  
! /* unregister with the async volume op ref counter */
! static void
! VCancelReservation_r(Volume * vp)
  {
!     assert(--vp-&gt;nWaiters &gt;= 0);
!     if (vp-&gt;nWaiters == 0) {
! 	VCheckOffline(vp);
! 	if (!VCheckDetach(vp)) {
! 	    VCheckSalvage(vp);
! 	    VCheckFree(vp);
! 	}
!     }
  }
  
! /* check to see if we should free this volume now
!  * return 1 if volume was freed, 0 otherwise */
! static int
! VCheckFree(Volume * vp)
! {
!     int ret = 0;
!     if ((vp-&gt;nUsers == 0) &amp;&amp;
! 	(vp-&gt;nWaiters == 0) &amp;&amp;
! 	!(V_attachFlags(vp) &amp; (VOL_IN_HASH | 
! 			       VOL_ON_VBYP_LIST | 
! 			       VOL_IS_BUSY |
! 			       VOL_ON_VLRU))) {
! 	ReallyFreeVolume(vp);
! 	ret = 1;
!     }
!     return ret;
! }
! #endif /* AFS_DEMAND_ATTACH_FS */
  
  
! /***************************************************/
! /* online volume operations routines               */
! /***************************************************/
  
+ #ifdef AFS_DEMAND_ATTACH_FS
  int
! VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo)
  {
!     FSSYNC_VolOp_info * info;
  
!     /* attach a vol op info node to the volume struct */
!     info = (FSSYNC_VolOp_info *) malloc(sizeof(FSSYNC_VolOp_info));
!     assert(info != NULL);
!     memcpy(info, vopinfo, sizeof(FSSYNC_VolOp_info));
!     vp-&gt;pending_vol_op = info;
! 
!     /* update stats */
!     vp-&gt;stats.last_vol_op = FT_ApproxTime();
!     vp-&gt;stats.vol_ops++;
!     IncUInt64(&amp;VStats.vol_ops);
  
!     return 0;
! }
  
! int
! VDeregisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo)
! {
!     if (vp-&gt;pending_vol_op) {
! 	free(vp-&gt;pending_vol_op);
! 	vp-&gt;pending_vol_op = NULL;
      }
+     return 0;
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
! int
! VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo)
! {
!     return (vopinfo-&gt;com.command == FSYNC_VOL_NEEDVOLUME &amp;&amp;
! 	    (vopinfo-&gt;com.reason == V_READONLY ||
! 	     (!VolumeWriteable(vp) &amp;&amp;
! 	      (vopinfo-&gt;com.reason == V_CLONE ||
! 	       vopinfo-&gt;com.reason == V_DUMP))));
! }
  
  int
! VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo)
  {
!     return (vopinfo-&gt;com.command == FSYNC_VOL_NEEDVOLUME &amp;&amp;
! 	    (vopinfo-&gt;com.reason == V_CLONE ||
! 	     vopinfo-&gt;com.reason == V_DUMP));
  }
  
! 
! /***************************************************/
! /* online salvager routines                        */
! /***************************************************/
! #if defined(AFS_DEMAND_ATTACH_FS)
! #define SALVAGE_PRIO_UPDATE_INTERVAL 3      /* number of seconds between prio updates */
! #define SALVAGE_COUNT_MAX 16                /* number of online salvages we
! 					     * allow before moving the volume
! 					     * into a permanent error state
! 					     *
! 					     * once this threshold is reached,
! 					     * the operator will have to manually
! 					     * issue a 'bos salvage' to bring
! 					     * the volume back online
! 					     */
! 
! /* check to see if we should salvage this volume
!  * returns 1 if salvage scheduled, 0 otherwise */
! static int
! VCheckSalvage(register Volume * vp)
  {
!     int ret = 0;
! #ifdef SALVSYNC_BUILD_CLIENT
!     if (vp-&gt;nUsers || vp-&gt;nWaiters)
! 	return ret;
!     if (vp-&gt;salvage.requested) {
! 	VScheduleSalvage_r(vp);
! 	ret = 1;
      }
+ #endif /* SALVSYNC_BUILD_CLIENT */
+     return ret;
  }
  
! /*
!  * request that a salvage be performed once
!  * ref counts reach zero
!  */
! int
! VRequestSalvage_r(Volume * vp, int reason, int flags)
  {
! #ifdef SALVSYNC_BUILD_CLIENT
!     if (programType != fileServer)
! 	return 1;
! 
!     if (!vp-&gt;salvage.requested) {
! 	vp-&gt;salvage.requested = 1;
! 	vp-&gt;salvage.reason = reason;
! 	vp-&gt;stats.last_salvage = FT_ApproxTime();
! 	if (flags &amp; VOL_SALVAGE_INVALIDATE_HEADER) {
! 	    ReleaseVolumeHeader(vp-&gt;header);
! 	}
! 	if (vp-&gt;stats.salvages &lt; SALVAGE_COUNT_MAX) {
! 	    VChangeState_r(vp, VOL_STATE_SALVAGING);
! 	} else {
! 	    Log("VRequestSalvage: volume %u online salvaged too many times; forced offline.\n", vp-&gt;hashid);
! 	    VChangeState_r(vp, VOL_STATE_ERROR);
! 	}
!     }
! #endif /* SALVSYNC_BUILD_CLIENT */
!     return 0;
  }
  
! /*
!  * update salvage priority
!  */
! static int
! VUpdateSalvagePriority_r(Volume * vp)
  {
!     int code, ret=0;
!     afs_uint32 now;
  
! #ifdef SALVSYNC_BUILD_CLIENT
!     vp-&gt;salvage.prio++;
!     now = FT_ApproxTime();
  
!     /* update the salvageserver priority queue occasionally so that
!      * frequently requested volumes get moved to the head of the queue 
!      */
!     if ((vp-&gt;salvage.scheduled) &amp;&amp;
! 	(vp-&gt;stats.last_salvage_req &lt; (now-SALVAGE_PRIO_UPDATE_INTERVAL))) {
! 	code = SALVSYNC_SalvageVolume(vp-&gt;hashid,
! 				      VPartitionPath(vp-&gt;partition),
! 				      SALVSYNC_RAISEPRIO,
! 				      vp-&gt;salvage.reason,
! 				      vp-&gt;salvage.prio,
! 				      NULL);
! 	vp-&gt;stats.last_salvage_req = now;
! 	if (code != SYNC_OK) {
! 	    ret = 1;
! 	}
      }
+ #endif /* SALVSYNC_BUILD_CLIENT */
+     return ret;
  }
  
! 
! /*
!  * schedule a salvage with the salvage server
!  */
! static int
! VScheduleSalvage_r(Volume * vp)
  {
!     int code, ret=0;
! #ifdef SALVSYNC_BUILD_CLIENT
!     VolState state_save;
!     char partName[16];
! 
!     if (vp-&gt;nWaiters || vp-&gt;nUsers) {
! 	return 1;
!     }
! 
!     /* prevent endless salvage,attach,salvage,attach,... loops */
!     if (vp-&gt;stats.salvages &gt;= SALVAGE_COUNT_MAX)
! 	return 1;
! 
!     if (!vp-&gt;salvage.scheduled) {
! 	/* if we haven't previously scheduled a salvage, do so now 
! 	 *
! 	 * set the volume to an exclusive state and drop the lock
! 	 * around the SALVSYNC call
! 	 */
! 	strlcpy(partName, VPartitionPath(vp-&gt;partition), sizeof(partName));
! 	state_save = VChangeState_r(vp, VOL_STATE_SALVSYNC_REQ);
! 	V_attachFlags(vp) |= VOL_IS_BUSY;
! 	VOL_UNLOCK;
  
! 	/* can't use V_id() since there's no guarantee
! 	 * we have the disk data header at this point */
! 	code = SALVSYNC_SalvageVolume(vp-&gt;hashid,
! 				      partName,
! 				      SALVSYNC_SALVAGE,
! 				      vp-&gt;salvage.reason,
! 				      vp-&gt;salvage.prio,
! 				      NULL);
! 	VOL_LOCK;
! 	VChangeState_r(vp, state_save);
! 	V_attachFlags(vp) &amp;= ~(VOL_IS_BUSY);
  
! 	if (code == SYNC_OK) {
! 	    vp-&gt;salvage.scheduled = 1;
! 	    vp-&gt;stats.salvages++;
! 	    vp-&gt;stats.last_salvage_req = FT_ApproxTime();
! 	    IncUInt64(&amp;VStats.salvages);
! 	} else {
! 	    ret = 1;
! 	    switch(code) {
! 	    case SYNC_BAD_COMMAND:
! 	    case SYNC_COM_ERROR:
! 		break;
! 	    case SYNC_DENIED:
! 		Log("VScheduleSalvage_r:  SALVSYNC request denied\n");
! 		break;
! 	    default:
! 		Log("VScheduleSalvage_r:  SALVSYNC unknown protocol error\n");
! 		break;
! 	    }
! 	}
!     }
! #endif /* SALVSYNC_BUILD_CLIENT */
!     return ret;
! }
  
! /*
!  * cancel a scheduled salvage operation
!  */
! static int
! VCancelSalvage_r(Volume * vp, int reason)
  {
!     int code, ret = 0;
! 
! #ifdef SALVSYNC_BUILD_CLIENT
!     if (vp-&gt;salvage.scheduled) {
! 	code = SALVSYNC_SalvageVolume(vp-&gt;hashid,
! 				      VPartitionPath(vp-&gt;partition),
! 				      SALVSYNC_CANCEL,
! 				      reason,
! 				      0,
! 				      NULL);
! 	if (code == SYNC_OK) {
! 	    vp-&gt;salvage.scheduled = 0;
! 	} else {
! 	    ret = 1;
  	}
      }
! #endif /* SALVSYNC_BUILD_CLIENT */
!     return ret;
  }
  
! /* This must be called by any volume utility which needs to run while the
!    file server is also running.  This is separated from VInitVolumePackage so
!    that a utility can fork--and each of the children can independently
!    initialize communication with the file server */
! #ifdef SALVSYNC_BUILD_CLIENT
! int
! VConnectSALV(void)
! {
!     int retVal;
!     VOL_LOCK;
!     retVal = VConnectSALV_r();
!     VOL_UNLOCK;
!     return retVal;
! }
! 
! int
! VConnectSALV_r(void)
! {
!     assert((programType != salvageServer) &amp;&amp;
! 	   (programType != volumeUtility));
!     return SALVSYNC_clientInit();
! }
! 
! int
! VDisconnectSALV(void)
! {
!     int retVal;
!     VOL_LOCK;
!     VDisconnectSALV_r();
!     VOL_UNLOCK;
!     return retVal;
! }
! 
! int
! VDisconnectSALV_r(void)
! { 
!     assert((programType != salvageServer) &amp;&amp;
! 	   (programType != volumeUtility));
!     return SALVSYNC_clientFinis();
! }
! 
! int
! VReconnectSALV(void)
! {
!     int retVal;
!     VOL_LOCK;
!     retVal = VReconnectSALV_r();
!     VOL_UNLOCK;
!     return retVal;
! }
! 
! int
! VReconnectSALV_r(void)
! {
!     assert((programType != salvageServer) &amp;&amp;
! 	   (programType != volumeUtility));
!     return SALVSYNC_clientReconnect();
! }
! #endif /* SALVSYNC_BUILD_CLIENT */
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
! 
! /***************************************************/
! /* FSSYNC routines                                 */
! /***************************************************/
! 
! /* This must be called by any volume utility which needs to run while the
!    file server is also running.  This is separated from VInitVolumePackage so
!    that a utility can fork--and each of the children can independently
!    initialize communication with the file server */
! #ifdef FSSYNC_BUILD_CLIENT
! int
! VConnectFS(void)
! {
!     int retVal;
!     VOL_LOCK;
!     retVal = VConnectFS_r();
!     VOL_UNLOCK;
!     return retVal;
! }
! 
! int
! VConnectFS_r(void)
! {
!     int rc;
!     assert((VInit == 2) &amp;&amp; 
! 	   (programType != fileServer) &amp;&amp;
! 	   (programType != salvager));
!     rc = FSYNC_clientInit();
!     if (rc)
! 	VInit = 3;
!     return rc;
! }
! 
! void
! VDisconnectFS_r(void)
! {
!     assert((programType != fileServer) &amp;&amp;
! 	   (programType != salvager));
!     FSYNC_clientFinis();
!     VInit = 2;
! }
! 
! void
! VDisconnectFS(void)
! {
!     VOL_LOCK;
!     VDisconnectFS_r();
!     VOL_UNLOCK;
! }
! 
! static int
! VChildProcReconnectFS_r(void)
! {
!     return FSYNC_clientChildProcReconnect();
! }
! 
! int
! VChildProcReconnectFS(void)
! {
!     int ret;
!     VOL_LOCK;
!     ret = VChildProcReconnectFS_r();
!     VOL_UNLOCK;
!     return ret;
! }
! #endif /* FSSYNC_BUILD_CLIENT */
! 
! 
! /***************************************************/
! /* volume bitmap routines                          */
! /***************************************************/
! 
! /*
!  * For demand attach fs, flags parameter controls
!  * locking behavior.  If (flags &amp; VOL_ALLOC_BITMAP_WAIT)
!  * is set, then this function will create a reservation
!  * and block on any other exclusive operations.  Otherwise,
!  * this function assumes the caller already has exclusive
!  * access to vp, and we just change the volume state.
!  */
! VnodeId
! VAllocBitmapEntry_r(Error * ec, Volume * vp, 
! 		    struct vnodeIndex *index, int flags)
! {
!     VnodeId ret;
!     register byte *bp, *ep;
! #ifdef AFS_DEMAND_ATTACH_FS
!     VolState state_save;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
!     *ec = 0;
! 
!     /* This test is probably redundant */
!     if (!VolumeWriteable(vp)) {
! 	*ec = (bit32) VREADONLY;
! 	return 0;
!     }
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     if (flags &amp; VOL_ALLOC_BITMAP_WAIT) {
! 	VCreateReservation_r(vp);
! 	VWaitExclusiveState_r(vp);
!     }
!     state_save = VChangeState_r(vp, VOL_STATE_GET_BITMAP);
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
! #ifdef BITMAP_LATER
!     if ((programType == fileServer) &amp;&amp; !index-&gt;bitmap) {
! 	int i;
! #ifndef AFS_DEMAND_ATTACH_FS
! 	/* demand attach fs uses the volume state to avoid races.
! 	 * specialStatus field is not used at all */
! 	int wasVBUSY = 0;
! 	if (vp-&gt;specialStatus == VBUSY) {
! 	    if (vp-&gt;goingOffline) {	/* vos dump waiting for the volume to
! 					 * go offline. We probably come here
! 					 * from AddNewReadableResidency */
! 		wasVBUSY = 1;
! 	    } else {
! 		while (vp-&gt;specialStatus == VBUSY) {
! #ifdef AFS_PTHREAD_ENV
! 		    VOL_UNLOCK;
! 		    sleep(2);
! 		    VOL_LOCK;
! #else /* AFS_PTHREAD_ENV */
! 		    IOMGR_Sleep(2);
! #endif /* AFS_DEMAND_ATTACH_FS */
! 		}
! 	    }
! 	}
! #endif /* !AFS_DEMAND_ATTACH_FS */
! 
! 	if (!index-&gt;bitmap) {
! #ifndef AFS_DEMAND_ATTACH_FS
! 	    vp-&gt;specialStatus = VBUSY;	/* Stop anyone else from using it. */
! #endif /* AFS_DEMAND_ATTACH_FS */
! 	    for (i = 0; i &lt; nVNODECLASSES; i++) {
! 		VGetBitmap_r(ec, vp, i);
! 		if (*ec) {
! #ifdef AFS_DEMAND_ATTACH_FS
! 		    VRequestSalvage_r(vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
! 		    *ec = VSALVAGING;
! #else /* AFS_DEMAND_ATTACH_FS */
! 		    DeleteVolumeFromHashTable(vp);
! 		    vp-&gt;shuttingDown = 1;	/* Let who has it free it. */
! 		    vp-&gt;specialStatus = 0;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 		    ret = NULL;
! 		    goto done;
! 		}
! 	    }
! #ifndef AFS_DEMAND_ATTACH_FS
! 	    if (!wasVBUSY)
! 		vp-&gt;specialStatus = 0;	/* Allow others to have access. */
! #endif /* AFS_DEMAND_ATTACH_FS */
! 	}
!     }
! #endif /* BITMAP_LATER */
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     VOL_UNLOCK;
! #endif /* AFS_DEMAND_ATTACH_FS */
!     bp = index-&gt;bitmap + index-&gt;bitmapOffset;
!     ep = index-&gt;bitmap + index-&gt;bitmapSize;
!     while (bp &lt; ep) {
! 	if ((*(bit32 *) bp) != (bit32) 0xffffffff) {
! 	    int o;
! 	    index-&gt;bitmapOffset = (afs_uint32) (bp - index-&gt;bitmap);
! 	    while (*bp == 0xff)
! 		bp++;
! 	    o = ffs(~*bp) - 1;	/* ffs is documented in BSTRING(3) */
! 	    *bp |= (1 &lt;&lt; o);
! 	    ret = (VnodeId) ((bp - index-&gt;bitmap) * 8 + o);
! #ifdef AFS_DEMAND_ATTACH_FS
! 	    VOL_LOCK;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 	    goto done;
! 	}
! 	bp += sizeof(bit32) /* i.e. 4 */ ;
!     }
!     /* No bit map entry--must grow bitmap */
!     bp = (byte *)
! 	realloc(index-&gt;bitmap, index-&gt;bitmapSize + VOLUME_BITMAP_GROWSIZE);
!     assert(bp != NULL);
!     index-&gt;bitmap = bp;
!     bp += index-&gt;bitmapSize;
!     memset(bp, 0, VOLUME_BITMAP_GROWSIZE);
!     index-&gt;bitmapOffset = index-&gt;bitmapSize;
!     index-&gt;bitmapSize += VOLUME_BITMAP_GROWSIZE;
!     *bp = 1;
!     ret = index-&gt;bitmapOffset * 8;
! #ifdef AFS_DEMAND_ATTACH_FS
!     VOL_LOCK;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
!  done:
! #ifdef AFS_DEMAND_ATTACH_FS
!     VChangeState_r(vp, state_save);
!     if (flags &amp; VOL_ALLOC_BITMAP_WAIT) {
! 	VCancelReservation_r(vp);
!     }
! #endif /* AFS_DEMAND_ATTACH_FS */
!     return ret;
! }
! 
! VnodeId
! VAllocBitmapEntry(Error * ec, Volume * vp, register struct vnodeIndex * index)
! {
!     VnodeId retVal;
!     VOL_LOCK;
!     retVal = VAllocBitmapEntry_r(ec, vp, index, VOL_ALLOC_BITMAP_WAIT);
!     VOL_UNLOCK;
!     return retVal;
! }
! 
! void
! VFreeBitMapEntry_r(Error * ec, register struct vnodeIndex *index,
! 		   unsigned bitNumber)
! {
!     unsigned int offset;
! 
!     *ec = 0;
! #ifdef BITMAP_LATER
!     if (!index-&gt;bitmap)
! 	return;
! #endif /* BITMAP_LATER */
!     offset = bitNumber &gt;&gt; 3;
!     if (offset &gt;= index-&gt;bitmapSize) {
! 	*ec = VNOVNODE;
! 	return;
!     }
!     if (offset &lt; index-&gt;bitmapOffset)
! 	index-&gt;bitmapOffset = offset &amp; ~3;	/* Truncate to nearest bit32 */
!     *(index-&gt;bitmap + offset) &amp;= ~(1 &lt;&lt; (bitNumber &amp; 0x7));
! }
! 
! void
! VFreeBitMapEntry(Error * ec, register struct vnodeIndex *index,
! 		 unsigned bitNumber)
! {
!     VOL_LOCK;
!     VFreeBitMapEntry_r(ec, index, bitNumber);
!     VOL_UNLOCK;
! }
! 
! /* this function will drop the glock internally.
!  * for old pthread fileservers, this is safe thanks to vbusy.
!  *
!  * for demand attach fs, caller must have already called
!  * VCreateReservation_r and VWaitExclusiveState_r */
! static void
! VGetBitmap_r(Error * ec, Volume * vp, VnodeClass class)
! {
!     StreamHandle_t *file;
!     int nVnodes;
!     int size;
!     struct VnodeClassInfo *vcp = &amp;VnodeClassInfo[class];
!     struct vnodeIndex *vip = &amp;vp-&gt;vnodeIndex[class];
!     struct VnodeDiskObject *vnode;
!     unsigned int unique = 0;
!     FdHandle_t *fdP;
! #ifdef BITMAP_LATER
!     byte *BitMap = 0;
! #endif /* BITMAP_LATER */
! #ifdef AFS_DEMAND_ATTACH_FS
!     VolState state_save;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
!     *ec = 0;
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     state_save = VChangeState_r(vp, VOL_STATE_GET_BITMAP);
! #endif /* AFS_DEMAND_ATTACH_FS */
!     VOL_UNLOCK;
! 
!     fdP = IH_OPEN(vip-&gt;handle);
!     assert(fdP != NULL);
!     file = FDH_FDOPEN(fdP, "r");
!     assert(file != NULL);
!     vnode = (VnodeDiskObject *) malloc(vcp-&gt;diskSize);
!     assert(vnode != NULL);
!     size = OS_SIZE(fdP-&gt;fd_fd);
!     assert(size != -1);
!     nVnodes = (size &lt;= vcp-&gt;diskSize ? 0 : size - vcp-&gt;diskSize)
! 	&gt;&gt; vcp-&gt;logSize;
!     vip-&gt;bitmapSize = ((nVnodes / 8) + 10) / 4 * 4;	/* The 10 is a little extra so
! 							 * a few files can be created in this volume,
! 							 * the whole thing is rounded up to nearest 4
! 							 * bytes, because the bit map allocator likes
! 							 * it that way */
! #ifdef BITMAP_LATER
!     BitMap = (byte *) calloc(1, vip-&gt;bitmapSize);
!     assert(BitMap != NULL);
! #else /* BITMAP_LATER */
!     vip-&gt;bitmap = (byte *) calloc(1, vip-&gt;bitmapSize);
!     assert(vip-&gt;bitmap != NULL);
!     vip-&gt;bitmapOffset = 0;
! #endif /* BITMAP_LATER */
!     if (STREAM_SEEK(file, vcp-&gt;diskSize, 0) != -1) {
! 	int bitNumber = 0;
! 	for (bitNumber = 0; bitNumber &lt; nVnodes + 100; bitNumber++) {
! 	    if (STREAM_READ(vnode, vcp-&gt;diskSize, 1, file) != 1)
! 		break;
! 	    if (vnode-&gt;type != vNull) {
! 		if (vnode-&gt;vnodeMagic != vcp-&gt;magic) {
! 		    Log("GetBitmap: addled vnode index in volume %s; volume needs salvage\n", V_name(vp));
! 		    *ec = VSALVAGE;
! 		    break;
! 		}
! #ifdef BITMAP_LATER
! 		*(BitMap + (bitNumber &gt;&gt; 3)) |= (1 &lt;&lt; (bitNumber &amp; 0x7));
! #else /* BITMAP_LATER */
! 		*(vip-&gt;bitmap + (bitNumber &gt;&gt; 3)) |= (1 &lt;&lt; (bitNumber &amp; 0x7));
! #endif /* BITMAP_LATER */
! 		if (unique &lt;= vnode-&gt;uniquifier)
! 		    unique = vnode-&gt;uniquifier + 1;
! 	    }
! #ifndef AFS_PTHREAD_ENV
! 	    if ((bitNumber &amp; 0x00ff) == 0x0ff) {	/* every 256 iterations */
! 		IOMGR_Poll();
! 	    }
! #endif /* !AFS_PTHREAD_ENV */
! 	}
!     }
!     if (vp-&gt;nextVnodeUnique &lt; unique) {
! 	Log("GetBitmap: bad volume uniquifier for volume %s; volume needs salvage\n", V_name(vp));
! 	*ec = VSALVAGE;
!     }
!     /* Paranoia, partly justified--I think fclose after fdopen
!      * doesn't seem to close fd.  In any event, the documentation
!      * doesn't specify, so it's safer to close it twice.
!      */
!     STREAM_CLOSE(file);
!     FDH_CLOSE(fdP);
!     free(vnode);
! 
!     VOL_LOCK;
! #ifdef BITMAP_LATER
!     /* There may have been a racing condition with some other thread, both
!      * creating the bitmaps for this volume. If the other thread was faster
!      * the pointer to bitmap should already be filled and we can free ours.
!      */
!     if (vip-&gt;bitmap == NULL) {
! 	vip-&gt;bitmap = BitMap;
! 	vip-&gt;bitmapOffset = 0;
!     } else
! 	free((byte *) BitMap);
! #endif /* BITMAP_LATER */
! #ifdef AFS_DEMAND_ATTACH_FS
!     VChangeState_r(vp, state_save);
! #endif /* AFS_DEMAND_ATTACH_FS */
! }
! 
! 
! /***************************************************/
! /* demand attach fs state machine routines         */
! /***************************************************/
! 
! #ifdef AFS_DEMAND_ATTACH_FS
! /* wait for the volume to change states */
! static void
! VWaitStateChange_r(Volume * vp)
! {
!     VolState state_save = V_attachState(vp);
! 
!     assert(vp-&gt;nWaiters || vp-&gt;nUsers);
!     do {
! 	assert(pthread_cond_wait(&amp;V_attachCV(vp), &amp;vol_glock_mutex) == 0);
!     } while (V_attachState(vp) == state_save);
!     assert(V_attachState(vp) != VOL_STATE_FREED);
! }
! 
! /* wait for blocking ops to end */
! static void
! VWaitExclusiveState_r(Volume * vp)
! {
!     assert(vp-&gt;nWaiters || vp-&gt;nUsers);
!     while (IsExclusiveState(V_attachState(vp))) {
! 	assert(pthread_cond_wait(&amp;V_attachCV(vp), &amp;vol_glock_mutex) == 0);
!     }
!     assert(V_attachState(vp) != VOL_STATE_FREED);
! }
! 
! /* change state, and notify other threads,
!  * return previous state to caller */
! VolState
! VChangeState_r(Volume * vp, VolState new_state)
! {
!     VolState old_state = V_attachState(vp);
! 
!     /* XXX profiling need to make sure these counters
!      * don't kill performance... */
!     VStats.state_levels[old_state]--;
!     VStats.state_levels[new_state]++;
! 
!     V_attachState(vp) = new_state;
!     assert(pthread_cond_broadcast(&amp;V_attachCV(vp)) == 0);
!     return old_state;
! }
! 
! /* tells caller whether or not the current state requires
!  * exclusive access without holding glock */
! static int
! IsExclusiveState(VolState state)
! {
!     switch (state) {
!     case VOL_STATE_UPDATING:
!     case VOL_STATE_ATTACHING:
!     case VOL_STATE_GET_BITMAP:
!     case VOL_STATE_HDR_LOADING:
!     case VOL_STATE_HDR_ATTACHING:
!     case VOL_STATE_OFFLINING:
!     case VOL_STATE_DETACHING:
! 	return 1;
!     }
!     return 0;
! }
! 
! /* tell caller whether V_attachState is an error condition */
! static int
! IsErrorState(VolState state)
! {
!     switch (state) {
!     case VOL_STATE_ERROR:
!     case VOL_STATE_SALVAGING:
! 	return 1;
!     }
!     return 0;
! }
! 
! /* tell caller whether V_attachState is valid */
! static int
! IsValidState(VolState state)
! {
!     if ((state &gt;= 0) &amp;&amp; 
! 	(state &lt; VOL_STATE_COUNT) &amp;&amp;
! 	(state != VOL_STATE_FREED)) {
! 	return 1;
!     }
!     return 0;
! }
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
! 
! /***************************************************/
! /* Volume Path and Volume Number utility routines  */
! /***************************************************/
! 
! static void
! GetVolumePath(Error * ec, VolId volumeId, char **partitionp, char **namep)
! {
!     static char partition[VMAXPATHLEN], name[VMAXPATHLEN];
!     char path[VMAXPATHLEN];
!     int found = 0;
!     struct DiskPartition *dp;
! 
!     *ec = 0;
!     name[0] = '/';
!     (void)afs_snprintf(&amp;name[1], (sizeof name) - 1, VFORMAT, volumeId);
!     for (dp = DiskPartitionList; dp; dp = dp-&gt;next) {
! 	struct afs_stat status;
! 	strcpy(path, VPartitionPath(dp));
! 	strcat(path, name);
! 	if (afs_stat(path, &amp;status) == 0) {
! 	    strcpy(partition, dp-&gt;name);
! 	    found = 1;
! 	    break;
! 	}
!     }
!     if (!found) {
! 	*ec = VNOVOL;
! 	*partitionp = *namep = NULL;
!     } else {
! 	*partitionp = partition;
! 	*namep = name;
!     }
! }
! 
! int
! VolumeNumber(char *name)
! {
!     if (*name == '/')
! 	name++;
!     return atoi(name + 1);
! }
! 
! char *
! VolumeExternalName(VolumeId volumeId)
! {
!     static char name[VMAXPATHLEN];
!     (void)afs_snprintf(name, sizeof name, VFORMAT, volumeId);
!     return name;
! }
! 
! static int
! VolumeExternalName_r(VolumeId volumeId, char * name, size_t len)
! {
!     return afs_snprintf(name, len, VFORMAT, volumeId);
! }
! 
! 
! /***************************************************/
! /* Volume Usage Statistics routines                */
! /***************************************************/
! 
! #if OPENAFS_VOL_STATS
! #define OneDay	(86400)		/* 24 hours' worth of seconds */
! #else
! #define OneDay	(24*60*60)	/* 24 hours */
! #endif /* OPENAFS_VOL_STATS */
! 
! #define Midnight(date) ((date-TimeZoneCorrection)/OneDay*OneDay+TimeZoneCorrection)
! 
! /*------------------------------------------------------------------------
!  * [export] VAdjustVolumeStatistics
!  *
!  * Description:
!  *	If we've passed midnight, we need to update all the day use
!  *	statistics as well as zeroing the detailed volume statistics
!  *	(if we are implementing them).
!  *
!  * Arguments:
!  *	vp : Pointer to the volume structure describing the lucky
!  *		volume being considered for update.
!  *
!  * Returns:
!  *	0 (always!)
!  *
!  * Environment:
!  *	Nothing interesting.
!  *
!  * Side Effects:
!  *	As described.
!  *------------------------------------------------------------------------*/
! 
! int
! VAdjustVolumeStatistics_r(register Volume * vp)
! {
!     unsigned int now = FT_ApproxTime();
! 
!     if (now - V_dayUseDate(vp) &gt; OneDay) {
! 	register int ndays, i;
! 
! 	ndays = (now - V_dayUseDate(vp)) / OneDay;
! 	for (i = 6; i &gt; ndays - 1; i--)
! 	    V_weekUse(vp)[i] = V_weekUse(vp)[i - ndays];
! 	for (i = 0; i &lt; ndays - 1 &amp;&amp; i &lt; 7; i++)
! 	    V_weekUse(vp)[i] = 0;
! 	if (ndays &lt;= 7)
! 	    V_weekUse(vp)[ndays - 1] = V_dayUse(vp);
! 	V_dayUse(vp) = 0;
! 	V_dayUseDate(vp) = Midnight(now);
! 
! #if OPENAFS_VOL_STATS
! 	/*
! 	 * All we need to do is bzero the entire VOL_STATS_BYTES of
! 	 * the detailed volume statistics area.
! 	 */
! 	memset((char *)(V_stat_area(vp)), 0, VOL_STATS_BYTES);
! #endif /* OPENAFS_VOL_STATS */
!     }
! 
!     /*It's been more than a day of collection */
!     /*
!      * Always return happily.
!      */
!     return (0);
! }				/*VAdjustVolumeStatistics */
! 
! int
! VAdjustVolumeStatistics(register Volume * vp)
! {
!     int retVal;
!     VOL_LOCK;
!     retVal = VAdjustVolumeStatistics_r(vp);
!     VOL_UNLOCK;
!     return retVal;
! }
! 
! void
! VBumpVolumeUsage_r(register Volume * vp)
! {
!     unsigned int now = FT_ApproxTime();
!     if (now - V_dayUseDate(vp) &gt; OneDay)
! 	VAdjustVolumeStatistics_r(vp);
!     /*
!      * Save the volume header image to disk after every 128 bumps to dayUse.
!      */
!     if ((V_dayUse(vp)++ &amp; 127) == 0) {
! 	Error error;
! 	VUpdateVolume_r(&amp;error, vp, VOL_UPDATE_WAIT);
!     }
! }
! 
! void
! VBumpVolumeUsage(register Volume * vp)
! {
!     VOL_LOCK;
!     VBumpVolumeUsage_r(vp);
!     VOL_UNLOCK;
! }
! 
! void
! VSetDiskUsage_r(void)
! {
! #ifndef AFS_DEMAND_ATTACH_FS
!     static int FifteenMinuteCounter = 0;
! #endif
! 
!     while (VInit &lt; 2) {
! 	/* NOTE: Don't attempt to access the partitions list until the
! 	 * initialization level indicates that all volumes are attached,
! 	 * which implies that all partitions are initialized. */
! #ifdef AFS_PTHREAD_ENV
! 	sleep(10);
! #else /* AFS_PTHREAD_ENV */
! 	IOMGR_Sleep(10);
! #endif /* AFS_PTHREAD_ENV */
!     }
! 
!     VResetDiskUsage_r();
! 
! #ifndef AFS_DEMAND_ATTACH_FS
!     if (++FifteenMinuteCounter == 3) {
! 	FifteenMinuteCounter = 0;
! 	VScanUpdateList();
!     }
! #endif /* !AFS_DEMAND_ATTACH_FS */
! }
! 
! void
! VSetDiskUsage(void)
! {
!     VOL_LOCK;
!     VSetDiskUsage_r();
!     VOL_UNLOCK;
! }
! 
! 
! /***************************************************/
! /* Volume Update List routines                     */
! /***************************************************/
! 
! /* The number of minutes that a volume hasn't been updated before the
!  * "Dont salvage" flag in the volume header will be turned on */
! #define SALVAGE_INTERVAL	(10*60)
! 
! /*
!  * demand attach fs
!  *
!  * volume update list functionality has been moved into the VLRU
!  * the DONT_SALVAGE flag is now set during VLRU demotion
!  */
! 
! #ifndef AFS_DEMAND_ATTACH_FS
! static VolumeId *UpdateList = NULL;	/* Pointer to array of Volume ID's */
! static int nUpdatedVolumes = 0;	        /* Updated with entry in UpdateList, salvage after crash flag on */
! static int updateSize = 0;		/* number of entries possible */
! #define UPDATE_LIST_SIZE 128	        /* initial size increment (must be a power of 2!) */
! #endif /* !AFS_DEMAND_ATTACH_FS */
! 
! void
! VAddToVolumeUpdateList_r(Error * ec, Volume * vp)
! {
!     *ec = 0;
!     vp-&gt;updateTime = FT_ApproxTime();
!     if (V_dontSalvage(vp) == 0)
! 	return;
!     V_dontSalvage(vp) = 0;
!     VSyncVolume_r(ec, vp, 0);
! #ifdef AFS_DEMAND_ATTACH_FS
!     V_attachFlags(vp) &amp;= ~(VOL_HDR_DONTSALV);
! #else /* !AFS_DEMAND_ATTACH_FS */
!     if (*ec)
! 	return;
!     if (UpdateList == NULL) {
! 	updateSize = UPDATE_LIST_SIZE;
! 	UpdateList = (VolumeId *) malloc(sizeof(VolumeId) * updateSize);
!     } else {
! 	if (nUpdatedVolumes == updateSize) {
! 	    updateSize &lt;&lt; 1;
! 	    if (updateSize &gt; 524288) {
! 		Log("warning: there is likely a bug in the volume update scanner\n");
! 		return;
! 	    }
! 	    UpdateList =
! 		(VolumeId *) realloc(UpdateList,
! 				     sizeof(VolumeId) * updateSize);
! 	}
!     }
!     assert(UpdateList != NULL);
!     UpdateList[nUpdatedVolumes++] = V_id(vp);
! #endif /* !AFS_DEMAND_ATTACH_FS */
! }
! 
! #ifndef AFS_DEMAND_ATTACH_FS
! static void
! VScanUpdateList(void)
! {
      register int i, gap;
      register Volume *vp;
      Error error;
      afs_uint32 now = FT_ApproxTime();
      /* Be careful with this code, since it works with interleaved calls to AddToVolumeUpdateList */
      for (i = gap = 0; i &lt; nUpdatedVolumes; i++) {
+ 	if (gap)
+ 	    UpdateList[i - gap] = UpdateList[i];
+ 
+ 	/* XXX this routine needlessly messes up the Volume LRU by
+ 	 * breaking the LRU temporal-locality assumptions.....
+ 	 * we should use a special volume header allocator here */
  	vp = VGetVolume_r(&amp;error, UpdateList[i - gap] = UpdateList[i]);
  	if (error) {
  	    gap++;
  	} else if (vp-&gt;nUsers == 1 &amp;&amp; now - vp-&gt;updateTime &gt; SALVAGE_INTERVAL) {
  	    V_dontSalvage(vp) = DONT_SALVAGE;
! 	    VUpdateVolume_r(&amp;error, vp, 0);	/* No need to fsync--not critical */
  	    gap++;
  	}
! 
! 	if (vp) {
! 	    VPutVolume_r(vp);
! 	}
! 
! #ifndef AFS_PTHREAD_ENV
! 	IOMGR_Poll();
! #endif /* !AFS_PTHREAD_ENV */
!     }
!     nUpdatedVolumes -= gap;
! }
! #endif /* !AFS_DEMAND_ATTACH_FS */
! 
! 
! /***************************************************/
! /* Volume LRU routines                             */
! /***************************************************/
! 
! /* demand attach fs
!  * volume LRU
!  *
!  * with demand attach fs, we attempt to soft detach(1)
!  * volumes which have not been accessed in a long time
!  * in order to speed up fileserver shutdown
!  *
!  * (1) by soft detach we mean a process very similar
!  *     to VOffline, except the final state of the 
!  *     Volume will be VOL_STATE_PREATTACHED, instead
!  *     of the usual VOL_STATE_UNATTACHED
!  */
! #ifdef AFS_DEMAND_ATTACH_FS
! 
! /* implementation is reminiscent of a generational GC
!  *
!  * queue 0 is newly attached volumes. this queue is
!  * sorted by attach timestamp
!  *
!  * queue 1 is volumes that have been around a bit
!  * longer than queue 0. this queue is sorted by
!  * attach timestamp
!  *
!  * queue 2 is volumes tha have been around the longest.
!  * this queue is unsorted
!  *
!  * queue 3 is volumes that have been marked as
!  * candidates for soft detachment. this queue is
!  * unsorted
!  */
! #define VLRU_GENERATIONS  3   /* number of generations in VLRU */
! #define VLRU_QUEUES       5   /* total number of VLRU queues */
! struct VLRU_q {
!     volatile struct rx_queue q;
!     volatile int len;
!     volatile int busy;
!     pthread_cond_t cv;
! };
! struct VLRU {
!     struct VLRU_q q[VLRU_QUEUES];
! 
!     /* VLRU config */
!     afs_uint32 promotion_interval[VLRU_GENERATIONS-1];  /* interval between promotions */
!     afs_uint32 scan_interval[VLRU_GENERATIONS+1];       /* interval between scans for candidates */
! 
!     /* state */
!     int next_idx;
!     afs_uint32 last_promotion[VLRU_GENERATIONS-1];      /* timestamp of last promotion scan */
!     afs_uint32 last_scan[VLRU_GENERATIONS+1];           /* timestamp of last detach scan */
! 
!     int scanner_state;                                  /* state of scanner thread */
!     pthread_cond_t cv;                                  /* state transition CV */
! };
! 
! static struct VLRU volume_LRU;
! 
! /* valid scanner states */
! #define VLRU_SCANNER_STATE_OFFLINE        0
! #define VLRU_SCANNER_STATE_ONLINE         1
! #define VLRU_SCANNER_STATE_SHUTTING_DOWN  2
! #define VLRU_SCANNER_STATE_PAUSING        3
! #define VLRU_SCANNER_STATE_PAUSED         4
! 
! /* vlru disk data header stuff */
! #define VLRU_DISK_MAGIC      0x7a8b9cad
! #define VLRU_DISK_VERSION    1
! 
! /* vlru default expiration time (for eventual fs state serialization of vlru data) */
! #define VLRU_DUMP_EXPIRATION_TIME   (60*60*24*7)  /* expire vlru data after 1 week */
! 
! 
! static afs_uint32 VLRU_offline_thresh = VLRU_DEFAULT_OFFLINE_THRESH;
! static afs_uint32 VLRU_offline_interval = VLRU_DEFAULT_OFFLINE_INTERVAL;
! static afs_uint32 VLRU_offline_max = VLRU_DEFAULT_OFFLINE_MAX;
! static afs_uint32 VLRU_enabled = 1;
! 
! /* queue synchronization routines */
! static void VLRU_BeginExclusive_r(struct VLRU_q * q);
! static void VLRU_EndExclusive_r(struct VLRU_q * q);
! static void VLRU_Wait_r(struct VLRU_q * q);
! 
! /* set the VLRU parameters 
!  *
!  * valid options are:
!  *  VLRU_SET_THRESH -- set the period of inactivity after
!  *    which volumes are eligible for being detached
!  *  VLRU_SET_INTERVAL -- the time interval between calls
!  *    to the volume LRU "garbage collector"
!  *  VLRU_SET_MAX -- the max number of volumes to deallocate
!  *    in one GC pass
!  */
! void
! VLRU_SetOptions(int option, afs_uint32 val)
! {
!     if (option == VLRU_SET_THRESH) {
! 	VLRU_offline_thresh = val;
!     } else if (option == VLRU_SET_INTERVAL) {
! 	VLRU_offline_interval = val;
!     } else if (option == VLRU_SET_MAX) {
! 	VLRU_offline_max = val;
!     } else if (option == VLRU_SET_ENABLED) {
! 	VLRU_enabled = val;
!     }
!     VLRU_ComputeConstants();
! }
! 
! /* compute the VLRU internal timing parameters based upon the user's inputs */
! static void
! VLRU_ComputeConstants(void)
! {
!     afs_uint32 factor = VLRU_offline_thresh / VLRU_offline_interval;
! 
!     /* compute the candidate scan interval */
!     volume_LRU.scan_interval[VLRU_QUEUE_CANDIDATE] = VLRU_offline_interval;
! 
!     /* compute the promotion intervals */
!     volume_LRU.promotion_interval[VLRU_QUEUE_NEW] = VLRU_offline_thresh * 2;
!     volume_LRU.promotion_interval[VLRU_QUEUE_MID] = VLRU_offline_thresh * 4;
! 
!     if (factor &gt; 16) {
! 	/* compute the gen 0 scan interval */
! 	volume_LRU.scan_interval[VLRU_QUEUE_NEW] = VLRU_offline_thresh / 8;
!     } else {
! 	/* compute the gen 0 scan interval */
! 	volume_LRU.scan_interval[VLRU_QUEUE_NEW] = VLRU_offline_interval * 2;
!     }
! }
! 
! /* initialize VLRU */
! static void
! VInitVLRU(void)
! {
!     pthread_t tid;
!     pthread_attr_t attrs;
!     int i;
! 
!     if (!VLRU_enabled) {
! 	Log("VLRU: disabled\n");
! 	return;
!     }
! 
!     /* initialize each of the VLRU queues */
!     for (i = 0; i &lt; VLRU_QUEUES; i++) {
! 	queue_Init(&amp;volume_LRU.q[i]);
! 	volume_LRU.q[i].len = 0;
! 	volume_LRU.q[i].busy = 0;
! 	assert(pthread_cond_init(&amp;volume_LRU.q[i].cv, NULL) == 0);
!     }
! 
!     /* setup the timing constants */
!     VLRU_ComputeConstants();
! 
!     /* XXX put inside LogLevel check? */
!     Log("VLRU: starting scanner with the following configuration parameters:\n");
!     Log("VLRU:  offlining volumes after minimum of %d seconds of inactivity\n", VLRU_offline_thresh);
!     Log("VLRU:  running VLRU soft detach pass every %d seconds\n", VLRU_offline_interval);
!     Log("VLRU:  taking up to %d volumes offline per pass\n", VLRU_offline_max);
!     Log("VLRU:  scanning generation 0 for inactive volumes every %d seconds\n", volume_LRU.scan_interval[0]);
!     Log("VLRU:  scanning for promotion/demotion between generations 0 and 1 every %d seconds\n", volume_LRU.promotion_interval[0]);
!     Log("VLRU:  scanning for promotion/demotion between generations 1 and 2 every %d seconds\n", volume_LRU.promotion_interval[1]);
! 
!     /* start up the VLRU scanner */
!     volume_LRU.scanner_state = VLRU_SCANNER_STATE_OFFLINE;
!     if (programType == fileServer) {
! 	assert(pthread_cond_init(&amp;volume_LRU.cv, NULL) == 0);
! 	assert(pthread_attr_init(&amp;attrs) == 0);
! 	assert(pthread_attr_setdetachstate(&amp;attrs, PTHREAD_CREATE_DETACHED) == 0);
! 	assert(pthread_create(&amp;tid, &amp;attrs, &amp;VLRU_ScannerThread, NULL) == 0);
!     }
! }
! 
! /* initialize LRU support for a volume */
! static void
! VLRU_Init_Node_r(volatile Volume * vp)
! {
!     if (!VLRU_enabled)
! 	return;
! 
!     assert(queue_IsNotOnQueue(&amp;vp-&gt;vlru));
!     vp-&gt;vlru.idx = VLRU_QUEUE_INVALID;
! }
! 
! /* add volume to VLRU 
!  * now supports adding to queues other
!  * than new for vlru state restore
!  * caller MUST hold a ref count on vp */
! static void
! VLRU_Add_r(volatile Volume * vp)
! {
!     int idx;
! 
!     if (!VLRU_enabled)
! 	return;
! 
!     if (queue_IsOnQueue(&amp;vp-&gt;vlru))
! 	return;
! 
!     VLRU_Wait_r(&amp;volume_LRU.q[VLRU_QUEUE_NEW]);
! 
!     /* repeat check since VLRU_Wait_r may have dropped
!      * the glock */
!     if (queue_IsNotOnQueue(&amp;vp-&gt;vlru)) {
! 	idx = vp-&gt;vlru.idx;
! 	if ((idx &lt; 0) || (idx &gt;= VLRU_QUEUE_INVALID)) {
! 	    idx = vp-&gt;vlru.idx = VLRU_QUEUE_NEW;
! 	}
! 	queue_Prepend(&amp;volume_LRU.q[idx], &amp;vp-&gt;vlru);
! 	volume_LRU.q[idx].len++;
! 	V_attachFlags(vp) |= VOL_ON_VLRU;
! 	vp-&gt;stats.last_promote = FT_ApproxTime();
!     }
! }
! 
! /* delete volume from VLRU 
!  * caller MUST hold a ref count on vp */
! static void
! VLRU_Delete_r(volatile Volume * vp)
! {
!     int idx;
! 
!     if (!VLRU_enabled)
! 	return;
! 
!     if (queue_IsNotOnQueue(&amp;vp-&gt;vlru))
! 	return;
! 
!     /* handle races */
!     do {
!       idx = vp-&gt;vlru.idx;
!       if (idx == VLRU_QUEUE_INVALID)
! 	  return;
!       VLRU_Wait_r(&amp;volume_LRU.q[idx]);
!     } while (idx != vp-&gt;vlru.idx);
! 
!     /* now remove from the VLRU and update 
!      * the appropriate counter */
!     queue_Remove(&amp;vp-&gt;vlru);
!     volume_LRU.q[idx].len--;
!     vp-&gt;vlru.idx = VLRU_QUEUE_INVALID;
!     V_attachFlags(vp) &amp;= ~(VOL_ON_VLRU);
! }
! 
! /* signal that volume was just accessed.
!  * caller MUST hold a ref count on vp */
! static void
! VLRU_UpdateAccess_r(volatile Volume * vp)
! {
!     afs_uint32 live_interval;
!     Volume * rvp = NULL;
! 
!     if (!VLRU_enabled)
! 	return;
! 
!     if (queue_IsNotOnQueue(&amp;vp-&gt;vlru))
! 	return;
! 
!     assert(V_attachFlags(vp) &amp; VOL_ON_VLRU);
! 
!     /* update the access timestamp */
!     vp-&gt;stats.last_get = FT_ApproxTime();
! 
!     /*
!      * if the volume is on the soft detach candidate
!      * list, we need to safely move it back to a
!      * regular generation.  this has to be done
!      * carefully so we don't race against the scanner
!      * thread.
!      */
! 
!     /* if this volume is on the soft detach candidate queue,
!      * then grab exclusive access to the necessary queues */
!     if (vp-&gt;vlru.idx == VLRU_QUEUE_CANDIDATE) {
! 	rvp = vp;
! 	VCreateReservation_r(rvp);
! 
! 	VLRU_Wait_r(&amp;volume_LRU.q[VLRU_QUEUE_NEW]);
! 	VLRU_BeginExclusive_r(&amp;volume_LRU.q[VLRU_QUEUE_NEW]);
! 	VLRU_Wait_r(&amp;volume_LRU.q[VLRU_QUEUE_CANDIDATE]);
! 	VLRU_BeginExclusive_r(&amp;volume_LRU.q[VLRU_QUEUE_CANDIDATE]);
!     }
! 
!     /* make sure multiple threads don't race to update */
!     if (vp-&gt;vlru.idx == VLRU_QUEUE_CANDIDATE) {
! 	VLRU_SwitchQueues(vp, VLRU_QUEUE_NEW, 1);
!     }
! 
!     if (rvp) {
!       VLRU_EndExclusive_r(&amp;volume_LRU.q[VLRU_QUEUE_CANDIDATE]);
!       VLRU_EndExclusive_r(&amp;volume_LRU.q[VLRU_QUEUE_NEW]);
!       VCancelReservation_r(rvp);
!     }
! }
! 
! /* switch a volume between two VLRU queues */
! static void
! VLRU_SwitchQueues(volatile Volume * vp, int new_idx, int append)
! {
!     if (queue_IsNotOnQueue(&amp;vp-&gt;vlru))
! 	return;
! 
!     queue_Remove(&amp;vp-&gt;vlru);
!     volume_LRU.q[vp-&gt;vlru.idx].len--;
!     
!     /* put the volume back on the correct generational queue */
!     if (append) {
! 	queue_Append(&amp;volume_LRU.q[new_idx], &amp;vp-&gt;vlru);
!     } else {
! 	queue_Prepend(&amp;volume_LRU.q[new_idx], &amp;vp-&gt;vlru);
!     }
! 
!     volume_LRU.q[new_idx].len++;
!     vp-&gt;vlru.idx = new_idx;
! }
! 
! /* VLRU GC thread */
! static void *
! VLRU_ScannerThread(void * args)
! {
!     afs_uint32 now, min_delay, delay;
!     afs_uint32 next_scan[VLRU_GENERATIONS];
!     afs_uint32 next_promotion[VLRU_GENERATIONS];
!     int i, min_idx, min_op, overdue, state;
! 
!     /* set t=0 for promotion cycle to be 
!      * fileserver startup */
!     now = FT_ApproxTime();
!     for (i=0; i &lt; VLRU_GENERATIONS-1; i++) {
! 	volume_LRU.last_promotion[i] = now;
!     }
! 
!     /* don't start the scanner until VLRU_offline_thresh
!      * plus a small delay for VInitVolumePackage to finish
!      * has gone by */
! 
!     sleep(VLRU_offline_thresh + 60);
! 
!     /* set t=0 for scan cycle to be now */
!     now = FT_ApproxTime();
!     for (i=0; i &lt; VLRU_GENERATIONS+1; i++) {
! 	volume_LRU.last_scan[i] = now;
!     }
! 
!     VOL_LOCK;
!     if (volume_LRU.scanner_state == VLRU_SCANNER_STATE_OFFLINE) {
! 	volume_LRU.scanner_state = VLRU_SCANNER_STATE_ONLINE;
!     }
! 
!     while ((state = volume_LRU.scanner_state) != VLRU_SCANNER_STATE_SHUTTING_DOWN) {
! 	/* check to see if we've been asked to pause */
! 	if (volume_LRU.scanner_state == VLRU_SCANNER_STATE_PAUSING) {
! 	    volume_LRU.scanner_state = VLRU_SCANNER_STATE_PAUSED;
! 	    assert(pthread_cond_broadcast(&amp;volume_LRU.cv) == 0);
! 	    do {
! 		assert(pthread_cond_wait(&amp;volume_LRU.cv, &amp;vol_glock_mutex) == 0);
! 	    } while (volume_LRU.scanner_state == VLRU_SCANNER_STATE_PAUSED);
! 	}
! 
! 	/* scheduling can happen outside the glock */
! 	VOL_UNLOCK;
! 
! 	/* figure out what is next on the schedule */
! 
! 	/* figure out a potential schedule for the new generation first */
! 	overdue = 0;
! 	min_delay = volume_LRU.scan_interval[0] + volume_LRU.last_scan[0] - now;
! 	min_idx = 0;
! 	min_op = 0;
! 	if (min_delay &gt; volume_LRU.scan_interval[0]) {
! 	    /* unsigned overflow -- we're overdue to run this scan */
! 	    min_delay = 0;
! 	    overdue = 1;
! 	}
! 
! 	/* if we're not overdue for gen 0, figure out schedule for candidate gen */
! 	if (!overdue) {
! 	    i = VLRU_QUEUE_CANDIDATE;
! 	    delay = volume_LRU.scan_interval[i] + volume_LRU.last_scan[i] - now;
! 	    if (delay &lt; min_delay) {
! 		min_delay = delay;
! 		min_idx = i;
! 	    }
! 	    if (delay &gt; volume_LRU.scan_interval[i]) {
! 		/* unsigned overflow -- we're overdue to run this scan */
! 		min_delay = 0;
! 		min_idx = i;
! 		overdue = 1;
! 		break;
! 	    }
! 	}
! 
! 	/* if we're still not overdue for something, figure out schedules for promotions */
! 	for (i=0; !overdue &amp;&amp; i &lt; VLRU_GENERATIONS-1; i++) {
! 	    delay = volume_LRU.promotion_interval[i] + volume_LRU.last_promotion[i] - now;
! 	    if (delay &lt; min_delay) {
! 		min_delay = delay;
! 		min_idx = i;
! 		min_op = 1;
! 	    }
! 	    if (delay &gt; volume_LRU.promotion_interval[i]) {
! 		/* unsigned overflow -- we're overdue to run this promotion */
! 		min_delay = 0;
! 		min_idx = i;
! 		min_op = 1;
! 		overdue = 1;
! 		break;
! 	    }
! 	}
! 
! 	/* sleep as needed */
! 	if (min_delay) {
! 	    sleep(min_delay);
! 	}
! 
! 	/* do whatever is next */
! 	VOL_LOCK;
! 	if (min_op) {
! 	    VLRU_Promote_r(min_idx);
! 	    VLRU_Demote_r(min_idx+1);
! 	} else {
! 	    VLRU_Scan_r(min_idx);
! 	}
! 	now = FT_ApproxTime();
!     }
! 
!     Log("VLRU scanner asked to go offline (scanner_state=%d)\n", state);
! 
!     /* signal that scanner is down */
!     volume_LRU.scanner_state = VLRU_SCANNER_STATE_OFFLINE;
!     assert(pthread_cond_broadcast(&amp;volume_LRU.cv) == 0);
!     VOL_UNLOCK;
!     return NULL;
! }
! 
! /* run the promotions */
! static void
! VLRU_Promote_r(int idx)
! {
!     int len, chaining, promote;
!     afs_uint32 now, thresh;
!     struct rx_queue *qp, *nqp;
!     Volume * vp, *start, *end;
! 
!     /* get exclusive access to two chains, and drop the glock */
!     VLRU_Wait_r(&amp;volume_LRU.q[idx]);
!     VLRU_BeginExclusive_r(&amp;volume_LRU.q[idx]);
!     VLRU_Wait_r(&amp;volume_LRU.q[idx+1]);
!     VLRU_BeginExclusive_r(&amp;volume_LRU.q[idx+1]);
!     VOL_UNLOCK;
! 
!     thresh = volume_LRU.promotion_interval[idx];
!     now = FT_ApproxTime();
! 
!     len = chaining = 0;
!     for (queue_ScanBackwards(&amp;volume_LRU.q[idx], qp, nqp, rx_queue)) {
! 	vp = (Volume *)((char *)qp - offsetof(Volume, vlru));
! 	promote = (((vp-&gt;stats.last_promote + thresh) &lt;= now) &amp;&amp;
! 		   (vp-&gt;stats.last_get &gt;= vp-&gt;stats.last_promote));
! 
! 	if (chaining) {
! 	    if (promote) {
! 		vp-&gt;vlru.idx++;
! 		len++;
! 		start = vp;
! 	    } else {
! 		/* promote and prepend chain */
! 		queue_MoveChainAfter(&amp;volume_LRU.q[idx+1], &amp;start-&gt;vlru, &amp;end-&gt;vlru);
! 		chaining = 0;
! 	    }
! 	} else {
! 	    if (promote) {
! 		vp-&gt;vlru.idx++;
! 		len++;
! 		chaining = 1;
! 		start = end = vp;
! 	    }
! 	}
!     }
! 
!     if (chaining) {
! 	/* promote and prepend */
! 	queue_MoveChainAfter(&amp;volume_LRU.q[idx+1], &amp;start-&gt;vlru, &amp;end-&gt;vlru);
!     }
! 
!     if (len) {
! 	volume_LRU.q[idx].len -= len;
! 	volume_LRU.q[idx+1].len += len;
!     }
! 
!     /* release exclusive access to the two chains */
!     VOL_LOCK;
!     volume_LRU.last_promotion[idx] = now;
!     VLRU_EndExclusive_r(&amp;volume_LRU.q[idx+1]);
!     VLRU_EndExclusive_r(&amp;volume_LRU.q[idx]);
! }
! 
! /* run the demotions */
! static void
! VLRU_Demote_r(int idx)
! {
!     Error ec;
!     int len, chaining, demote;
!     afs_uint32 now, thresh;
!     struct rx_queue *qp, *nqp;
!     Volume * vp, *start, *end;
!     Volume ** salv_flag_vec = NULL;
!     int salv_vec_offset = 0;
! 
!     assert(idx == VLRU_QUEUE_MID || idx == VLRU_QUEUE_OLD);
! 
!     /* get exclusive access to two chains, and drop the glock */
!     VLRU_Wait_r(&amp;volume_LRU.q[idx-1]);
!     VLRU_BeginExclusive_r(&amp;volume_LRU.q[idx-1]);
!     VLRU_Wait_r(&amp;volume_LRU.q[idx]);
!     VLRU_BeginExclusive_r(&amp;volume_LRU.q[idx]);
!     VOL_UNLOCK;
! 
!     /* no big deal if this allocation fails */
!     if (volume_LRU.q[idx].len) {
! 	salv_flag_vec = (Volume **) malloc(volume_LRU.q[idx].len * sizeof(Volume *));
!     }
! 
!     now = FT_ApproxTime();
!     thresh = volume_LRU.promotion_interval[idx-1];
! 
!     len = chaining = 0;
!     for (queue_ScanBackwards(&amp;volume_LRU.q[idx], qp, nqp, rx_queue)) {
! 	vp = (Volume *)((char *)qp - offsetof(Volume, vlru));
! 	demote = (((vp-&gt;stats.last_promote + thresh) &lt;= now) &amp;&amp;
! 		  (vp-&gt;stats.last_get &lt; (now - thresh)));
! 
! 	/* we now do volume update list DONT_SALVAGE flag setting during
! 	 * demotion passes */
! 	if (salv_flag_vec &amp;&amp;
! 	    !(V_attachFlags(vp) &amp; VOL_HDR_DONTSALV) &amp;&amp;
! 	    demote &amp;&amp; 
! 	    (vp-&gt;updateTime &lt; (now - SALVAGE_INTERVAL)) &amp;&amp;
! 	    (V_attachState(vp) == VOL_STATE_ATTACHED)) {
! 	    salv_flag_vec[salv_vec_offset++] = vp;
! 	    VCreateReservation_r(vp);
! 	}
! 
! 	if (chaining) {
! 	    if (demote) {
! 		vp-&gt;vlru.idx--;
! 		len++;
! 		start = vp;
! 	    } else {
! 		/* demote and append chain */
! 		queue_MoveChainBefore(&amp;volume_LRU.q[idx-1], &amp;start-&gt;vlru, &amp;end-&gt;vlru);
! 		chaining = 0;
! 	    }
! 	} else {
! 	    if (demote) {
! 		vp-&gt;vlru.idx--;
! 		len++;
! 		chaining = 1;
! 		start = end = vp;
! 	    }
! 	}
!     }
! 
!     if (chaining) {
! 	queue_MoveChainBefore(&amp;volume_LRU.q[idx-1], &amp;start-&gt;vlru, &amp;end-&gt;vlru);
!     }
! 
!     if (len) {
! 	volume_LRU.q[idx].len -= len;
! 	volume_LRU.q[idx-1].len += len;
!     }
! 
!     /* release exclusive access to the two chains */
!     VOL_LOCK;
!     VLRU_EndExclusive_r(&amp;volume_LRU.q[idx]);
!     VLRU_EndExclusive_r(&amp;volume_LRU.q[idx-1]);
! 
!     /* now go back and set the DONT_SALVAGE flags as appropriate */
!     if (salv_flag_vec) {
! 	int i;
! 	for (i = 0; i &lt; salv_vec_offset; i++) {
! 	    vp = salv_flag_vec[i];
! 	    if (!(V_attachFlags(vp) &amp; VOL_HDR_DONTSALV) &amp;&amp;
! 		(vp-&gt;updateTime &lt; (now - SALVAGE_INTERVAL)) &amp;&amp;
! 		(V_attachState(vp) == VOL_STATE_ATTACHED)) {
! 		ec = VHold_r(vp);
! 		if (!ec) {
! 		    V_attachFlags(vp) |= VOL_HDR_DONTSALV;
! 		    V_dontSalvage(vp) = DONT_SALVAGE;
! 		    VUpdateVolume_r(&amp;ec, vp, 0);
! 		    VPutVolume_r(vp);
! 		}
! 	    }
! 	    VCancelReservation_r(vp);
! 	}
! 	free(salv_flag_vec);
!     }
! }
! 
! /* run a pass of the VLRU GC scanner */
! static void
! VLRU_Scan_r(int idx)
! {
!     afs_uint32 now, thresh;
!     struct rx_queue *qp, *nqp;
!     volatile Volume * vp;
!     int i, locked = 1;
! 
!     assert(idx == VLRU_QUEUE_NEW || idx == VLRU_QUEUE_CANDIDATE);
! 
!     /* gain exclusive access to the idx VLRU */
!     VLRU_Wait_r(&amp;volume_LRU.q[idx]);
!     VLRU_BeginExclusive_r(&amp;volume_LRU.q[idx]);
! 
!     if (idx != VLRU_QUEUE_CANDIDATE) {
! 	/* gain exclusive access to the candidate VLRU */
! 	VLRU_Wait_r(&amp;volume_LRU.q[VLRU_QUEUE_CANDIDATE]);
! 	VLRU_BeginExclusive_r(&amp;volume_LRU.q[VLRU_QUEUE_CANDIDATE]);
!     }
! 
!     now = FT_ApproxTime();
!     thresh = now - VLRU_offline_thresh;
! 
!     /* perform candidate selection and soft detaching */
!     if (idx == VLRU_QUEUE_CANDIDATE) {
! 	/* soft detach some volumes from the candidate pool */
! 	VOL_UNLOCK;
! 	locked = 0;
! 
! 	for (i=0,queue_ScanBackwards(&amp;volume_LRU.q[idx], qp, nqp, rx_queue)) {
! 	    vp = (Volume *)((char *)qp - offsetof(Volume, vlru));
! 	    if (i &gt;= VLRU_offline_max) {
! 		break;
! 	    }
! 	    /* check timestamp to see if it's a candidate for soft detaching */
! 	    if (vp-&gt;stats.last_get &lt;= thresh) {
! 		VOL_LOCK;
! 		if (VCheckSoftDetach(vp, thresh))
! 		    i++;
! 		VOL_UNLOCK;
! 	    }
! 	}
!     } else {
! 	/* scan for volumes to become soft detach candidates */
! 	for (i=1,queue_ScanBackwards(&amp;volume_LRU.q[idx], qp, nqp, rx_queue),i++) {
! 	    vp = (Volume *)((char *)qp - offsetof(Volume, vlru));
! 
! 	    /* check timestamp to see if it's a candidate for soft detaching */
! 	    if (vp-&gt;stats.last_get &lt;= thresh) {
! 		VCheckSoftDetachCandidate(vp, thresh);
! 	    }
! 
! 	    if (!(i&amp;0x7f)) {   /* lock coarsening optimization */
! 		VOL_UNLOCK;
! 		pthread_yield();
! 		VOL_LOCK;
! 	    }
! 	}
!     }
! 
!     /* relinquish exclusive access to the VLRU chains */
!     if (!locked) {
! 	VOL_LOCK;
!     }
!     volume_LRU.last_scan[idx] = now;
!     if (idx != VLRU_QUEUE_CANDIDATE) {
! 	VLRU_EndExclusive_r(&amp;volume_LRU.q[VLRU_QUEUE_CANDIDATE]);
!     }
!     VLRU_EndExclusive_r(&amp;volume_LRU.q[idx]);
! }
! 
! /* check whether volume is safe to soft detach
!  * caller MUST NOT hold a ref count on vp */
! static int
! VCheckSoftDetach(volatile Volume * vp, afs_uint32 thresh)
! {
!     int ret=0;
! 
!     if (vp-&gt;nUsers || vp-&gt;nWaiters)
! 	return 0;
! 
!     if (vp-&gt;stats.last_get &lt;= thresh) {
! 	ret = VSoftDetachVolume_r(vp, thresh);
!     }
! 
!     return ret;
! }
! 
! /* check whether volume should be made a 
!  * soft detach candidate */
! static int
! VCheckSoftDetachCandidate(volatile Volume * vp, afs_uint32 thresh)
! {
!     int idx, ret = 0;
!     if (vp-&gt;nUsers || vp-&gt;nWaiters)
! 	return 0;
! 
!     idx = vp-&gt;vlru.idx;
! 
!     assert(idx == VLRU_QUEUE_NEW);
! 
!     if (vp-&gt;stats.last_get &lt;= thresh) {
! 	/* move to candidate pool */
! 	queue_Remove(&amp;vp-&gt;vlru);
! 	volume_LRU.q[VLRU_QUEUE_NEW].len--;
! 	queue_Prepend(&amp;volume_LRU.q[VLRU_QUEUE_CANDIDATE], &amp;vp-&gt;vlru);
! 	vp-&gt;vlru.idx = VLRU_QUEUE_CANDIDATE;
! 	volume_LRU.q[VLRU_QUEUE_CANDIDATE].len++;
! 	ret = 1;
!     }
! 
!     return ret;
! }
! 
! 
! /* begin exclusive access on VLRU */
! static void
! VLRU_BeginExclusive_r(struct VLRU_q * q)
! {
!     assert(q-&gt;busy == 0);
!     q-&gt;busy = 1;
! }
! 
! /* end exclusive access on VLRU */
! static void
! VLRU_EndExclusive_r(struct VLRU_q * q)
! {
!     assert(q-&gt;busy);
!     q-&gt;busy = 0;
!     assert(pthread_cond_broadcast(&amp;q-&gt;cv) == 0);
! }
! 
! /* wait for another thread to end exclusive access on VLRU */
! static void
! VLRU_Wait_r(struct VLRU_q * q)
! {
!     while(q-&gt;busy) {
! 	assert(pthread_cond_wait(&amp;q-&gt;cv, &amp;vol_glock_mutex) == 0);
!     }
! }
! 
! /* demand attach fs
!  * volume soft detach
!  *
!  * caller MUST NOT hold a ref count on vp */
! static int
! VSoftDetachVolume_r(volatile Volume * vp, afs_uint32 thresh)
! {
!     afs_uint32 ts_save;
!     int ret = 0;
! 
!     assert(vp-&gt;vlru.idx == VLRU_QUEUE_CANDIDATE);
! 
!     ts_save = vp-&gt;stats.last_get;
!     if (ts_save &gt; thresh)
! 	return 0;
! 
!     if (vp-&gt;nUsers || vp-&gt;nWaiters)
! 	return 0;
! 
!     if (IsExclusiveState(V_attachState(vp))) {
! 	return 0;
!     }
! 
!     switch (V_attachState(vp)) {
!     case VOL_STATE_UNATTACHED:
!     case VOL_STATE_PREATTACHED:
!     case VOL_STATE_ERROR:
!     case VOL_STATE_GOING_OFFLINE:
!     case VOL_STATE_SHUTTING_DOWN:
!     case VOL_STATE_SALVAGING:
! 	volume_LRU.q[vp-&gt;vlru.idx].len--;
! 
! 	/* create and cancel a reservation to
! 	 * give the volume an opportunity to
! 	 * be deallocated */
! 	VCreateReservation_r(vp);
! 	queue_Remove(&amp;vp-&gt;vlru);
! 	vp-&gt;vlru.idx = VLRU_QUEUE_INVALID;
! 	V_attachFlags(vp) &amp;= ~(VOL_ON_VLRU);
! 	VCancelReservation_r(vp);
! 	return 0;
!     }
! 
!     /* hold the volume and take it offline.
!      * no need for reservations, as VHold_r
!      * takes care of that internally. */
!     if (VHold_r(vp) == 0) {
! 	/* vhold drops the glock, so now we should
! 	 * check to make sure we aren't racing against
! 	 * other threads.  if we are racing, offlining vp
! 	 * would be wasteful, and block the scanner for a while 
! 	 */
! 	if (vp-&gt;nWaiters || 
! 	    (vp-&gt;nUsers &gt; 1) ||
! 	    (vp-&gt;shuttingDown) ||
! 	    (vp-&gt;goingOffline) ||
! 	    (vp-&gt;stats.last_get != ts_save)) {
! 	    /* looks like we're racing someone else. bail */
  	    VPutVolume_r(vp);
! 	    vp = NULL;
! 	} else {
! 	    /* pull it off the VLRU */
! 	    assert(vp-&gt;vlru.idx == VLRU_QUEUE_CANDIDATE);
! 	    volume_LRU.q[VLRU_QUEUE_CANDIDATE].len--;
! 	    queue_Remove(&amp;vp-&gt;vlru);
! 	    vp-&gt;vlru.idx = VLRU_QUEUE_INVALID;
! 	    V_attachFlags(vp) &amp;= ~(VOL_ON_VLRU);
! 
! 	    /* take if offline */
! 	    VOffline_r(vp, "volume has been soft detached");
! 
! 	    /* invalidate the volume header cache */
! 	    FreeVolumeHeader(vp);
! 
! 	    /* update stats */
! 	    IncUInt64(&amp;VStats.soft_detaches);
! 	    vp-&gt;stats.soft_detaches++;
! 
! 	    /* put in pre-attached state so demand
! 	     * attacher can work on it */
! 	    VChangeState_r(vp, VOL_STATE_PREATTACHED);
! 	    ret = 1;
! 	}
      }
!     return ret;
  }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  
  /***************************************************/
! /* Volume Header Cache routines                    */
  /***************************************************/
  
! struct volume_hdr_LRU_t volume_hdr_LRU;
  
  /* Allocate a bunch of headers; string them together */
  static void
! VInitVolumeHeaderCache(afs_uint32 howMany)
  {
      register struct volHeader *hp;
      if (programType != fileServer)
  	return;
+     queue_Init(&amp;volume_hdr_LRU);
+ #ifdef AFS_DEMAND_ATTACH_FS
+     volume_hdr_LRU.stats.free = 0;
+     volume_hdr_LRU.stats.used = howMany;
+     volume_hdr_LRU.stats.attached = 0;
+ #endif
      hp = (struct volHeader *)(calloc(howMany, sizeof(struct volHeader)));
      while (howMany--)
  	ReleaseVolumeHeader(hp++);
  }
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /* Get a volume header from the LRU list; update the old one if necessary */
+ /* Returns 1 if there was already a header, which is removed from the LRU list */
+ /* caller MUST has a ref count on vp */
+ static int
+ GetVolumeHeader(register Volume * vp)
+ {
+     Error error;
+     register struct volHeader *hd;
+     int old;
+     static int everLogged = 0;
+ 
+     /* XXX debug 9/19/05 we've apparently got
+      * a ref counting bug somewhere that's
+      * breaking the nUsers == 0 =&gt; header on LRU
+      * assumption */
+     if (vp-&gt;header &amp;&amp; queue_IsNotOnQueue(vp-&gt;header)) {
+ 	Log("nUsers == 0, but header not on LRU\n");
+ 	return 1;
+     }
+ 
+     old = (vp-&gt;header != NULL);	/* old == volume already has a header */
+ 
+     if (programType != fileServer) {
+ 	/* for volume utilities, we allocate volHeaders as needed */
+ 	if (!vp-&gt;header) {
+ 	    hd = (struct volHeader *)calloc(1, sizeof(*vp-&gt;header));
+ 	    assert(hd != NULL);
+ 	    vp-&gt;header = hd;
+ 	    hd-&gt;back = vp;
+ 	    V_attachFlags(vp) |= VOL_HDR_ATTACHED;
+ 	}
+     } else {
+ 	if (old) {
+ 	    /* the header we previously dropped in the lru is
+ 	     * still available. pull it off the lru and return */
+ 	    hd = vp-&gt;header;
+ 	    queue_Remove(hd);
+ 	    assert(hd-&gt;back == vp);
+ 	} else {
+ 	    /* we need to grab a new element off the LRU */
+ 	    if (queue_IsNotEmpty(&amp;volume_hdr_LRU)) {
+ 		/* grab an element and pull off of LRU */
+ 		hd = queue_First(&amp;volume_hdr_LRU, volHeader);
+ 		queue_Remove(hd);
+ 	    } else {
+ 		/* LRU is empty, so allocate a new volHeader 
+ 		 * this is probably indicative of a leak, so let the user know */
+ 		hd = (struct volHeader *)calloc(1, sizeof(struct volHeader));
+ 		assert(hd != NULL);
+ 		if (!everLogged) {
+ 		    Log("****Allocated more volume headers, probably leak****\n");
+ 		    everLogged = 1;
+ 		}
+ 		volume_hdr_LRU.stats.free++;
+ 	    }
+ 	    if (hd-&gt;back) {
+ 		VolState vp_save, back_save;
+ 		/* this header used to belong to someone else. 
+ 		 * we'll need to check if the header needs to
+ 		 * be sync'd out to disk */
+ 
+ 		/* if hd-&gt;back were in an exclusive state, then
+ 		 * its volHeader would not be on the LRU... */
+ 		assert(!IsExclusiveState(V_attachState(hd-&gt;back)));
+ 
+ 		if (hd-&gt;diskstuff.inUse) {
+ 		    /* volume was in use, so we'll need to sync
+ 		     * its header to disk */
+ 		    back_save = VChangeState_r(hd-&gt;back, VOL_STATE_UPDATING);
+ 		    vp_save = VChangeState_r(vp, VOL_STATE_HDR_ATTACHING);
+ 		    VCreateReservation_r(hd-&gt;back);
+ 		    VOL_UNLOCK;
+ 
+ 		    WriteVolumeHeader_r(&amp;error, hd-&gt;back);
+ 		    /* Ignore errors; catch them later */
+ 
+ 		    VOL_LOCK;
+ 		}
+ 
+ 		V_attachFlags(hd-&gt;back) &amp;= ~(VOL_HDR_ATTACHED | VOL_HDR_LOADED | VOL_HDR_IN_LRU);
+ 		hd-&gt;back-&gt;header = NULL;
+ 
+ 		if (hd-&gt;diskstuff.inUse) {
+ 		    VChangeState_r(hd-&gt;back, back_save);
+ 		    VCancelReservation_r(hd-&gt;back);
+ 		    VChangeState_r(vp, vp_save);
+ 		}
+ 	    } else {
+ 		volume_hdr_LRU.stats.attached++;
+ 	    }
+ 	    hd-&gt;back = vp;
+ 	    vp-&gt;header = hd;
+ 	    V_attachFlags(vp) |= VOL_HDR_ATTACHED;
+ 	}
+ 	volume_hdr_LRU.stats.free--;
+ 	volume_hdr_LRU.stats.used++;
+     }
+     IncUInt64(&amp;VStats.hdr_gets);
+     IncUInt64(&amp;vp-&gt;stats.hdr_gets);
+     vp-&gt;stats.last_hdr_get = FT_ApproxTime();
+     return old;
+ }
+ #else /* AFS_DEMAND_ATTACH_FS */
  /* Get a volume header from the LRU list; update the old one if necessary */
  /* Returns 1 if there was already a header, which is removed from the LRU list */
  static int
***************
*** 1932,1938 ****
--- 5480,5488 ----
      static int everLogged = 0;
  
      old = (vp-&gt;header != NULL);	/* old == volume already has a header */
+ 
      if (programType != fileServer) {
+ 	/* for volume utilities, we allocate volHeaders as needed */
  	if (!vp-&gt;header) {
  	    hd = (struct volHeader *)calloc(1, sizeof(*vp-&gt;header));
  	    assert(hd != NULL);
***************
*** 1940,1984 ****
  	    hd-&gt;back = vp;
  	}
      } else {
  	if (old) {
  	    hd = vp-&gt;header;
! 	    if (volumeLRU == hd)
! 		volumeLRU = hd-&gt;next;
  	    assert(hd-&gt;back == vp);
  	} else {
! 	    if (volumeLRU)
! 		/* not currently in use and least recently used */
! 		hd = volumeLRU-&gt;prev;
! 	    else {
! 		hd = (struct volHeader *)calloc(1, sizeof(*vp-&gt;header));
! 		/* make it look like single elt LRU */
! 		hd-&gt;prev = hd-&gt;next = hd;
  		if (!everLogged) {
  		    Log("****Allocated more volume headers, probably leak****\n");
  		    everLogged = 1;
  		}
  	    }
  	    if (hd-&gt;back) {
  		if (hd-&gt;diskstuff.inUse) {
  		    WriteVolumeHeader_r(&amp;error, hd-&gt;back);
  		    /* Ignore errors; catch them later */
  		}
! 		hd-&gt;back-&gt;header = 0;
  	    }
  	    hd-&gt;back = vp;
  	    vp-&gt;header = hd;
  	}
- 	if (hd-&gt;next) {		/* hd-&gt;next != 0 --&gt; in LRU chain (we zero it later) */
- 	    hd-&gt;prev-&gt;next = hd-&gt;next;	/* pull hd out of LRU list */
- 	    hd-&gt;next-&gt;prev = hd-&gt;prev;	/* if hd only element, this is noop */
- 	}
- 	hd-&gt;next = hd-&gt;prev = 0;
- 	/* if not in LRU chain, next test won't be true */
- 	if (hd == volumeLRU)	/* last header item, turn into empty list */
- 	    volumeLRU = NULL;
      }
      return old;
  }
  
  /* Put it at the top of the LRU chain */
  static void
--- 5490,5587 ----
  	    hd-&gt;back = vp;
  	}
      } else {
+ 	/* for the fileserver, we keep a volume header cache */
  	if (old) {
+ 	    /* the header we previously dropped in the lru is
+ 	     * still available. pull it off the lru and return */
  	    hd = vp-&gt;header;
! 	    queue_Remove(hd);
  	    assert(hd-&gt;back == vp);
  	} else {
! 	    /* we need to grab a new element off the LRU */
! 	    if (queue_IsNotEmpty(&amp;volume_hdr_LRU)) {
! 		/* grab an element */
! 		hd = queue_First(&amp;volume_hdr_LRU, volHeader);
! 		queue_Remove(hd);
! 	    } else {
! 		/* LRU is empty, so allocate a new volHeader 
! 		 * this is probably indicative of a leak, so let the user know */
! 		hd = (struct volHeader *)calloc(1, sizeof(struct volHeader));
! 		assert(hd != NULL);
  		if (!everLogged) {
  		    Log("****Allocated more volume headers, probably leak****\n");
  		    everLogged = 1;
  		}
  	    }
  	    if (hd-&gt;back) {
+ 		/* this header used to belong to someone else. 
+ 		 * we'll need to check if the header needs to
+ 		 * be sync'd out to disk */
+ 
  		if (hd-&gt;diskstuff.inUse) {
  		    WriteVolumeHeader_r(&amp;error, hd-&gt;back);
  		    /* Ignore errors; catch them later */
  		}
! 		hd-&gt;back-&gt;header = NULL;
  	    }
  	    hd-&gt;back = vp;
  	    vp-&gt;header = hd;
  	}
      }
      return old;
  }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ 
+ /* make sure a volume header is attached to
+  * vp, and has the correct data loaded from
+  * disk. */
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /* caller MUST hold a ref count on vp */
+ static void
+ LoadVolumeHeader(Error * ec, Volume * vp)
+ {
+     VolState state_save;
+     *ec = 0;
+ 
+     if (vp-&gt;nUsers == 0 &amp;&amp; !GetVolumeHeader(vp)) {
+ 	IncUInt64(&amp;VStats.hdr_loads);
+ 	state_save = VChangeState_r(vp, VOL_STATE_HDR_LOADING);
+ 	VOL_UNLOCK;
+ 
+ 	ReadHeader(ec, V_diskDataHandle(vp), (char *)&amp;V_disk(vp),
+ 		   sizeof(V_disk(vp)), VOLUMEINFOMAGIC,
+ 		   VOLUMEINFOVERSION);
+ 	IncUInt64(&amp;vp-&gt;stats.hdr_loads);
+ 
+ 	VOL_LOCK;
+ 	if (!*ec)
+ 	    V_attachFlags(vp) |= VOL_HDR_LOADED;
+ 	VChangeState_r(vp, state_save);
+     }
+     if (*ec) {
+ 	/* maintain (nUsers==0) =&gt; header in LRU invariant */
+ 	ReleaseVolumeHeader(vp-&gt;header);
+     }
+ }
+ #else /* AFS_DEMAND_ATTACH_FS */
+ static void
+ LoadVolumeHeader(Error * ec, Volume * vp)
+ {
+     *ec = 0;
+     if (vp-&gt;nUsers == 0 &amp;&amp; !GetVolumeHeader(vp)) {
+ 	IncUInt64(&amp;VStats.hdr_loads);
+ 
+ 	ReadHeader(ec, V_diskDataHandle(vp), (char *)&amp;V_disk(vp),
+ 		   sizeof(V_disk(vp)), VOLUMEINFOMAGIC,
+ 		   VOLUMEINFOVERSION);
+     }
+     if (*ec) {
+ 	/* maintain (nUsers==0) =&gt; header in LRU invariant */
+ 	ReleaseVolumeHeader(vp-&gt;header);
+     }
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
  /* Put it at the top of the LRU chain */
  static void
***************
*** 1986,2003 ****
  {
      if (programType != fileServer)
  	return;
!     if (!hd || hd-&gt;next)	/* no header, or header already released */
  	return;
!     if (!volumeLRU) {
! 	hd-&gt;next = hd-&gt;prev = hd;
!     } else {
! 	hd-&gt;prev = volumeLRU-&gt;prev;
! 	hd-&gt;next = volumeLRU;
! 	hd-&gt;prev-&gt;next = hd-&gt;next-&gt;prev = hd;
      }
!     volumeLRU = hd;
  }
  
  static void
  FreeVolumeHeader(register Volume * vp)
  {
--- 5589,5610 ----
  {
      if (programType != fileServer)
  	return;
!     if (!hd || queue_IsOnQueue(hd))	/* no header, or header already released */
  	return;
!     queue_Append(&amp;volume_hdr_LRU, hd);
! #ifdef AFS_DEMAND_ATTACH_FS
!     if (hd-&gt;back) {
! 	V_attachFlags(hd-&gt;back) |= VOL_HDR_IN_LRU;
      }
!     volume_hdr_LRU.stats.free++;
!     volume_hdr_LRU.stats.used--;
! #endif
  }
  
+ /* for fileserver, return header to LRU, and
+  * invalidate it as a cache entry.
+  *
+  * for volume utilities, free the heap space */
  static void
  FreeVolumeHeader(register Volume * vp)
  {
***************
*** 2006,2062 ****
  	return;
      if (programType == fileServer) {
  	ReleaseVolumeHeader(hd);
! 	hd-&gt;back = 0;
      } else {
  	free(hd);
      }
!     vp-&gt;header = 0;
  }
  
  
  /***************************************************/
! /* Routines to add volume to hash chain, delete it */
  /***************************************************/
  
  static void
  AddVolumeToHashTable(register Volume * vp, int hashid)
  {
!     int hash = VOLUME_HASH(hashid);
      vp-&gt;hashid = hashid;
!     vp-&gt;hashNext = VolumeHashTable[hash];
!     VolumeHashTable[hash] = vp;
      vp-&gt;vnodeHashOffset = VolumeHashOffset_r();
  }
  
  static void
  DeleteVolumeFromHashTable(register Volume * vp)
  {
!     int hash = VOLUME_HASH(vp-&gt;hashid);
!     if (VolumeHashTable[hash] == vp)
! 	VolumeHashTable[hash] = vp-&gt;hashNext;
!     else {
! 	Volume *tvp = VolumeHashTable[hash];
! 	if (tvp == NULL)
! 	    return;
! 	while (tvp-&gt;hashNext &amp;&amp; tvp-&gt;hashNext != vp)
! 	    tvp = tvp-&gt;hashNext;
! 	if (tvp-&gt;hashNext == NULL)
! 	    return;
! 	tvp-&gt;hashNext = vp-&gt;hashNext;
      }
-     vp-&gt;hashid = 0;
  }
  
  void
  VPrintCacheStats_r(void)
  {
      register struct VnodeClassInfo *vcp;
      vcp = &amp;VnodeClassInfo[vLarge];
      Log("Large vnode cache, %d entries, %d allocs, %d gets (%d reads), %d writes\n", vcp-&gt;cacheSize, vcp-&gt;allocs, vcp-&gt;gets, vcp-&gt;reads, vcp-&gt;writes);
      vcp = &amp;VnodeClassInfo[vSmall];
      Log("Small vnode cache,%d entries, %d allocs, %d gets (%d reads), %d writes\n", vcp-&gt;cacheSize, vcp-&gt;allocs, vcp-&gt;gets, vcp-&gt;reads, vcp-&gt;writes);
      Log("Volume header cache, %d entries, %d gets, %d replacements\n",
! 	VolumeCacheSize, VolumeGets, VolumeReplacements);
  }
  
  void
--- 5613,5961 ----
  	return;
      if (programType == fileServer) {
  	ReleaseVolumeHeader(hd);
! 	hd-&gt;back = NULL;
      } else {
  	free(hd);
      }
! #ifdef AFS_DEMAND_ATTACH_FS
!     V_attachFlags(vp) &amp;= ~(VOL_HDR_ATTACHED | VOL_HDR_IN_LRU | VOL_HDR_LOADED);
!     volume_hdr_LRU.stats.attached--;
! #endif
!     vp-&gt;header = NULL;
  }
  
  
  /***************************************************/
! /* Volume Hash Table routines                      */
  /***************************************************/
  
+ int 
+ VSetVolHashSize(int logsize)
+ {
+     /* 64 to 16384 hash buckets seems like a reasonable range */
+     if ((logsize &lt; 6 ) || (logsize &gt; 14)) {
+         return -1;
+     }
+     
+     if (!VInit) {
+         VolumeHashTable.Size = 1 &lt;&lt; logsize;
+         VolumeHashTable.Mask = VolumeHashTable.Size - 1;
+     } else {
+ 	/* we can't yet support runtime modification of this
+ 	 * parameter. we'll need a configuration rwlock to
+ 	 * make runtime modification feasible.... */
+ 	return -1;
+     }
+     return 0;
+ }
+ 
+ static void
+ VInitVolumeHash(void)
+ {
+     register int i;
+ 
+     VolumeHashTable.Table = (VolumeHashChainHead *) calloc(VolumeHashTable.Size, 
+ 							   sizeof(VolumeHashChainHead));
+     assert(VolumeHashTable.Table != NULL);
+     
+     for (i=0; i &lt; VolumeHashTable.Size; i++) {
+ 	queue_Init(&amp;VolumeHashTable.Table[i]);
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	assert(pthread_cond_init(&amp;VolumeHashTable.Table[i].chain_busy_cv, NULL) == 0);
+ #endif /* AFS_DEMAND_ATTACH_FS */
+     }
+ }
+ 
+ /* for demand-attach, caller MUST hold a ref count on vp */
  static void
  AddVolumeToHashTable(register Volume * vp, int hashid)
  {
!     VolumeHashChainHead * head;
! 
!     if (queue_IsOnQueue(vp))
! 	return;
! 
!     head = &amp;VolumeHashTable.Table[VOLUME_HASH(hashid)];
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     /* wait for the hash chain to become available */
!     VHashWait_r(head);
! 
!     V_attachFlags(vp) |= VOL_IN_HASH;
!     vp-&gt;chainCacheCheck = ++head-&gt;cacheCheck;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
!     head-&gt;len++;
      vp-&gt;hashid = hashid;
!     queue_Append(head, vp);
      vp-&gt;vnodeHashOffset = VolumeHashOffset_r();
  }
  
+ /* for demand-attach, caller MUST hold a ref count on vp */
  static void
  DeleteVolumeFromHashTable(register Volume * vp)
  {
!     VolumeHashChainHead * head;
! 
!     if (!queue_IsOnQueue(vp))
! 	return;
! 
!     head = &amp;VolumeHashTable.Table[VOLUME_HASH(vp-&gt;hashid)];
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     /* wait for the hash chain to become available */
!     VHashWait_r(head);
! 
!     V_attachFlags(vp) &amp;= ~(VOL_IN_HASH);
!     head-&gt;cacheCheck++;
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
!     head-&gt;len--;
!     queue_Remove(vp);
!     /* do NOT reset hashid to zero, as the online
!      * salvager package may need to know the volume id
!      * after the volume is removed from the hash */
! }
! 
! /* - look up a volume id in the hash table
!  * - occasionally rebalance hash chains
!  * - update lookup statistics accordingly
!  */
! /* the hint parameter allows us to short-circuit on
!  * DEMAND_ATTACH_FS if the cacheChecks match between
!  * the hash chain head and hint
!  * caller MUST hold a refcount on hint */
! Volume *
! VLookupVolume_r(Error * ec, VolId volumeId, Volume * hint)
! {
!     register int looks = 0;
!     Volume * vp, *np, *pp;
!     VolumeHashChainHead * head;
!     *ec = 0;
! 
!     head = &amp;VolumeHashTable.Table[VOLUME_HASH(volumeId)];
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     /* wait for the hash chain to become available */
!     VHashWait_r(head);
! 
!     /* check to see if we can short circuit without walking the hash chain */
!     if (hint &amp;&amp; (hint-&gt;chainCacheCheck == head-&gt;cacheCheck)) {
! 	IncUInt64(&amp;hint-&gt;stats.hash_short_circuits);
! 	return hint;
!     }
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
!     /* someday we need to either do per-chain locks, RWlocks,
!      * or both for volhash access. 
!      * (and move to a data structure with better cache locality) */
! 
!     /* search the chain for this volume id */
!     for(queue_Scan(head, vp, np, Volume)) {
! 	looks++;
! 	if ((vp-&gt;hashid == volumeId)) {
! 	    break;
! 	}
!     }
! 
!     if (queue_IsEnd(head, vp)) {
! 	vp = NULL;
!     }
! 
! #ifdef AFS_DEMAND_ATTACH_FS
!     /* update hash chain statistics */
!     {
! 	afs_uint64 lks;
! 	FillInt64(lks, 0, looks);
! 	AddUInt64(head-&gt;looks, lks, &amp;head-&gt;looks);
! 	AddUInt64(VStats.hash_looks, lks, &amp;VStats.hash_looks);
! 	IncUInt64(&amp;head-&gt;gets);
!     }
! 
!     if (vp) {
! 	afs_uint64 thresh;
! 	IncUInt64(&amp;vp-&gt;stats.hash_lookups);
! 
! 	/* for demand attach fileserver, we permit occasional hash chain reordering
! 	 * so that frequently looked up volumes move towards the head of the chain */
! 	pp = queue_Prev(vp, Volume);
! 	if (!queue_IsEnd(head, pp)) {
! 	    FillInt64(thresh, 0, VOLUME_HASH_REORDER_THRESHOLD);
! 	    AddUInt64(thresh, pp-&gt;stats.hash_lookups, &amp;thresh);
! 	    if (GEInt64(vp-&gt;stats.hash_lookups, thresh)) {
! 		VReorderHash_r(head, pp, vp);
! 	    }
! 	}
! 
! 	/* update the short-circuit cache check */
! 	vp-&gt;chainCacheCheck = head-&gt;cacheCheck;
!     }
! #endif /* AFS_DEMAND_ATTACH_FS */    
! 
!     return vp;
! }
! 
! #ifdef AFS_DEMAND_ATTACH_FS
! /* perform volume hash chain reordering.
!  *
!  * advance a subchain beginning at vp ahead of
!  * the adjacent subchain ending at pp */
! static void
! VReorderHash_r(VolumeHashChainHead * head, Volume * pp, Volume * vp)
! {
!     Volume *tp, *np, *lp;
!     afs_uint64 move_thresh;
! 
!     /* this should never be called if the chain is already busy, so
!      * no need to wait for other exclusive chain ops to finish */
! 
!     /* this is a rather heavy set of operations,
!      * so let's set the chain busy flag and drop
!      * the vol_glock */
!     VHashBeginExclusive_r(head);
!     VOL_UNLOCK;
! 
!     /* scan forward in the chain from vp looking for the last element
!      * in the chain we want to advance */
!     FillInt64(move_thresh, 0, VOLUME_HASH_REORDER_CHAIN_THRESH);
!     AddUInt64(move_thresh, pp-&gt;stats.hash_lookups, &amp;move_thresh);
!     for(queue_ScanFrom(head, vp, tp, np, Volume)) {
! 	if (LTInt64(tp-&gt;stats.hash_lookups, move_thresh)) {
! 	    break;
! 	}
!     }
!     lp = queue_Prev(tp, Volume);
! 
!     /* scan backwards from pp to determine where to splice and
!      * insert the subchain we're advancing */
!     for(queue_ScanBackwardsFrom(head, pp, tp, np, Volume)) {
! 	if (GTInt64(tp-&gt;stats.hash_lookups, move_thresh)) {
! 	    break;
! 	}
!     }
!     tp = queue_Next(tp, Volume);
! 
!     /* rebalance chain(vp,...,lp) ahead of chain(tp,...,pp) */
!     queue_MoveChainBefore(tp,vp,lp);
! 
!     VOL_LOCK;
!     IncUInt64(&amp;VStats.hash_reorders);
!     head-&gt;cacheCheck++;
!     IncUInt64(&amp;head-&gt;reorders);
! 
!     /* wake up any threads waiting for the hash chain */
!     VHashEndExclusive_r(head);
! }
! 
! 
! /* demand-attach fs volume hash
!  * asynchronous exclusive operations */
! 
! /* take exclusive control over the hash chain */
! static void
! VHashBeginExclusive_r(VolumeHashChainHead * head)
! {
!     assert(head-&gt;busy == 0);
!     head-&gt;busy = 1;
! }
! 
! /* relinquish exclusive control over the hash chain */
! static void
! VHashEndExclusive_r(VolumeHashChainHead * head)
! {
!     assert(head-&gt;busy);
!     head-&gt;busy = 0;
!     assert(pthread_cond_broadcast(&amp;head-&gt;chain_busy_cv) == 0);
! }
! 
! /* wait for another thread to finish its exclusive ops */
! static void
! VHashWait_r(VolumeHashChainHead * head)
! {
!     while (head-&gt;busy) {
! 	assert(pthread_cond_wait(&amp;head-&gt;chain_busy_cv, &amp;vol_glock_mutex) == 0);
!     }
! }
! #endif /* AFS_DEMAND_ATTACH_FS */
! 
! 
! /***************************************************/
! /* Volume by Partition List routines               */
! /***************************************************/
! 
! /*
!  * demand attach fileserver adds a
!  * linked list of volumes to each
!  * partition object, thus allowing
!  * for quick enumeration of all
!  * volumes on a partition
!  */
! 
! #ifdef AFS_DEMAND_ATTACH_FS
! static void
! AddVolumeToVByPList_r(Volume * vp)
! {
!     if (queue_IsNotOnQueue(&amp;vp-&gt;vol_list)) {
! 	queue_Append(&amp;vp-&gt;partition-&gt;vol_list, &amp;vp-&gt;vol_list);
! 	V_attachFlags(vp) |= VOL_ON_VBYP_LIST;
! 	vp-&gt;partition-&gt;vol_list.len++;
!     }
! }
! 
! static void
! DeleteVolumeFromVByPList_r(Volume * vp)
! {
!     if (queue_IsOnQueue(&amp;vp-&gt;vol_list)) {
! 	queue_Remove(&amp;vp-&gt;vol_list);
! 	V_attachFlags(vp) &amp;= ~(VOL_ON_VBYP_LIST);
! 	vp-&gt;partition-&gt;vol_list.len--;
!     }
! }
! 
! /* take exclusive control over the list */
! static void
! VVByPListBeginExclusive_r(struct DiskPartition * dp)
! {
!     assert(dp-&gt;vol_list.busy == 0);
!     dp-&gt;vol_list.busy = 1;
! }
! 
! /* relinquish exclusive control over the list */
! static void
! VVByPListEndExclusive_r(struct DiskPartition * dp)
! {
!     assert(dp-&gt;vol_list.busy);
!     dp-&gt;vol_list.busy = 0;
!     assert(pthread_cond_broadcast(&amp;dp-&gt;vol_list.cv) == 0);
! }
! 
! /* wait for another thread to finish its exclusive ops */
! static void
! VVByPListWait_r(struct DiskPartition * dp)
! {
!     while (dp-&gt;vol_list.busy) {
! 	assert(pthread_cond_wait(&amp;dp-&gt;vol_list.cv, &amp;vol_glock_mutex) == 0);
      }
  }
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ /***************************************************/
+ /* Volume Cache Statistics routines                */
+ /***************************************************/
  
  void
  VPrintCacheStats_r(void)
  {
+     afs_uint32 get_hi, get_lo, load_hi, load_lo;
      register struct VnodeClassInfo *vcp;
      vcp = &amp;VnodeClassInfo[vLarge];
      Log("Large vnode cache, %d entries, %d allocs, %d gets (%d reads), %d writes\n", vcp-&gt;cacheSize, vcp-&gt;allocs, vcp-&gt;gets, vcp-&gt;reads, vcp-&gt;writes);
      vcp = &amp;VnodeClassInfo[vSmall];
      Log("Small vnode cache,%d entries, %d allocs, %d gets (%d reads), %d writes\n", vcp-&gt;cacheSize, vcp-&gt;allocs, vcp-&gt;gets, vcp-&gt;reads, vcp-&gt;writes);
+     SplitInt64(VStats.hdr_gets, get_hi, get_lo);
+     SplitInt64(VStats.hdr_loads, load_hi, load_lo);
      Log("Volume header cache, %d entries, %d gets, %d replacements\n",
! 	VStats.hdr_cache_size, get_lo, load_lo);
  }
  
  void
***************
*** 2067,2069 ****
--- 5966,6224 ----
      VOL_UNLOCK;
  }
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ static double
+ UInt64ToDouble(afs_uint64 * x)
+ {
+     static double c32 = 4.0 * 1.073741824 * 1000000000.0;
+     afs_uint32 h, l;
+     SplitInt64(*x, h, l);
+     return (((double)h) * c32) + ((double) l);
+ }
+ 
+ static char *
+ DoubleToPrintable(double x, char * buf, int len)
+ {
+     static double billion = 1000000000.0;
+     afs_uint32 y[3];
+ 
+     y[0] = (afs_uint32) (x / (billion * billion));
+     y[1] = (afs_uint32) ((x - (((double)y[0]) * billion * billion)) / billion);
+     y[2] = (afs_uint32) (x - ((((double)y[0]) * billion * billion) + (((double)y[1]) * billion)));
+ 
+     if (y[0]) {
+ 	snprintf(buf, len, "%d%09d%09d", y[0], y[1], y[2]);
+     } else if (y[1]) {
+ 	snprintf(buf, len, "%d%09d", y[1], y[2]);
+     } else {
+ 	snprintf(buf, len, "%d", y[2]);
+     }
+     buf[len-1] = '\0';
+     return buf;
+ }
+ 
+ static void
+ VPrintExtendedCacheStats_r(int flags)
+ {
+     int i, j;
+     struct stats {
+ 	double min;
+ 	double max;
+ 	double sum;
+ 	double avg;
+     };
+     struct stats looks, gets, reorders, len;
+     struct stats ch_looks, ch_gets, ch_reorders;
+     char pr_buf[4][32];
+     VolumeHashChainHead *head;
+     Volume *vp, *np;
+ 
+     /* zero out stats */
+     memset(&amp;looks, 0, sizeof(struct stats));
+     memset(&amp;gets, 0, sizeof(struct stats));
+     memset(&amp;reorders, 0, sizeof(struct stats));
+     memset(&amp;len, 0, sizeof(struct stats));
+     memset(&amp;ch_looks, 0, sizeof(struct stats));
+     memset(&amp;ch_gets, 0, sizeof(struct stats));
+     memset(&amp;ch_reorders, 0, sizeof(struct stats));
+ 
+     for (i = 0; i &lt; VolumeHashTable.Size; i++) {
+ 	head = &amp;VolumeHashTable.Table[i];
+ 
+ 	VHashWait_r(head);
+ 	VHashBeginExclusive_r(head);
+ 	VOL_UNLOCK;
+ 
+ 	ch_looks.sum    = UInt64ToDouble(&amp;head-&gt;looks);
+ 	ch_gets.sum     = UInt64ToDouble(&amp;head-&gt;gets);
+ 	ch_reorders.sum = UInt64ToDouble(&amp;head-&gt;reorders);
+ 
+ 	/* update global statistics */
+ 	{
+ 	    looks.sum    += ch_looks.sum;
+ 	    gets.sum     += ch_gets.sum;
+ 	    reorders.sum += ch_reorders.sum;
+ 	    len.sum      += (double)head-&gt;len;
+ 	    
+ 	    if (i == 0) {
+ 		len.min      = (double) head-&gt;len;
+ 		len.max      = (double) head-&gt;len;
+ 		looks.min    = ch_looks.sum;
+ 		looks.max    = ch_looks.sum;
+ 		gets.min     = ch_gets.sum;
+ 		gets.max     = ch_gets.sum;
+ 		reorders.min = ch_reorders.sum;
+ 		reorders.max = ch_reorders.sum;
+ 	    } else {
+ 		if (((double)head-&gt;len) &lt; len.min)
+ 		    len.min = (double) head-&gt;len;
+ 		if (((double)head-&gt;len) &gt; len.max)
+ 		    len.max = (double) head-&gt;len;
+ 		if (ch_looks.sum &lt; looks.min)
+ 		    looks.min = ch_looks.sum;
+ 		else if (ch_looks.sum &gt; looks.max)
+ 		    looks.max = ch_looks.sum;
+ 		if (ch_gets.sum &lt; gets.min)
+ 		    gets.min = ch_gets.sum;
+ 		else if (ch_gets.sum &gt; gets.max)
+ 		    gets.max = ch_gets.sum;
+ 		if (ch_reorders.sum &lt; reorders.min)
+ 		    reorders.min = ch_reorders.sum;
+ 		else if (ch_reorders.sum &gt; reorders.max)
+ 		    reorders.max = ch_reorders.sum;
+ 	    }
+ 	}
+ 
+ 	if ((flags &amp; VOL_STATS_PER_CHAIN2) &amp;&amp; queue_IsNotEmpty(head)) {
+ 	    /* compute detailed per-chain stats */
+ 	    struct stats hdr_loads, hdr_gets;
+ 	    double v_looks, v_loads, v_gets;
+ 
+ 	    /* initialize stats with data from first element in chain */
+ 	    vp = queue_First(head, Volume);
+ 	    v_looks = UInt64ToDouble(&amp;vp-&gt;stats.hash_lookups);
+ 	    v_loads = UInt64ToDouble(&amp;vp-&gt;stats.hdr_loads);
+ 	    v_gets  = UInt64ToDouble(&amp;vp-&gt;stats.hdr_gets);
+ 	    ch_gets.min = ch_gets.max = v_looks;
+ 	    hdr_loads.min = hdr_loads.max = v_loads;
+ 	    hdr_gets.min = hdr_gets.max = v_gets;
+ 	    hdr_loads.sum = hdr_gets.sum = 0;
+ 
+ 	    vp = queue_Next(vp, Volume);
+ 
+ 	    /* pull in stats from remaining elements in chain */
+ 	    for (queue_ScanFrom(head, vp, vp, np, Volume)) {
+ 		v_looks = UInt64ToDouble(&amp;vp-&gt;stats.hash_lookups);
+ 		v_loads = UInt64ToDouble(&amp;vp-&gt;stats.hdr_loads);
+ 		v_gets  = UInt64ToDouble(&amp;vp-&gt;stats.hdr_gets);
+ 
+ 		hdr_loads.sum += v_loads;
+ 		hdr_gets.sum += v_gets;
+ 
+ 		if (v_looks &lt; ch_gets.min)
+ 		    ch_gets.min = v_looks;
+ 		else if (v_looks &gt; ch_gets.max)
+ 		    ch_gets.max = v_looks;
+ 
+ 		if (v_loads &lt; hdr_loads.min)
+ 		    hdr_loads.min = v_loads;
+ 		else if (v_loads &gt; hdr_loads.max)
+ 		    hdr_loads.max = v_loads;
+ 
+ 		if (v_gets &lt; hdr_gets.min)
+ 		    hdr_gets.min = v_gets;
+ 		else if (v_gets &gt; hdr_gets.max)
+ 		    hdr_gets.max = v_gets;
+ 	    }
+ 
+ 	    /* compute per-chain averages */
+ 	    ch_gets.avg = ch_gets.sum / ((double)head-&gt;len);
+ 	    hdr_loads.avg = hdr_loads.sum / ((double)head-&gt;len);
+ 	    hdr_gets.avg = hdr_gets.sum / ((double)head-&gt;len);
+ 
+ 	    /* dump per-chain stats */
+ 	    Log("Volume hash chain %d : len=%d, looks=%s, reorders=%s\n",
+ 		i, head-&gt;len, 
+ 		DoubleToPrintable(ch_looks.sum, pr_buf[0], sizeof(pr_buf[0])),
+ 		DoubleToPrintable(ch_reorders.sum, pr_buf[1], sizeof(pr_buf[1])));
+ 	    Log("\tVolume gets : min=%s, max=%s, avg=%s, total=%s\n",
+ 		DoubleToPrintable(ch_gets.min, pr_buf[0], sizeof(pr_buf[0])),
+ 		DoubleToPrintable(ch_gets.max, pr_buf[1], sizeof(pr_buf[1])),
+ 		DoubleToPrintable(ch_gets.avg, pr_buf[2], sizeof(pr_buf[2])),
+ 		DoubleToPrintable(ch_gets.sum, pr_buf[3], sizeof(pr_buf[3])));
+ 	    Log("\tHDR gets : min=%s, max=%s, avg=%s, total=%s\n",
+ 		DoubleToPrintable(hdr_gets.min, pr_buf[0], sizeof(pr_buf[0])),
+ 		DoubleToPrintable(hdr_gets.max, pr_buf[1], sizeof(pr_buf[1])),
+ 		DoubleToPrintable(hdr_gets.avg, pr_buf[2], sizeof(pr_buf[2])),
+ 		DoubleToPrintable(hdr_gets.sum, pr_buf[3], sizeof(pr_buf[3])));
+ 	    Log("\tHDR loads : min=%s, max=%s, avg=%s, total=%s\n",
+ 		DoubleToPrintable(hdr_loads.min, pr_buf[0], sizeof(pr_buf[0])),
+ 		DoubleToPrintable(hdr_loads.max, pr_buf[1], sizeof(pr_buf[1])),
+ 		DoubleToPrintable(hdr_loads.avg, pr_buf[2], sizeof(pr_buf[2])),
+ 		DoubleToPrintable(hdr_loads.sum, pr_buf[3], sizeof(pr_buf[3])));
+ 	} else if (flags &amp; VOL_STATS_PER_CHAIN) {
+ 	    /* dump simple per-chain stats */
+ 	    Log("Volume hash chain %d : len=%d, looks=%s, gets=%s, reorders=%s\n",
+ 		i, head-&gt;len, 
+ 		DoubleToPrintable(ch_looks.sum, pr_buf[0], sizeof(pr_buf[0])),
+ 		DoubleToPrintable(ch_gets.sum, pr_buf[1], sizeof(pr_buf[1])),
+ 		DoubleToPrintable(ch_reorders.sum, pr_buf[2], sizeof(pr_buf[2])));
+ 	}
+ 
+ 	VOL_LOCK;
+ 	VHashEndExclusive_r(head);
+     }
+ 
+     VOL_UNLOCK;
+ 
+     /* compute global averages */
+     len.avg      = len.sum      / ((double)VolumeHashTable.Size);
+     looks.avg    = looks.sum    / ((double)VolumeHashTable.Size);
+     gets.avg     = gets.sum     / ((double)VolumeHashTable.Size);
+     reorders.avg = reorders.sum / ((double)VolumeHashTable.Size);
+ 
+     /* dump global stats */
+     Log("Volume hash summary: %d buckets\n", VolumeHashTable.Size);
+     Log(" chain length : min=%s, max=%s, avg=%s, total=%s\n",
+ 	DoubleToPrintable(len.min, pr_buf[0], sizeof(pr_buf[0])),
+ 	DoubleToPrintable(len.max, pr_buf[1], sizeof(pr_buf[1])),
+ 	DoubleToPrintable(len.avg, pr_buf[2], sizeof(pr_buf[2])),
+ 	DoubleToPrintable(len.sum, pr_buf[3], sizeof(pr_buf[3])));
+     Log(" looks : min=%s, max=%s, avg=%s, total=%s\n",
+ 	DoubleToPrintable(looks.min, pr_buf[0], sizeof(pr_buf[0])),
+ 	DoubleToPrintable(looks.max, pr_buf[1], sizeof(pr_buf[1])),
+ 	DoubleToPrintable(looks.avg, pr_buf[2], sizeof(pr_buf[2])),
+ 	DoubleToPrintable(looks.sum, pr_buf[3], sizeof(pr_buf[3])));
+     Log(" gets : min=%s, max=%s, avg=%s, total=%s\n",
+ 	DoubleToPrintable(gets.min, pr_buf[0], sizeof(pr_buf[0])),
+ 	DoubleToPrintable(gets.max, pr_buf[1], sizeof(pr_buf[1])),
+ 	DoubleToPrintable(gets.avg, pr_buf[2], sizeof(pr_buf[2])),
+ 	DoubleToPrintable(gets.sum, pr_buf[3], sizeof(pr_buf[3])));
+     Log(" reorders : min=%s, max=%s, avg=%s, total=%s\n",
+ 	DoubleToPrintable(reorders.min, pr_buf[0], sizeof(pr_buf[0])),
+ 	DoubleToPrintable(reorders.max, pr_buf[1], sizeof(pr_buf[1])),
+ 	DoubleToPrintable(reorders.avg, pr_buf[2], sizeof(pr_buf[2])),
+ 	DoubleToPrintable(reorders.sum, pr_buf[3], sizeof(pr_buf[3])));
+ 
+     /* print extended disk related statistics */
+     {
+ 	struct DiskPartition * diskP;
+ 	afs_uint32 vol_count[VOLMAXPARTS+1];
+ 	byte part_exists[VOLMAXPARTS+1];
+ 	Device id;
+ 	int i;
+ 
+ 	memset(vol_count, 0, sizeof(vol_count));
+ 	memset(part_exists, 0, sizeof(part_exists));
+ 
+ 	VOL_LOCK;
+ 
+ 	for (diskP = DiskPartitionList; diskP; diskP = diskP-&gt;next) {
+ 	    id = diskP-&gt;device;
+ 	    vol_count[id] = diskP-&gt;vol_list.len;
+ 	    part_exists[id] = 1;
+ 	}
+ 
+ 	VOL_UNLOCK;
+ 	for (i = 0; i &lt;= VOLMAXPARTS; i++) {
+ 	    if (part_exists[i]) {
+ 		diskP = VGetPartitionById_r(i, 0);
+ 		if (diskP) {
+ 		    Log("Partition %s has %d online volumes\n", 
+ 			VPartitionPath(diskP), diskP-&gt;vol_list.len);
+ 		}
+ 	    }
+ 	}
+ 	VOL_LOCK;
+     }
+ 
+ }
+ 
+ void
+ VPrintExtendedCacheStats(int flags)
+ {
+     VOL_LOCK;
+     VPrintExtendedCacheStats_r(flags);
+     VOL_UNLOCK;
+ }
+ #endif /* AFS_DEMAND_ATTACH_FS */
Index: openafs/src/vol/volume.h
diff -c openafs/src/vol/volume.h:1.18 openafs/src/vol/volume.h:1.19
*** openafs/src/vol/volume.h:1.18	Sat Oct 15 11:36:56 2005
--- openafs/src/vol/volume.h	Fri Mar 17 14:54:52 2006
***************
*** 5,10 ****
--- 5,12 ----
   * This software has been released under the terms of the IBM Public
   * License.  For details, see the LICENSE file in the top-level source
   * directory or online at http://www.openafs.org/dl/license10.html
+  *
+  * Portions Copyright (c) 2006 Sine Nomine Associates
   */
  
  /*
***************
*** 24,67 ****
  #define VolumeWriteable2(vol)		(vol.type == readwriteVolume)
  typedef bit32 FileOffset;	/* Offset in this file */
  #define Date afs_uint32
  
  #ifdef AFS_PTHREAD_ENV
  #include &lt;assert.h&gt;
  #include &lt;pthread.h&gt;
  extern pthread_mutex_t vol_glock_mutex;
- extern pthread_mutex_t vol_attach_mutex;
- extern pthread_mutex_t vol_fsync_mutex;
  extern pthread_mutex_t vol_trans_mutex;
  extern pthread_cond_t vol_put_volume_cond;
  extern pthread_cond_t vol_sleep_cond;
  extern int vol_attach_threads;
- /* this lock has been deprecated */
- #define VATTACH_LOCK
- #define VATTACH_UNLOCK
  #define VOL_LOCK \
      assert(pthread_mutex_lock(&amp;vol_glock_mutex) == 0)
  #define VOL_UNLOCK \
      assert(pthread_mutex_unlock(&amp;vol_glock_mutex) == 0)
! #define VFSYNC_LOCK \
!     assert(pthread_mutex_lock(&amp;vol_fsync_mutex) == 0)
! #define VFSYNC_UNLOCK \
!     assert(pthread_mutex_unlock(&amp;vol_fsync_mutex) == 0)
  #define VTRANS_LOCK \
      assert(pthread_mutex_lock(&amp;vol_trans_mutex) == 0)
  #define VTRANS_UNLOCK \
      assert(pthread_mutex_unlock(&amp;vol_trans_mutex) == 0)
  #else /* AFS_PTHREAD_ENV */
- #define VATTACH_LOCK
- #define VATTACH_UNLOCK
  #define VOL_LOCK
  #define VOL_UNLOCK
! #define VFSYNC_LOCK
! #define VFSYNC_UNLOCK
  #define VTRANS_LOCK
  #define VTRANS_UNLOCK
  #endif /* AFS_PTHREAD_ENV */
  
! typedef enum { fileServer, volumeUtility, salvager } ProgramType;
  extern ProgramType programType;	/* The type of program using the package */
  
  /* Some initialization parameters for the volume package */
--- 26,69 ----
  #define VolumeWriteable2(vol)		(vol.type == readwriteVolume)
  typedef bit32 FileOffset;	/* Offset in this file */
  #define Date afs_uint32
+ #include "daemon_com.h"
+ #include "fssync.h"
  
  #ifdef AFS_PTHREAD_ENV
  #include &lt;assert.h&gt;
  #include &lt;pthread.h&gt;
  extern pthread_mutex_t vol_glock_mutex;
  extern pthread_mutex_t vol_trans_mutex;
  extern pthread_cond_t vol_put_volume_cond;
  extern pthread_cond_t vol_sleep_cond;
  extern int vol_attach_threads;
  #define VOL_LOCK \
      assert(pthread_mutex_lock(&amp;vol_glock_mutex) == 0)
  #define VOL_UNLOCK \
      assert(pthread_mutex_unlock(&amp;vol_glock_mutex) == 0)
! #define VSALVSYNC_LOCK \
!     assert(pthread_mutex_lock(&amp;vol_salvsync_mutex) == 0)
! #define VSALVSYNC_UNLOCK \
!     assert(pthread_mutex_unlock(&amp;vol_salvsync_mutex) == 0)
  #define VTRANS_LOCK \
      assert(pthread_mutex_lock(&amp;vol_trans_mutex) == 0)
  #define VTRANS_UNLOCK \
      assert(pthread_mutex_unlock(&amp;vol_trans_mutex) == 0)
  #else /* AFS_PTHREAD_ENV */
  #define VOL_LOCK
  #define VOL_UNLOCK
! #define VSALVSYNC_LOCK
! #define VSALVSYNC_UNLOCK
  #define VTRANS_LOCK
  #define VTRANS_UNLOCK
  #endif /* AFS_PTHREAD_ENV */
  
! typedef enum { fileServer,       /* the fileserver process */
! 	       volumeUtility,    /* volserver, or a single volume salvager (non-dafs) */
! 	       salvager,         /* standalone whole-partition salvager */
! 	       salvageServer,    /* dafs online salvager */
! 	       debugUtility      /* fssync-debug or similar utility */
! } ProgramType;
  extern ProgramType programType;	/* The type of program using the package */
  
  /* Some initialization parameters for the volume package */
***************
*** 76,81 ****
--- 78,147 ----
  				 * that created this file */
  };
  
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /*
+  * demand attach fs
+  * volume state machine
+  *
+  * these must be contiguous in order for IsValidState() to work correctly 
+  */
+ #define VOL_STATE_UNATTACHED     0       /* volume is unattached */
+ #define VOL_STATE_PREATTACHED    1       /* volume has been pre-attached */
+ #define VOL_STATE_ATTACHING      2       /* volume is transitioning to fully attached */
+ #define VOL_STATE_ATTACHED       3       /* volume has been fully attached */
+ #define VOL_STATE_UPDATING       4       /* volume is updating on-disk structures */
+ #define VOL_STATE_GET_BITMAP     5       /* volume is getting bitmap entries */
+ #define VOL_STATE_HDR_LOADING    6       /* volume is loading disk header */
+ #define VOL_STATE_HDR_ATTACHING  7       /* volume is getting a header from the LRU */
+ #define VOL_STATE_SHUTTING_DOWN  8       /* volume is shutting down */
+ #define VOL_STATE_GOING_OFFLINE  9       /* volume is going offline */
+ #define VOL_STATE_OFFLINING      10      /* volume is transitioning to offline */
+ #define VOL_STATE_DETACHING      11      /* volume is transitioning to detached */
+ #define VOL_STATE_SALVSYNC_REQ   12      /* volume is blocked on a salvsync request */
+ #define VOL_STATE_SALVAGING      13      /* volume is being salvaged */
+ #define VOL_STATE_ERROR          14      /* volume is in an error state */
+ #define VOL_STATE_FREED          15      /* debugging aid */
+ 
+ #define VOL_STATE_COUNT          16      /* total number of valid states */
+ 
+ /* V_attachFlags bits */
+ #define VOL_HDR_ATTACHED   0x1     /* volume header is attached to Volume struct */
+ #define VOL_HDR_LOADED     0x2     /* volume header contents are valid */
+ #define VOL_HDR_IN_LRU     0x4     /* volume header is in LRU */
+ #define VOL_IN_HASH        0x8     /* volume is in hash table */
+ #define VOL_ON_VBYP_LIST   0x10    /* volume is on VByP list */
+ #define VOL_IS_BUSY        0x20    /* volume is not to be free()d */
+ #define VOL_ON_VLRU        0x40    /* volume is on the VLRU */
+ #define VOL_HDR_DONTSALV   0x80    /* volume header DONTSALVAGE flag is set */
+ 
+ /* VPrintExtendedCacheStats flags */
+ #define VOL_STATS_PER_CHAIN   0x1  /* compute simple per-chain stats */
+ #define VOL_STATS_PER_CHAIN2  0x2  /* compute per-chain stats that require scanning
+ 				    * every element of the chain */
+ 
+ /* VLRU_SetOptions options */
+ #define VLRU_SET_THRESH       1
+ #define VLRU_SET_INTERVAL     2
+ #define VLRU_SET_MAX          3
+ #define VLRU_SET_ENABLED      4
+ 
+ /* valid VLRU queue names */
+ #define VLRU_QUEUE_NEW 0            /* LRU queue for new volumes */
+ #define VLRU_QUEUE_MID 1            /* survivor generation */
+ #define VLRU_QUEUE_OLD 2            /* old generation */
+ #define VLRU_QUEUE_CANDIDATE 3      /* soft detach candidate pool */
+ #define VLRU_QUEUE_HELD 4           /* volumes which are not allowed
+ 				     * to be soft detached */
+ #define VLRU_QUEUE_INVALID 5        /* invalid queue id */
+ 
+ /* default scanner timing parameters */
+ #define VLRU_DEFAULT_OFFLINE_THRESH (60*60*2) /* 2 hours */
+ #define VLRU_DEFAULT_OFFLINE_INTERVAL (60*2) /* 2 minutes */
+ #define VLRU_DEFAULT_OFFLINE_MAX 8 /* 8 volumes */
+ 
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+ 
  /* Magic numbers and version stamps for each type of file */
  #define VOLUMEHEADERMAGIC	((bit32)0x88a1bb3c)
  #define VOLUMEINFOMAGIC		((bit32)0x78a1b2c5)
***************
*** 297,304 ****
  /**************************************/
  /* Memory resident volume information */
  /**************************************/
  typedef struct Volume {
!     struct Volume *hashNext;	/* Next in hash resolution table */
      VolumeId hashid;		/* Volume number -- for hash table lookup */
      struct volHeader *header;	/* Cached disk data */
      Device device;		/* Unix device for the volume */
--- 363,506 ----
  /**************************************/
  /* Memory resident volume information */
  /**************************************/
+ 
+ /* global volume package stats */
+ typedef struct VolPkgStats {
+ #ifdef AFS_DEMAND_ATTACH_FS
+     /*
+      * demand attach fs
+      * extended volume package statistics
+      */
+ 
+     /* levels */
+     afs_uint32 state_levels[VOL_STATE_COUNT];
+ 
+     /* counters */
+     afs_uint64 hash_looks;           /* number of hash chain element traversals */
+     afs_uint64 hash_reorders;        /* number of hash chain reorders */
+     afs_uint64 salvages;             /* online salvages since fileserver start */
+     afs_uint64 vol_ops;              /* volume operations since fileserver start */
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
+     afs_uint64 hdr_loads;            /* header loads from disk */
+     afs_uint64 hdr_gets;             /* header pulls out of LRU */
+     afs_uint64 attaches;             /* volume attaches since fileserver start */
+     afs_uint64 soft_detaches;        /* soft detach ops since fileserver start */
+ 
+     /* configuration parameters */
+     afs_uint32 hdr_cache_size;       /* size of volume header cache */
+ } VolPkgStats;
+ extern VolPkgStats VStats;
+ 
+ /*
+  * volume header cache supporting structures
+  */
+ #ifdef AFS_DEMAND_ATTACH_FS
+ struct volume_hdr_LRU_stats {
+     afs_uint32 free;
+     afs_uint32 used;
+     afs_uint32 attached;
+ };
+ #endif
+ 
+ struct volume_hdr_LRU_t {
+     struct rx_queue lru;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     struct volume_hdr_LRU_stats stats;
+ #endif
+ };
+ extern struct volume_hdr_LRU_t volume_hdr_LRU;
+ 
+ /*
+  * volume hash chain supporting structures
+  */
+ typedef struct VolumeHashChainHead {
+     struct rx_queue queue;
+     int len;
+     /* someday we could put a per-chain lock here... */
+ #ifdef AFS_DEMAND_ATTACH_FS
+     int busy;
+     int cacheCheck;
+ 
+     /* per-chain statistics */
+     afs_uint64 looks;
+     afs_uint64 gets;
+     afs_uint64 reorders;
+ 
+     pthread_cond_t chain_busy_cv;
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ } VolumeHashChainHead;
+ 
+ typedef struct VolumeHashTable {
+     int Size;
+     int Mask;
+     VolumeHashChainHead * Table;
+ } VolumeHashTable_t;
+ extern VolumeHashTable_t VolumeHashTable;
+ 
+ struct VolumeHashChainStats {
+     afs_int32 table_size;
+     afs_int32 chain_len;
+ #ifdef AFS_DEMAND_ATTACH_FS
+     afs_int32 chain_cacheCheck;
+     afs_int32 chain_busy;
+     afs_uint64 chain_looks;
+     afs_uint64 chain_gets;
+     afs_uint64 chain_reorders;
+ #endif
+ };
+ 
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ /* demand attach fs
+  * extended per-volume statistics 
+  *
+  * please note that this structure lives across the entire
+  * lifetime of the fileserver process
+  */
+ typedef struct VolumeStats {
+     /* counters */
+     afs_uint64 hash_lookups;         /* hash table lookups */
+     afs_uint64 hash_short_circuits;  /* short circuited hash lookups (due to cacheCheck) */
+     afs_uint64 hdr_loads;            /* header loads from disk */
+     afs_uint64 hdr_gets;             /* header pulls out of LRU */
+     afs_uint16 attaches;             /* attaches of this volume since fileserver start */
+     afs_uint16 soft_detaches;        /* soft detaches of this volume */
+     afs_uint16 salvages;             /* online salvages since fileserver start */
+     afs_uint16 vol_ops;              /* volume operations since fileserver start */
+ 
+     /* timestamps */
+     afs_uint32 last_attach;      /* unix timestamp of last VAttach */
+     afs_uint32 last_get;         /* unix timestamp of last VGet/VHold */
+     afs_uint32 last_promote;     /* unix timestamp of last VLRU promote/demote */
+     afs_uint32 last_hdr_get;     /* unix timestamp of last GetVolumeHeader() */
+     afs_uint32 last_salvage;     /* unix timestamp of last initiation of an online salvage */
+     afs_uint32 last_salvage_req; /* unix timestamp of last SALVSYNC request */
+     afs_uint32 last_vol_op;      /* unix timestamp of last volume operation */
+ } VolumeStats;
+ 
+ /* demand attach fs
+  * online salvager state */
+ typedef struct VolumeOnlineSalvage {
+     afs_uint32 prio;            /* number of VGetVolume's since salvage requested */
+     int reason;                 /* reason for requesting online salvage */
+     byte requested;             /* flag specifying that salvage should be scheduled */
+     byte scheduled;             /* flag specifying whether online salvage scheduled */
+     byte reserved[2];           /* padding */
+ } VolumeOnlineSalvage;
+ 
+ /* demand attach fs
+  * volume LRU state */
+ typedef struct VolumeVLRUState {
+     struct rx_queue lru;        /* VLRU queue pointers */
+     int idx;                    /* VLRU generation index */
+ } VolumeVLRUState;
+ 
+ typedef afs_uint16 VolState;    /* attachment state type */
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ 
  typedef struct Volume {
!     struct rx_queue q;          /* Volume hash chain pointers */
      VolumeId hashid;		/* Volume number -- for hash table lookup */
      struct volHeader *header;	/* Cached disk data */
      Device device;		/* Unix device for the volume */
***************
*** 339,348 ****
      afs_uint32 updateTime;	/* Time that this volume was put on the updated
  				 * volume list--the list of volumes that will be
  				 * salvaged should the file server crash */
  } Volume;
  
  struct volHeader {
!     struct volHeader *prev, *next;	/* LRU pointers */
      VolumeDiskData diskstuff;	/* General volume info read from disk */
      Volume *back;		/* back pointer to current volume structure */
  };
--- 541,563 ----
      afs_uint32 updateTime;	/* Time that this volume was put on the updated
  				 * volume list--the list of volumes that will be
  				 * salvaged should the file server crash */
+ #ifdef AFS_DEMAND_ATTACH_FS
+     VolState attach_state;      /* what stage of attachment has been completed */
+     afs_uint16 attach_flags;    /* flags related to attachment state */
+     pthread_cond_t attach_cv;   /* state change condition variable */
+     short nWaiters;             /* volume package internal ref count */
+     int chainCacheCheck;        /* Volume hash chain cache check */
+     struct rx_queue vol_list;   /* per-partition volume list (VByPList) */
+ 
+     VolumeOnlineSalvage salvage;  /* online salvager state */
+     VolumeStats stats;            /* per-volume statistics */
+     VolumeVLRUState vlru;         /* state specific to the VLRU */
+     FSSYNC_VolOp_info * pending_vol_op;  /* fssync command info for any pending vol ops */
+ #endif /* AFS_DEMAND_ATTACH_FS */
  } Volume;
  
  struct volHeader {
!     struct rx_queue lru;
      VolumeDiskData diskstuff;	/* General volume info read from disk */
      Volume *back;		/* back pointer to current volume structure */
  };
***************
*** 356,361 ****
--- 571,581 ----
  #define V_vnodeIndex(vp)	((vp)-&gt;vnodeIndex)
  #define V_nextVnodeUnique(vp)	((vp)-&gt;nextVnodeUnique)
  #define V_linkHandle(vp)	((vp)-&gt;linkHandle)
+ #ifdef AFS_DEMAND_ATTACH_FS
+ #define V_attachState(vp)       ((vp)-&gt;attach_state)
+ #define V_attachFlags(vp)       ((vp)-&gt;attach_flags)
+ #define V_attachCV(vp)          ((vp)-&gt;attach_cv)
+ #endif /* AFS_DEMAND_ATTACH_FS */
  
  /* N.B. V_id must be this, rather than vp-&gt;id, or some programs will break, probably */
  #define V_stamp(vp)		((vp)-&gt;header-&gt;diskstuff.stamp)
***************
*** 414,420 ****
  
  extern char *VSalvageMessage;	/* Canonical message when a volume is forced
  				 * offline */
! extern Volume *VGetVolume(Error * ec, VolId volumeId);
  extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
  extern void VPutVolume(Volume *);
  extern void VPutVolume_r(Volume *);
--- 634,640 ----
  
  extern char *VSalvageMessage;	/* Canonical message when a volume is forced
  				 * offline */
! extern Volume *VGetVolume(Error * ec, Error * client_ec, VolId volumeId);
  extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
  extern void VPutVolume(Volume *);
  extern void VPutVolume_r(Volume *);
***************
*** 422,427 ****
--- 642,650 ----
  extern void VOffline_r(Volume * vp, char *message);
  extern int VConnectFS(void);
  extern int VConnectFS_r(void);
+ extern void VDisconnectFS(void);
+ extern void VDisconnectFS_r(void);
+ extern int VChildProcReconnectFS(void);
  extern Volume *VAttachVolume(Error * ec, VolumeId volumeId, int mode);
  extern Volume *VAttachVolume_r(Error * ec, VolumeId volumeId, int mode);
  extern Volume *VCreateVolume(Error * ec, char *partname, VolId volumeId,
***************
*** 431,437 ****
  extern VnodeId VAllocBitmapEntry(Error * ec, Volume * vp,
  				 struct vnodeIndex *index);
  extern VnodeId VAllocBitmapEntry_r(Error * ec, Volume * vp,
! 				   struct vnodeIndex *index);
  extern void VFreeBitMapEntry(Error * ec, register struct vnodeIndex *index,
  			     unsigned bitNumber);
  extern void VFreeBitMapEntry_r(Error * ec, register struct vnodeIndex *index,
--- 654,660 ----
  extern VnodeId VAllocBitmapEntry(Error * ec, Volume * vp,
  				 struct vnodeIndex *index);
  extern VnodeId VAllocBitmapEntry_r(Error * ec, Volume * vp,
! 				   struct vnodeIndex *index, int flags);
  extern void VFreeBitMapEntry(Error * ec, register struct vnodeIndex *index,
  			     unsigned bitNumber);
  extern void VFreeBitMapEntry_r(Error * ec, register struct vnodeIndex *index,
***************
*** 444,456 ****
  				     int mode);
  extern void VShutdown(void);
  extern void VUpdateVolume(Error * ec, Volume * vp);
! extern void VUpdateVolume_r(Error * ec, Volume * vp);
  extern void VAddToVolumeUpdateList(Error * ec, Volume * vp);
  extern void VAddToVolumeUpdateList_r(Error * ec, Volume * vp);
  extern void VDetachVolume(Error * ec, Volume * vp);
  extern void VDetachVolume_r(Error * ec, Volume * vp);
  extern void VForceOffline(Volume * vp);
! extern void VForceOffline_r(Volume * vp);
  extern void VBumpVolumeUsage(register Volume * vp);
  extern void VBumpVolumeUsage_r(register Volume * vp);
  extern void VSetDiskUsage(void);
--- 667,679 ----
  				     int mode);
  extern void VShutdown(void);
  extern void VUpdateVolume(Error * ec, Volume * vp);
! extern void VUpdateVolume_r(Error * ec, Volume * vp, int flags);
  extern void VAddToVolumeUpdateList(Error * ec, Volume * vp);
  extern void VAddToVolumeUpdateList_r(Error * ec, Volume * vp);
  extern void VDetachVolume(Error * ec, Volume * vp);
  extern void VDetachVolume_r(Error * ec, Volume * vp);
  extern void VForceOffline(Volume * vp);
! extern void VForceOffline_r(Volume * vp, int flags);
  extern void VBumpVolumeUsage(register Volume * vp);
  extern void VBumpVolumeUsage_r(register Volume * vp);
  extern void VSetDiskUsage(void);
***************
*** 459,470 ****
  extern void VCloseVnodeFiles_r(Volume * vp);
  extern struct DiskPartition *VGetPartition(char *name, int abortp);
  extern struct DiskPartition *VGetPartition_r(char *name, int abortp);
! extern int VInitVolumePackage(ProgramType pt, int nLargeVnodes,
! 			      int nSmallVnodes, int connect, int volcache);
  extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
  extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
  extern void VTakeOffline_r(register Volume * vp);
  extern void VTakeOffline(register Volume * vp);
  
  
  /* Naive formula relating number of file size to number of 1K blocks in file */
--- 682,722 ----
  extern void VCloseVnodeFiles_r(Volume * vp);
  extern struct DiskPartition *VGetPartition(char *name, int abortp);
  extern struct DiskPartition *VGetPartition_r(char *name, int abortp);
! extern int VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes,
! 			      afs_uint32 nSmallVnodes, int connect, afs_uint32 volcache);
  extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
  extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
  extern void VTakeOffline_r(register Volume * vp);
  extern void VTakeOffline(register Volume * vp);
+ extern Volume * VLookupVolume_r(Error * ec, VolId volumeId, Volume * hint);
+ 
+ #ifdef AFS_DEMAND_ATTACH_FS
+ extern Volume *VPreAttachVolumeByName(Error * ec, char *partition, char *name, 
+ 				       int mode);
+ extern Volume *VPreAttachVolumeByName_r(Error * ec, char *partition, char *name,
+ 				     int mode);
+ extern Volume *VPreAttachVolumeById_r(Error * ec, struct DiskPartition * partp, 
+ 				      Volume * vp, int volume_id);
+ extern Volume *VGetVolumeByVp_r(Error * ec, Volume * vp);
+ extern int VShutdownByPartition_r(struct DiskPartition * dp);
+ extern int VShutdownVolume_r(Volume * vp);
+ extern int VConnectSALV(void);
+ extern int VConnectSALV_r(void);
+ extern int VReconnectSALV(void);
+ extern int VReconnectSALV_r(void);
+ extern int VDisconnectSALV(void);
+ extern int VDisconnectSALV_r(void);
+ extern void VPrintExtendedCacheStats(int flags);
+ extern void VPrintExtendedCacheStats_r(int flags);
+ extern VolState VChangeState_r(Volume * vp, VolState new_state);
+ extern void VLRU_SetOptions(int option, afs_uint32 val);
+ extern int VSetVolHashSize(int logsize);
+ extern int VRequestSalvage_r(Volume * vp, int reason, int flags);
+ extern int VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
+ extern int VDeregisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
+ #endif /* AFS_DEMAND_ATTACH_FS */
+ extern int VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
+ extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
  
  
  /* Naive formula relating number of file size to number of 1K blocks in file */
***************
*** 500,505 ****
--- 752,777 ----
  				 * getting the most recent data. */
  
  
+ 
+ /* VUpdateVolume_r flags */
+ #define VOL_UPDATE_WAIT          0x1  /* for demand attach, wait for other exclusive ops to end */
+ #define VOL_UPDATE_NOFORCEOFF    0x2  /* don't force offline on failure. this is to prevent
+ 				       * infinite recursion between vupdate and vforceoff */
+ 
+ /* VForceOffline_r flags */
+ #define VOL_FORCEOFF_NOUPDATE    0x1  /* don't force update on forceoff. this is to prevent
+ 				       * infinite recursion between vupdate and vforceoff */
+ 
+ /* VSyncVolume_r flags */
+ #define VOL_SYNC_WAIT            0x1  /* for demand attach, wait for other exclusive ops to end */
+ 
+ /* VAllocBitmapEntry_r flags */
+ #define VOL_ALLOC_BITMAP_WAIT    0x1  /* for demand attach, wait for other exclusive ops to end */
+ 
+ /* VRequestSalvage_r flags */
+ #define VOL_SALVAGE_INVALIDATE_HEADER 0x1 /* for demand attach fs, invalidate volume header cache */
+ 
+ 
  #if	defined(NEARINODE_HINT)
  #define V_pref(vp,nearInode)  nearInodeHash(V_id(vp),(nearInode)); (nearInode) %= V_partition(vp)-&gt;f_files
  #else
Index: openafs/src/vol/test/Makefile.in
diff -c openafs/src/vol/test/Makefile.in:1.7 openafs/src/vol/test/Makefile.in:1.8
*** openafs/src/vol/test/Makefile.in:1.7	Tue Oct 15 23:59:28 2002
--- openafs/src/vol/test/Makefile.in	Thu Mar  9 01:35:15 2006
***************
*** 11,17 ****
  
  INCDIRS=-I. -I.. -I${TOP_INCDIR} ${FSINCLUDES}
  INSTALL = ${SRCDIR}/bin/install
! LDFLAGS = ${OPTMZ} ${PROF} ${LDIRS} ${XLDFLAGS}
  
  LIBS=${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/vlib.a \
  	${TOP_LIBDIR}/util.a \
--- 11,17 ----
  
  INCDIRS=-I. -I.. -I${TOP_INCDIR} ${FSINCLUDES}
  INSTALL = ${SRCDIR}/bin/install
! LDFLAGS = ${OPTMZ} ${PROF} ${LDIRS} ${XLDFLAGS} ${ARCHFLAGS}
  
  LIBS=${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/vlib.a \
  	${TOP_LIBDIR}/util.a \
***************
*** 20,26 ****
  
  NAMEI_LIBS=../vlib.a ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/liblwp.a
  
! CFLAGS = -D${SYS_NAME} ${OPTMZ} ${INCDIRS} ${XCFLAGS} -g
  
  PROGS = listVicepx
  
--- 20,26 ----
  
  NAMEI_LIBS=../vlib.a ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/liblwp.a
  
! CFLAGS = -D${SYS_NAME} ${OPTMZ} ${INCDIRS} ${XCFLAGS} ${ARCHFLAGS} -g
  
  PROGS = listVicepx
  
Index: openafs/src/vol/test/listVicepx.c
diff -c openafs/src/vol/test/listVicepx.c:1.6 openafs/src/vol/test/listVicepx.c:1.7
*** openafs/src/vol/test/listVicepx.c:1.6	Tue Jul 15 19:17:43 2003
--- openafs/src/vol/test/listVicepx.c	Fri Mar 17 14:54:54 2006
***************
*** 18,24 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/test/listVicepx.c,v 1.6 2003/07/15 23:17:43 shadow Exp $");
  
  #include &lt;rx/xdr.h&gt;
  #include &lt;afs/afsint.h&gt;
--- 18,24 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/test/listVicepx.c,v 1.7 2006/03/17 19:54:54 shadow Exp $");
  
  #include &lt;rx/xdr.h&gt;
  #include &lt;afs/afsint.h&gt;
***************
*** 102,107 ****
--- 102,108 ----
  #include "afs/assert.h"
  #include "filesignal.h"
  #include "vutils.h"
+ #include "daemon_com.h"
  #include "fssync.h"
  #include &lt;afs/auxinode.h&gt;
  #include &lt;afs/dir.h&gt;
Index: openafs/src/vol/test/updateDirInode.c
diff -c openafs/src/vol/test/updateDirInode.c:1.5 openafs/src/vol/test/updateDirInode.c:1.6
*** openafs/src/vol/test/updateDirInode.c:1.5	Tue Jul 15 19:17:46 2003
--- openafs/src/vol/test/updateDirInode.c	Fri Mar 17 14:54:54 2006
***************
*** 18,24 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/test/updateDirInode.c,v 1.5 2003/07/15 23:17:46 shadow Exp $");
  
  #include &lt;rx/xdr.h&gt;
  #include &lt;afs/afsint.h&gt;
--- 18,24 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/test/updateDirInode.c,v 1.6 2006/03/17 19:54:54 shadow Exp $");
  
  #include &lt;rx/xdr.h&gt;
  #include &lt;afs/afsint.h&gt;
***************
*** 102,107 ****
--- 102,108 ----
  #include "afs/assert.h"
  #include "filesignal.h"
  #include "vutils.h"
+ #include "daemon_com.h"
  #include "fssync.h"
  #include &lt;afs/auxinode.h&gt;
  #include &lt;afs/dir.h&gt;
Index: openafs/src/volser/NTMakefile
diff -c openafs/src/volser/NTMakefile:1.10 openafs/src/volser/NTMakefile:1.11
*** openafs/src/volser/NTMakefile:1.10	Sun Nov 20 20:57:46 2005
--- openafs/src/volser/NTMakefile	Mon Mar 20 11:07:21 2006
***************
*** 5,10 ****
--- 5,12 ----
  # License.  For details, see the LICENSE file in the top-level source
  # directory or online at http://www.openafs.org/dl/license10.html
  
+ AFSDEV_AUXCDEFINES = -DFSSYNC_BUILD_CLIENT
+ 
  RELDIR=volser
  !INCLUDE ..\config\NTMakefile.$(SYS_NAME)
  !INCLUDE ..\config\NTMakefile.version
Index: openafs/src/volser/dumpstuff.c
diff -c openafs/src/volser/dumpstuff.c:1.26 openafs/src/volser/dumpstuff.c:1.29
*** openafs/src/volser/dumpstuff.c:1.26	Sat Oct 15 11:36:57 2005
--- openafs/src/volser/dumpstuff.c	Wed Apr 26 11:43:20 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/dumpstuff.c,v 1.26 2005/10/15 15:36:57 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;ctype.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/dumpstuff.c,v 1.29 2006/04/26 15:43:20 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #include &lt;ctype.h&gt;
***************
*** 51,56 ****
--- 51,57 ----
  #include &lt;afs/volume.h&gt;
  #include &lt;afs/partition.h&gt;
  #include "dump.h"
+ #include &lt;afs/daemon_com.h&gt;
  #include &lt;afs/fssync.h&gt;
  #include &lt;afs/acl.h&gt;
  #include "volser.h"
***************
*** 211,219 ****
  {
      register b1, b0;
      b1 = iod_getc(iodp);
      b0 = iod_getc(iodp);
      *sp = (b1 &lt;&lt; 8) | b0;
!     return b0 != EOF;
  }
  
  static int
--- 212,224 ----
  {
      register b1, b0;
      b1 = iod_getc(iodp);
+     if (b1 == EOF)
+ 	return 0;
      b0 = iod_getc(iodp);
+     if (b0 == EOF)
+ 	return 0;
      *sp = (b1 &lt;&lt; 8) | b0;
!     return 1;
  }
  
  static int
***************
*** 221,244 ****
  {
      afs_uint32 register b3, b2, b1, b0;
      b3 = iod_getc(iodp);
      b2 = iod_getc(iodp);
      b1 = iod_getc(iodp);
      b0 = iod_getc(iodp);
      *lp = (((((b3 &lt;&lt; 8) | b2) &lt;&lt; 8) | b1) &lt;&lt; 8) | b0;
!     return b0 != EOF;
  }
  
  static void
  ReadString(register struct iod *iodp, register char *to, register int maxa)
  {
      register int c;
      while (maxa--) {
! 	if ((*to++ = iod_getc(iodp)) == 0)
  	    break;
      }
      if (to[-1]) {
  	while ((c = iod_getc(iodp)) &amp;&amp; c != EOF);
! 	to[-1] = 0;
      }
  }
  
--- 226,263 ----
  {
      afs_uint32 register b3, b2, b1, b0;
      b3 = iod_getc(iodp);
+     if (b3 == EOF)
+ 	return 0;
      b2 = iod_getc(iodp);
+     if (b2 == EOF)
+ 	return 0;
      b1 = iod_getc(iodp);
+     if (b1 == EOF)
+ 	return 0;
      b0 = iod_getc(iodp);
+     if (b0 == EOF)
+ 	return 0;
      *lp = (((((b3 &lt;&lt; 8) | b2) &lt;&lt; 8) | b1) &lt;&lt; 8) | b0;
!     return 1;
  }
  
  static void
  ReadString(register struct iod *iodp, register char *to, register int maxa)
  {
      register int c;
+     int first = 1;
+ 
+     *to = '\0';
+     if (maxa == 0)
+ 	return;
+ 
      while (maxa--) {
! 	if ((*to++ = c = iod_getc(iodp)) == 0 || c == EOF)
  	    break;
      }
      if (to[-1]) {
  	while ((c = iod_getc(iodp)) &amp;&amp; c != EOF);
! 	to[-1] = '\0';
      }
  }
  
***************
*** 961,968 ****
  	     vcp-&gt;diskSize ? 0 : size - vcp-&gt;diskSize) &gt;&gt; vcp-&gt;logSize;
  	if (nVnodes &gt; 0) {
  	    Buf = (afs_int32 *) malloc(nVnodes * sizeof(afs_int32));
! 	    if (Buf == NULL)
  		return 1;
  	    memset((char *)Buf, 0, nVnodes * sizeof(afs_int32));
  	    STREAM_SEEK(afile, offset = vcp-&gt;diskSize, 0);
  	    while (1) {
--- 980,990 ----
  	     vcp-&gt;diskSize ? 0 : size - vcp-&gt;diskSize) &gt;&gt; vcp-&gt;logSize;
  	if (nVnodes &gt; 0) {
  	    Buf = (afs_int32 *) malloc(nVnodes * sizeof(afs_int32));
! 	    if (Buf == NULL) {
! 		STREAM_CLOSE(afile);
! 		FDH_CLOSE(fdP);
  		return 1;
+ 	    }
  	    memset((char *)Buf, 0, nVnodes * sizeof(afs_int32));
  	    STREAM_SEEK(afile, offset = vcp-&gt;diskSize, 0);
  	    while (1) {
***************
*** 997,1004 ****
      register Volume *vp;
      struct iod iod;
      register struct iod *iodp = &amp;iod;
!     afs_int32 *b1 = 0, *b2 = 0;
!     int s1 = 0, s2 = 0, delo = 0, tdelo;
      int tag;
  
      iod_Init(iodp, call);
--- 1019,1026 ----
      register Volume *vp;
      struct iod iod;
      register struct iod *iodp = &amp;iod;
!     afs_int32 *b1 = NULL, *b2 = NULL;
!     int s1 = 0, s2 = 0, delo = incremental, tdelo;
      int tag;
  
      iod_Init(iodp, call);
***************
*** 1015,1021 ****
      if (ReadVolumeHeader(iodp, &amp;vol) == VOLSERREAD_DUMPERROR)
  	return VOLSERREAD_DUMPERROR;
  
!     delo = ProcessIndex(vp, vLarge, &amp;b1, &amp;s1, 0);
      if (!delo)
  	delo = ProcessIndex(vp, vSmall, &amp;b2, &amp;s2, 0);
      if (delo) {
--- 1037,1044 ----
      if (ReadVolumeHeader(iodp, &amp;vol) == VOLSERREAD_DUMPERROR)
  	return VOLSERREAD_DUMPERROR;
  
!     if (!delo)
! 	delo = ProcessIndex(vp, vLarge, &amp;b1, &amp;s1, 0);
      if (!delo)
  	delo = ProcessIndex(vp, vSmall, &amp;b2, &amp;s2, 0);
      if (delo) {
***************
*** 1023,1029 ****
  	    free((char *)b1);
  	if (b2)
  	    free((char *)b2);
! 	b1 = b2 = 0;
      }
  
      strncpy(vol.name, cookie-&gt;name, VOLSER_OLDMAXVOLNAME);
--- 1046,1053 ----
  	    free((char *)b1);
  	if (b2)
  	    free((char *)b2);
! 	b1 = b2 = NULL;
! 	s1 = s2 = 0;
      }
  
      strncpy(vol.name, cookie-&gt;name, VOLSER_OLDMAXVOLNAME);
***************
*** 1034,1051 ****
  
      tdelo = delo;
      while (1) {
! 	if (ReadVnodes(iodp, vp, 0, b1, s1, b2, s2, tdelo)) {
  	    error = VOLSERREAD_DUMPERROR;
  	    goto clean;
  	}
  	tag = iod_getc(iodp);
  	if (tag != D_VOLUMEHEADER)
  	    break;
  	if (ReadVolumeHeader(iodp, &amp;vol) == VOLSERREAD_DUMPERROR) {
  	    error = VOLSERREAD_DUMPERROR;
  	    goto out;
  	}
- 	tdelo = -1;
      }
      if (tag != D_DUMPEND || !ReadInt32(iodp, &amp;endMagic)
  	|| endMagic != DUMPENDMAGIC) {
--- 1058,1081 ----
  
      tdelo = delo;
      while (1) {
! 	int temprc;
! 
! 	V_linkHandle(avp)-&gt;ih_flags |= IH_DELAY_SYNC;	/* Avoid repetitive fdsync()s on linkfile */
! 	temprc = ReadVnodes(iodp, vp, 0, b1, s1, b2, s2, tdelo);
! 	V_linkHandle(avp)-&gt;ih_flags &amp;= ~IH_DELAY_SYNC;	/* normal sync behaviour again */
! 	IH_CONDSYNC(V_linkHandle(avp));			/* sync link file */
! 	if (temprc) {
  	    error = VOLSERREAD_DUMPERROR;
  	    goto clean;
  	}
  	tag = iod_getc(iodp);
  	if (tag != D_VOLUMEHEADER)
  	    break;
+ 
  	if (ReadVolumeHeader(iodp, &amp;vol) == VOLSERREAD_DUMPERROR) {
  	    error = VOLSERREAD_DUMPERROR;
  	    goto out;
  	}
      }
      if (tag != D_DUMPEND || !ReadInt32(iodp, &amp;endMagic)
  	|| endMagic != DUMPENDMAGIC) {
***************
*** 1062,1069 ****
      }
  
      if (!delo) {
! 	ProcessIndex(vp, vLarge, &amp;b1, &amp;s1, 1);
! 	ProcessIndex(vp, vSmall, &amp;b2, &amp;s2, 1);
      }
  
    clean:
--- 1092,1104 ----
      }
  
      if (!delo) {
! 	delo = ProcessIndex(vp, vLarge, &amp;b1, &amp;s1, 1);
! 	if (!delo)
! 	    ProcessIndex(vp, vSmall, &amp;b2, &amp;s2, 1);
! 	if (delo) {
! 	    error = VOLSERREAD_DUMPERROR;
! 	    goto clean;
! 	}
      }
  
    clean:
***************
*** 1110,1116 ****
  	if (!ReadInt32(iodp, (afs_uint32 *) &amp; vnodeNumber))
  	    break;
  
! 	ReadInt32(iodp, &amp;vnode-&gt;uniquifier);
  	while ((tag = iod_getc(iodp)) &gt; D_MAX &amp;&amp; tag != EOF) {
  	    haveStuff = 1;
  	    switch (tag) {
--- 1145,1152 ----
  	if (!ReadInt32(iodp, (afs_uint32 *) &amp; vnodeNumber))
  	    break;
  
! 	if (!ReadInt32(iodp, &amp;vnode-&gt;uniquifier))
! 	    return VOLSERREAD_DUMPERROR;
  	while ((tag = iod_getc(iodp)) &gt; D_MAX &amp;&amp; tag != EOF) {
  	    haveStuff = 1;
  	    switch (tag) {
***************
*** 1120,1155 ****
  	    case 'l':
  		{
  		    unsigned short tlc;
! 		    ReadShort(iodp, &amp;tlc);
  		    vnode-&gt;linkCount = (signed int)tlc;
  		}
  		break;
  	    case 'v':
! 		ReadInt32(iodp, &amp;vnode-&gt;dataVersion);
  		break;
  	    case 'm':
! 		ReadInt32(iodp, &amp;vnode-&gt;unixModifyTime);
  		break;
  	    case 's':
! 		ReadInt32(iodp, &amp;vnode-&gt;serverModifyTime);
  		break;
  	    case 'a':
! 		ReadInt32(iodp, &amp;vnode-&gt;author);
  		break;
  	    case 'o':
! 		ReadInt32(iodp, &amp;vnode-&gt;owner);
  		break;
  	    case 'g':
! 		ReadInt32(iodp, (afs_uint32 *) &amp; vnode-&gt;group);
  		break;
  	    case 'b':{
  		    unsigned short modeBits;
! 		    ReadShort(iodp, &amp;modeBits);
  		    vnode-&gt;modeBits = (unsigned int)modeBits;
  		    break;
  		}
  	    case 'p':
! 		ReadInt32(iodp, &amp;vnode-&gt;parent);
  		break;
  	    case 'A':
  		ReadByteString(iodp, (byte *) VVnodeDiskACL(vnode),
--- 1156,1200 ----
  	    case 'l':
  		{
  		    unsigned short tlc;
! 		    if (!ReadShort(iodp, &amp;tlc))
! 			return VOLSERREAD_DUMPERROR;
  		    vnode-&gt;linkCount = (signed int)tlc;
  		}
  		break;
  	    case 'v':
! 		if (!ReadInt32(iodp, &amp;vnode-&gt;dataVersion))
! 		    return VOLSERREAD_DUMPERROR;
  		break;
  	    case 'm':
! 		if (!ReadInt32(iodp, &amp;vnode-&gt;unixModifyTime))
! 		    return VOLSERREAD_DUMPERROR;
  		break;
  	    case 's':
! 		if (!ReadInt32(iodp, &amp;vnode-&gt;serverModifyTime))
! 		    return VOLSERREAD_DUMPERROR;
  		break;
  	    case 'a':
! 		if (!ReadInt32(iodp, &amp;vnode-&gt;author))
! 		    return VOLSERREAD_DUMPERROR;
  		break;
  	    case 'o':
! 		if (!ReadInt32(iodp, &amp;vnode-&gt;owner))
! 		    return VOLSERREAD_DUMPERROR;
  		break;
  	    case 'g':
! 		if (!ReadInt32(iodp, (afs_uint32 *) &amp; vnode-&gt;group))
! 		    return VOLSERREAD_DUMPERROR;
  		break;
  	    case 'b':{
  		    unsigned short modeBits;
! 		    if (!ReadShort(iodp, &amp;modeBits))
! 			return VOLSERREAD_DUMPERROR;
  		    vnode-&gt;modeBits = (unsigned int)modeBits;
  		    break;
  		}
  	    case 'p':
! 		if (!ReadInt32(iodp, &amp;vnode-&gt;parent))
! 		    return VOLSERREAD_DUMPERROR;
  		break;
  	    case 'A':
  		ReadByteString(iodp, (byte *) VVnodeDiskACL(vnode),
***************
*** 1249,1255 ****
      }
      iod_ungetc(iodp, tag);
  
- 
      return 0;
  }
  
--- 1294,1299 ----
Index: openafs/src/volser/volmain.c
diff -c openafs/src/volser/volmain.c:1.21 openafs/src/volser/volmain.c:1.22
*** openafs/src/volser/volmain.c:1.21	Wed Feb  1 11:09:20 2006
--- openafs/src/volser/volmain.c	Tue Feb 21 23:07:40 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/volmain.c,v 1.21 2006/02/01 16:09:20 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #ifdef AFS_NT40_ENV
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/volmain.c,v 1.22 2006/02/22 04:07:40 jaltman Exp $");
  
  #include &lt;sys/types.h&gt;
  #ifdef AFS_NT40_ENV
***************
*** 242,247 ****
--- 242,248 ----
      char commandLine[150];
      int i;
      int rxJumbograms = 1;	/* default is to send and receive jumbograms. */
+     int rxMaxMTU = -1;
      int bufSize = 0;		/* temp variable to read in udp socket buf size */
  
  #ifdef	AFS_AIX32_ENV
***************
*** 326,331 ****
--- 327,345 ----
  		printf("Warning: auditlog %s not writable, ignored.\n", fileName);
  	} else if (strcmp(argv[code], "-nojumbo") == 0) {
  	    rxJumbograms = 0;
+ 	} else if (!strcmp(argv[code], "-rxmaxmtu")) {
+ 	    if ((code + 1) &gt;= argc) {
+ 		fprintf(stderr, "missing argument for -rxmaxmtu\n"); 
+ 		exit(1); 
+ 	    }
+ 	    rxMaxMTU = atoi(argv[++code]);
+ 	    if ((rxMaxMTU &lt; RX_MIN_PACKET_SIZE) || 
+ 		(rxMaxMTU &gt; RX_MAX_PACKET_DATA_SIZE)) {
+ 		printf("rxMaxMTU %d% invalid; must be between %d-%d\n",
+ 		       rxMaxMTU, RX_MIN_PACKET_SIZE, 
+ 		       RX_MAX_PACKET_DATA_SIZE);
+ 		exit(1);
+ 	    }
  	} else if (strcmp(argv[code], "-sleep") == 0) {
  	    sscanf(argv[++code], "%d/%d", &amp;TTsleep, &amp;TTrun);
  	    if ((TTsleep &lt; 0) || (TTrun &lt;= 0)) {
***************
*** 365,370 ****
--- 379,385 ----
  #ifndef AFS_NT40_ENV
  	    printf("Usage: volserver [-log] [-p &lt;number of processes&gt;] "
  		   "[-auditlog &lt;log path&gt;] "
+ 		   "[-nojumbo] [-rxmaxmtu &lt;bytes&gt;] "
  		   "[-udpsize &lt;size of socket buffer in bytes&gt;] "
  		   "[-syslog[=FACILITY]] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
***************
*** 372,377 ****
--- 387,393 ----
  #else
  	    printf("Usage: volserver [-log] [-p &lt;number of processes&gt;] "
  		   "[-auditlog &lt;log path&gt;] "
+ 		   "[-nojumbo] [-rxmaxmtu &lt;bytes&gt;] "
  		   "[-udpsize &lt;size of socket buffer in bytes&gt;] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
  		   "[-help]\n");
***************
*** 420,425 ****
--- 436,444 ----
  	/* Don't allow 3.4 vos clients to send jumbograms and we don't send. */
  	rx_SetNoJumbo();
      }
+     if (rxMaxMTU != -1) {
+ 	rx_SetMaxMTU(rxMaxMTU);
+     }
      rx_GetIFInfo();
      rx_SetRxDeadTime(420);
      memset(busyFlags, 0, sizeof(busyFlags));
Index: openafs/src/volser/volprocs.c
diff -c openafs/src/volser/volprocs.c:1.41 openafs/src/volser/volprocs.c:1.42
*** openafs/src/volser/volprocs.c:1.41	Tue Jan 24 22:24:25 2006
--- openafs/src/volser/volprocs.c	Fri Mar 17 14:54:56 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.41 2006/01/25 03:24:25 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;sys/types.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.42 2006/03/17 19:54:56 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;sys/types.h&gt;
***************
*** 61,66 ****
--- 61,67 ----
  #include &lt;afs/volume.h&gt;
  #include &lt;afs/partition.h&gt;
  #include "vol.h"
+ #include &lt;afs/daemon_com.h&gt;
  #include &lt;afs/fssync.h&gt;
  #include &lt;afs/acl.h&gt;
  #include "afs/audit.h"
***************
*** 844,850 ****
  
      {
  	struct DiskPartition *tpartp = originalvp-&gt;partition;
! 	FSYNC_askfs(cloneId, tpartp-&gt;name, FSYNC_RESTOREVOLUME, 0);
      }
      return 0;
  
--- 845,851 ----
  
      {
  	struct DiskPartition *tpartp = originalvp-&gt;partition;
! 	FSYNC_VolOp(cloneId, tpartp-&gt;name, FSYNC_VOL_BREAKCBKS, 0, NULL);
      }
      return 0;
  
***************
*** 1355,1362 ****
      DFlushVolume(V_parentId(tt-&gt;volume)); /* Ensure dir buffers get dropped */
  
      code = RestoreVolume(acid, tt-&gt;volume, (aflags &amp; 1), cookie);	/* last is incrementalp */
!     FSYNC_askfs(tt-&gt;volid, NULL, FSYNC_RESTOREVOLUME, 0l);	/*break call backs on the
! 								 * restored volume */
      tt-&gt;rxCallPtr = (struct rx_call *)0;
      tcode = TRELE(tt);
  
--- 1356,1362 ----
      DFlushVolume(V_parentId(tt-&gt;volume)); /* Ensure dir buffers get dropped */
  
      code = RestoreVolume(acid, tt-&gt;volume, (aflags &amp; 1), cookie);	/* last is incrementalp */
!     FSYNC_VolOp(tt-&gt;volid, NULL, FSYNC_VOL_BREAKCBKS, 0l, NULL);
      tt-&gt;rxCallPtr = (struct rx_call *)0;
      tcode = TRELE(tt);
  
***************
*** 1422,1428 ****
      }
      strcpy(tt-&gt;lastProcName, "SetForwarding");
      tt-&gt;rxCallPtr = acid;
!     FSYNC_askfs(tt-&gt;volid, NULL, FSYNC_MOVEVOLUME, anewsite);
      tt-&gt;rxCallPtr = (struct rx_call *)0;
      if (TRELE(tt))
  	return VOLSERTRELE_ERROR;
--- 1422,1428 ----
      }
      strcpy(tt-&gt;lastProcName, "SetForwarding");
      tt-&gt;rxCallPtr = acid;
!     FSYNC_VolOp(tt-&gt;volid, NULL, FSYNC_VOL_MOVE, anewsite, NULL);
      tt-&gt;rxCallPtr = (struct rx_call *)0;
      if (TRELE(tt))
  	return VOLSERTRELE_ERROR;
***************
*** 1672,1677 ****
--- 1672,1680 ----
  
      /* Only report attached partitions */
      for (i = 0; i &lt; VOLMAXPARTS; i++) {
+ #ifdef AFS_DEMAND_ATTACH_FS
+ 	dp = VGetPartitionById(i, 0);
+ #else
  	if (i &lt; 26) {
  	    namehead[6] = i + 'a';
  	    namehead[7] = '\0';
***************
*** 1682,1687 ****
--- 1685,1691 ----
  	    namehead[8] = '\0';
  	}
  	dp = VGetPartition(namehead, 0);
+ #endif
  	if (dp)
  	    partList.partId[j++] = i;
      }
***************
*** 1792,1798 ****
  		pntr-&gt;volid = volid;
  		goto drop;
  	    }
! 	    tv = VAttachVolumeByName(&amp;error, pname, volname, V_READONLY);
  	    if (error) {
  		pntr-&gt;status = 0;	/*things are messed up */
  		strcpy(pntr-&gt;name, volname);
--- 1796,1802 ----
  		pntr-&gt;volid = volid;
  		goto drop;
  	    }
! 	    tv = VAttachVolumeByName(&amp;error, pname, volname, V_PEEK);
  	    if (error) {
  		pntr-&gt;status = 0;	/*things are messed up */
  		strcpy(pntr-&gt;name, volname);
***************
*** 2007,2013 ****
  	    /*
  	     * Attach the volume, give up on the volume if we can't.
  	     */
! 	    tv = VAttachVolumeByName(&amp;error, pname, volname, V_READONLY);
  	    if (error) {
  		xInfoP-&gt;status = 0;	/*things are messed up */
  		strcpy(xInfoP-&gt;name, volname);
--- 2011,2017 ----
  	    /*
  	     * Attach the volume, give up on the volume if we can't.
  	     */
! 	    tv = VAttachVolumeByName(&amp;error, pname, volname, V_PEEK);
  	    if (error) {
  		xInfoP-&gt;status = 0;	/*things are messed up */
  		strcpy(xInfoP-&gt;name, volname);
***************
*** 2819,2825 ****
  	return EIO;
      }
      close(fd);
!     FSYNC_askfs(volumeId, pname, FSYNC_RESTOREVOLUME, 0);
  
      for (dp = DiskPartitionList; dp &amp;&amp; strcmp(dp-&gt;name, pname);
  	 dp = dp-&gt;next);
--- 2823,2829 ----
  	return EIO;
      }
      close(fd);
!     FSYNC_VolOp(volumeId, pname, FSYNC_VOL_BREAKCBKS, 0, NULL);
  
      for (dp = DiskPartitionList; dp &amp;&amp; strcmp(dp-&gt;name, pname);
  	 dp = dp-&gt;next);
***************
*** 2854,2861 ****
      if (unlink(opath) &lt; 0) {
  	Log("1 SAFS_VolConvertROtoRWvolume: Couldn't unlink RO header, error = %d\n", error);
      }
!     FSYNC_askfs(volumeId, pname, FSYNC_DONE, 0);
!     FSYNC_askfs(h.id, pname, FSYNC_ON, 0);
      return 0;
  #else /* AFS_NAMEI_ENV */
      return EINVAL;
--- 2858,2865 ----
      if (unlink(opath) &lt; 0) {
  	Log("1 SAFS_VolConvertROtoRWvolume: Couldn't unlink RO header, error = %d\n", error);
      }
!     FSYNC_VolOp(volumeId, pname, FSYNC_VOL_DONE, 0, NULL);
!     FSYNC_VolOp(h.id, pname, FSYNC_VOL_ON, 0, NULL);
      return 0;
  #else /* AFS_NAMEI_ENV */
      return EINVAL;
Index: openafs/src/volser/volser.p.h
diff -c openafs/src/volser/volser.p.h:1.9 openafs/src/volser/volser.p.h:1.10
*** openafs/src/volser/volser.p.h:1.9	Fri Jul  8 12:53:45 2005
--- openafs/src/volser/volser.p.h	Fri Mar 17 14:54:56 2006
***************
*** 15,20 ****
--- 15,22 ----
  #include &lt;pthread.h&gt;
  #endif
  
+ #include &lt;afs/voldefs.h&gt;
+ 
  /* vflags, representing state of the volume */
  #define	VTDeleteOnSalvage	1	/* delete on next salvage */
  #define	VTOutOfService		2	/* never put this volume online */
***************
*** 110,116 ****
  #define INVALID_BID 0
  #define VOLSER_MAXVOLNAME 65
  #define VOLSER_OLDMAXVOLNAME 32
- #define	VOLMAXPARTS	255
  
  /*flags used for interfacing with the  backup system */
  struct volDescription {		/*used for interfacing with the backup system */
--- 112,117 ----
Index: openafs/src/volser/vos.c
diff -c openafs/src/volser/vos.c:1.54 openafs/src/volser/vos.c:1.55
*** openafs/src/volser/vos.c:1.54	Thu Dec 15 23:25:48 2005
--- openafs/src/volser/vos.c	Mon Apr 17 10:59:04 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vos.c,v 1.54 2005/12/16 04:25:48 shadow Exp $");
  
  #include &lt;sys/types.h&gt;
  #ifdef AFS_NT40_ENV
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vos.c,v 1.55 2006/04/17 14:59:04 jaltman Exp $");
  
  #include &lt;sys/types.h&gt;
  #ifdef AFS_NT40_ENV
***************
*** 5578,5584 ****
  	code = ktime_DateToInt32(as-&gt;parms[4].items-&gt;data, &amp;fromdate);
  	if (code) {
  	    fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
! 		    as-&gt;parms[1].items-&gt;data, code);
  	    return code;
  	}
      }
--- 5578,5584 ----
  	code = ktime_DateToInt32(as-&gt;parms[4].items-&gt;data, &amp;fromdate);
  	if (code) {
  	    fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
! 		    as-&gt;parms[4].items-&gt;data, code);
  	    return code;
  	}
      }
Index: openafs/src/volser/vsprocs.c
diff -c openafs/src/volser/vsprocs.c:1.37 openafs/src/volser/vsprocs.c:1.38
*** openafs/src/volser/vsprocs.c:1.37	Tue Jan 24 22:49:25 2006
--- openafs/src/volser/vsprocs.c	Tue Apr  4 16:51:23 2006
***************
*** 11,17 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.37 2006/01/25 03:49:25 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;sys/types.h&gt;
--- 11,17 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.38 2006/04/04 20:51:23 shadow Exp $");
  
  #include &lt;stdio.h&gt;
  #include &lt;sys/types.h&gt;
***************
*** 3159,3164 ****
--- 3159,3165 ----
      afs_int32 clonetid = 0, onlinetid;
      afs_int32 fromtid = 0;
      afs_uint32 fromdate, thisdate;
+     time_t tmv;
      int s;
      manyDests tr;
      manyResults results;
***************
*** 3586,3593 ****
  
  	    if (fromdate == 0)
  		fprintf(STDOUT, " (full release)");
! 	    else
! 		fprintf(STDOUT, " (as of %.24s)", ctime((time_t *)&amp;fromdate));
  	    fprintf(STDOUT, ".\n");
  	    fflush(STDOUT);
  	}
--- 3587,3596 ----
  
  	    if (fromdate == 0)
  		fprintf(STDOUT, " (full release)");
! 	    else {
! 		tmv = fromdate;
! 		fprintf(STDOUT, " (as of %.24s)", ctime(&amp;tmv));
! 	    }
  	    fprintf(STDOUT, ".\n");
  	    fflush(STDOUT);
  	}
***************
*** 3838,3843 ****
--- 3841,3847 ----
      struct rx_call *fromcall = (struct rx_call *)0;
      afs_int32 fromtid = 0, rxError = 0, rcode = 0;
      afs_int32 code, error = 0;
+     time_t tmv = fromdate;
  
      if (setjmp(env))
  	ERROR_EXIT(EPIPE);
***************
*** 3850,3856 ****
  	VPRINT("Full Dump ...\n");
      } else {
  	VPRINT1("Incremental Dump (as of %.24s)...\n",
! 		ctime((time_t *) &amp; fromdate));
      }
  
      /* get connections to the servers */
--- 3854,3860 ----
  	VPRINT("Full Dump ...\n");
      } else {
  	VPRINT1("Incremental Dump (as of %.24s)...\n",
! 		ctime(&amp;tmv));
      }
  
      /* get connections to the servers */
***************
*** 3920,3925 ****
--- 3924,3930 ----
      afs_int32 code = 0, vcode = 0, error = 0;
      afs_int32 clonevol = 0;
      char vname[64];
+     time_t tmv = fromdate;
  
      if (setjmp(env))
  	ERROR_EXIT(EPIPE);
***************
*** 3932,3938 ****
  	VPRINT("Full Dump ...\n");
      } else {
  	VPRINT1("Incremental Dump (as of %.24s)...\n",
! 		ctime((time_t *) &amp; fromdate));
      }
  
      /* get connections to the servers */
--- 3937,3943 ----
  	VPRINT("Full Dump ...\n");
      } else {
  	VPRINT1("Incremental Dump (as of %.24s)...\n",
! 		ctime(&amp;tmv));
      }
  
      /* get connections to the servers */
Index: openafs/src/xstat/NTMakefile
diff -c /dev/null openafs/src/xstat/NTMakefile:1.2
*** /dev/null	Thu Apr 27 12:42:33 2006
--- openafs/src/xstat/NTMakefile	Sun Mar  5 22:11:31 2006
***************
*** 0 ****
--- 1,81 ----
+ # Copyright 2000, International Business Machines Corporation and others.
+ # All Rights Reserved.
+ # 
+ # This software has been released under the terms of the IBM Public
+ # License.  For details, see the LICENSE file in the top-level source
+ # directory or online at http://www.openafs.org/dl/license10.html
+ 
+ # Makefile for the module providing the client side of the File Server
+ # and Cache Manager extended statistics gathering.
+ 
+ RELDIR=xstat
+ !INCLUDE ..\config\NTMakefile.$(SYS_NAME)
+ !INCLUDE ..\config\NTMakefile.version
+ 
+ LIBDIR = $(DESTDIR)\lib
+ INCDIR = $(DESTDIR)\include
+ BINDIR = $(DESTDIR)\bin
+ 
+ RPCINCLS=$(INCDIR)\lwp.h $(INCDIR)\rx\rx.h
+ 
+ LIBS= \
+  	$(LIBDIR)\afs\afsint.lib \
+ 	$(LIBDIR)\afs\afscmd.lib \
+ 	$(LIBDIR)\afsrx.lib \
+ 	$(LIBDIR)\afslwp.lib \
+ 	$(LIBDIR)\afs\afspioctl.lib \
+ 	$(LIBDIR)\afs\afsutil.lib \
+ 	$(LIBDIR)\afs\afsreg.lib
+ 
+ 
+ install: \
+ 	$(INCDIR)\afs\xstat_fs.h \
+ 	$(INCDIR)\afs\xstat_cm.h \
+ 	$(LIBDIR)\afs_xstat_fs.lib \
+ 	$(LIBDIR)\afs_xstat_cm.lib \
+ 	$(BINDIR)\xstat_fs_test.exe \
+ 	$(BINDIR)\xstat_cm_test.exe
+ 
+ #
+ # File Server data collection
+ #
+ FSINCLS= $(INCDIR)\xstat_fs.h $(RPCINCLS)
+ 
+ {.}.c{$(OUT)}.obj:
+     $(C2OBJ) $&lt;
+ 
+ $(LIBDIR)\afs_xstat_fs.lib: $(OUT)\xstat_fs.obj $(OUT)\xstat_fs_callback.obj $(OUT)\AFS_component_version_number.obj
+ 	$(LIBARCH)
+ 
+ $(BINDIR)\xstat_fs_test.exe: $(OUT)\xstat_fs_test.obj $(LIBDIR)\afs_xstat_fs.lib $(LIBS)
+ 	$(EXECONLINK) rpcrt4.lib
+ 	$(_VC_MANIFEST_EMBED_EXE)
+ 	$(EXEPREP)
+ 
+ #
+ # Cache Manager data collection
+ #
+ CMINCLS=$(INCDIR)\xstat_cm.h $(RPCINCLS)
+ 
+ $(LIBDIR)\afs_xstat_cm.lib: $(OUT)\xstat_cm.obj $(OUT)\AFS_component_version_number.obj
+ 	$(LIBARCH)
+ 
+ $(BINDIR)\xstat_cm_test.exe: $(OUT)\xstat_cm_test.obj $(LIBDIR)\afs_xstat_cm.lib $(LIBS)
+ 	$(EXECONLINK) 
+ 	$(_VC_MANIFEST_EMBED_EXE)
+ 	$(EXEPREP)
+ 
+ #
+ # Misc targets
+ #
+ clean::
+ 	$(DEL) -f $(OUT)\*.obj
+ 	$(DEL) -f $(OUT)\*.pdb
+ 	$(DEL) -f $(OUT)\*.ilk
+  	$(DEL) -f $(INCDIR)\afs\xstat_fs.h
+ 	$(DEL) -f $(INCDIR)\afs\xstat_cm.h
+ 	$(DEL) -f $(LIBDIR)\afs_xstat_fs.lib
+ 	$(DEL) -f $(LIBDIR)\afs_xstat_cm.lib
+ 	$(DEL) -f $(BINDIR)\xstat_cm_test.exe
+ 	$(DEL) -f $(BINDIR)\xstat_fs_test.exe
+ 	$(DEL) -f AFS_component_version_number.c
Index: openafs/src/xstat/xstat_cm.c
diff -c openafs/src/xstat/xstat_cm.c:1.9 openafs/src/xstat/xstat_cm.c:1.10
*** openafs/src/xstat/xstat_cm.c:1.9	Tue Jul 15 19:17:52 2003
--- openafs/src/xstat/xstat_cm.c	Sun Mar  5 22:11:31 2006
***************
*** 18,24 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_cm.c,v 1.9 2003/07/15 23:17:52 shadow Exp $");
  
  #include "xstat_cm.h"		/*Interface for this module */
  #include &lt;lwp.h&gt;		/*Lightweight process package */
--- 18,24 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_cm.c,v 1.10 2006/03/06 03:11:31 jaltman Exp $");
  
  #include "xstat_cm.h"		/*Interface for this module */
  #include &lt;lwp.h&gt;		/*Lightweight process package */
***************
*** 403,408 ****
--- 403,409 ----
      char *hostNameFound;	/*Ptr to returned host name */
      int conn_err;		/*Connection error? */
      int collIDBytes;		/*Num bytes in coll ID array */
+     char hoststr[16];
  
      /*
       * If we've already been called, snicker at the bozo, gently
***************
*** 528,536 ****
  	 */
  	if (xstat_cm_debug) {
  	    printf("[%s] Copying in the following socket info:\n", rn);
! 	    printf("[%s] IP addr 0x%lx, port %d\n", rn,
! 		   (a_socketArray + curr_srv)-&gt;sin_addr.s_addr,
! 		   (a_socketArray + curr_srv)-&gt;sin_port);
  	}
  	memcpy(&amp;(curr_conn-&gt;skt), a_socketArray + curr_srv,
  	       sizeof(struct sockaddr_in));
--- 529,537 ----
  	 */
  	if (xstat_cm_debug) {
  	    printf("[%s] Copying in the following socket info:\n", rn);
! 	    printf("[%s] IP addr 0s, port %d\n", rn,
! 		   afs_inet_ntoa_r((a_socketArray + curr_srv)-&gt;sin_addr.s_addr,hoststr),
! 		   ntohs((a_socketArray + curr_srv)-&gt;sin_port));
  	}
  	memcpy(&amp;(curr_conn-&gt;skt), a_socketArray + curr_srv,
  	       sizeof(struct sockaddr_in));
***************
*** 539,546 ****
  	    hostutil_GetNameByINet(curr_conn-&gt;skt.sin_addr.s_addr);
  	if (hostNameFound == NULL) {
  	    fprintf(stderr,
! 		    "[%s] Can't map Internet address %lu to a string name\n",
! 		    rn, curr_conn-&gt;skt.sin_addr.s_addr);
  	    curr_conn-&gt;hostName[0] = '\0';
  	} else {
  	    strcpy(curr_conn-&gt;hostName, hostNameFound);
--- 540,547 ----
  	    hostutil_GetNameByINet(curr_conn-&gt;skt.sin_addr.s_addr);
  	if (hostNameFound == NULL) {
  	    fprintf(stderr,
! 		    "[%s] Can't map Internet address %s to a string name\n",
! 		    rn, afs_inet_ntoa_r(curr_conn-&gt;skt.sin_addr.s_addr,hoststr));
  	    curr_conn-&gt;hostName[0] = '\0';
  	} else {
  	    strcpy(curr_conn-&gt;hostName, hostNameFound);
***************
*** 554,562 ****
  	 */
  	if (xstat_cm_debug)
  	    printf
! 		("[%s] Connecting to srv idx %d, IP addr 0x%lx, port %d, service 1\n",
! 		 rn, curr_srv, curr_conn-&gt;skt.sin_addr.s_addr,
! 		 curr_conn-&gt;skt.sin_port);
  	curr_conn-&gt;rxconn = rx_NewConnection(curr_conn-&gt;skt.sin_addr.s_addr,	/*Server addr */
  					     curr_conn-&gt;skt.sin_port,	/*Server port */
  					     1,	/*AFS service # */
--- 555,563 ----
  	 */
  	if (xstat_cm_debug)
  	    printf
! 		("[%s] Connecting to srv idx %d, IP addr %s, port %d, service 1\n",
! 		 rn, curr_srv, afs_inet_ntoa_r(curr_conn-&gt;skt.sin_addr.s_addr,hoststr),
! 		 ntohs(curr_conn-&gt;skt.sin_port));
  	curr_conn-&gt;rxconn = rx_NewConnection(curr_conn-&gt;skt.sin_addr.s_addr,	/*Server addr */
  					     curr_conn-&gt;skt.sin_port,	/*Server port */
  					     1,	/*AFS service # */
***************
*** 564,571 ****
  					     0);	/*# of above */
  	if (curr_conn-&gt;rxconn == (struct rx_connection *)0) {
  	    fprintf(stderr,
! 		    "[%s] Can't create Rx connection to server '%s' (%lu)\n",
! 		    rn, curr_conn-&gt;hostName, curr_conn-&gt;skt.sin_addr.s_addr);
  	    conn_err = 1;
  	}
  	if (xstat_cm_debug)
--- 565,572 ----
  					     0);	/*# of above */
  	if (curr_conn-&gt;rxconn == (struct rx_connection *)0) {
  	    fprintf(stderr,
! 		    "[%s] Can't create Rx connection to server '%s' (%s)\n",
! 		    rn, curr_conn-&gt;hostName, afs_inet_ntoa_r(curr_conn-&gt;skt.sin_addr.s_addr,hoststr));
  	    conn_err = 1;
  	}
  	if (xstat_cm_debug)
Index: openafs/src/xstat/xstat_cm.h
diff -c openafs/src/xstat/xstat_cm.h:1.3 openafs/src/xstat/xstat_cm.h:1.4
*** openafs/src/xstat/xstat_cm.h:1.3	Tue Jul 15 19:17:52 2003
--- openafs/src/xstat/xstat_cm.h	Sat Mar  4 16:39:39 2006
***************
*** 21,26 ****
--- 21,27 ----
   *------------------------------------------------------------------------*/
  
  #include &lt;sys/types.h&gt;		/*Basic system types */
+ #ifndef AFS_NT40_ENV
  #ifndef	IPPROTO_IP
  #include &lt;netinet/in.h&gt;		/*Internet definitions */
  #endif
***************
*** 34,39 ****
--- 35,41 ----
  #define _socket_h_
  #include &lt;sys/socket.h&gt;		/*Socket definitions */
  #endif
+ #endif /* AFS_NT40_ENV */
  
  #include &lt;rx/rx.h&gt;		/*Rx definitions */
  #include &lt;afs/afscbint.h&gt;	/*AFS CM callback interface */
Index: openafs/src/xstat/xstat_cm_test.c
diff -c openafs/src/xstat/xstat_cm_test.c:1.9 openafs/src/xstat/xstat_cm_test.c:1.11
*** openafs/src/xstat/xstat_cm_test.c:1.9	Wed Apr 27 08:38:00 2005
--- openafs/src/xstat/xstat_cm_test.c	Tue Apr  4 16:51:24 2006
***************
*** 17,23 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_cm_test.c,v 1.9 2005/04/27 12:38:00 shadow Exp $");
  
  #include "xstat_cm.h"		/*Interface for xstat_cm module */
  #include &lt;cmd.h&gt;		/*Command line interpreter */
--- 17,23 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_cm_test.c,v 1.11 2006/04/04 20:51:24 shadow Exp $");
  
  #include "xstat_cm.h"		/*Interface for xstat_cm module */
  #include &lt;cmd.h&gt;		/*Command line interpreter */
***************
*** 132,144 ****
      int numInt32s;		/*# int32words returned */
      afs_int32 *currInt32;	/*Ptr to current afs_int32 value */
      char *printableTime;	/*Ptr to printable time string */
! 
      /*
       * Just print out the results of the particular probe.
       */
      numInt32s = xstat_cm_Results.data.AFSCB_CollData_len;
      currInt32 = (afs_int32 *) (xstat_cm_Results.data.AFSCB_CollData_val);
!     printableTime = ctime((time_t *) &amp; (xstat_cm_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
  
      printf
--- 132,144 ----
      int numInt32s;		/*# int32words returned */
      afs_int32 *currInt32;	/*Ptr to current afs_int32 value */
      char *printableTime;	/*Ptr to printable time string */
!     time_t probeTime = xstat_cm_Results.probeTime;
      /*
       * Just print out the results of the particular probe.
       */
      numInt32s = xstat_cm_Results.data.AFSCB_CollData_len;
      currInt32 = (afs_int32 *) (xstat_cm_Results.data.AFSCB_CollData_val);
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
  
      printf
***************
*** 163,170 ****
      static char rn[] = "print_cmCallStats";	/*Routine name */
      char *printableTime;	/*Ptr to printable time string */
      struct afs_CMStats *cmp;
  
!     printableTime = ctime((time_t *) &amp; (xstat_cm_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
  
      printf
--- 163,171 ----
      static char rn[] = "print_cmCallStats";	/*Routine name */
      char *printableTime;	/*Ptr to printable time string */
      struct afs_CMStats *cmp;
+     time_t probeTime = xstat_cm_Results.probeTime;
  
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
  
      printf
***************
*** 805,810 ****
--- 806,812 ----
      afs_int32 numInt32s;	/*# int32words received */
      struct afs_stats_CMPerf *perfP;	/*Ptr to performance stats */
      char *printableTime;	/*Ptr to printable time string */
+     time_t probeTime = xstat_cm_Results.probeTime;
  
      numInt32s = xstat_cm_Results.data.AFSCB_CollData_len;
      if (numInt32s != perfInt32s) {
***************
*** 814,820 ****
  	return;
      }
  
!     printableTime = ctime((time_t *) &amp; (xstat_cm_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
      perfP = (struct afs_stats_CMPerf *)
  	(xstat_cm_Results.data.AFSCB_CollData_val);
--- 816,822 ----
  	return;
      }
  
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
      perfP = (struct afs_stats_CMPerf *)
  	(xstat_cm_Results.data.AFSCB_CollData_val);
***************
*** 1036,1041 ****
--- 1038,1044 ----
      struct afs_stats_CMFullPerf *fullP;	/*Ptr to full perf info */
  
      char *printableTime;	/*Ptr to printable time string */
+     time_t probeTime = xstat_cm_Results.probeTime;
  
      numInt32s = xstat_cm_Results.data.AFSCB_CollData_len;
      if (numInt32s != fullPerfInt32s) {
***************
*** 1045,1051 ****
  	return;
      }
  
!     printableTime = ctime((time_t *) &amp; (xstat_cm_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
      fullP = (struct afs_stats_CMFullPerf *)
  	(xstat_cm_Results.data.AFSCB_CollData_val);
--- 1048,1054 ----
  	return;
      }
  
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
      fullP = (struct afs_stats_CMFullPerf *)
  	(xstat_cm_Results.data.AFSCB_CollData_val);
***************
*** 1308,1314 ****
--- 1311,1321 ----
       */
      curr_item = a_s-&gt;parms[P_CM_NAMES].items;
      for (currCM = 0; currCM &lt; numCMs; currCM++) {
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+ 	CMSktArray[currCM].sin_family = AF_INET;	/*Internet family */
+ #else
  	CMSktArray[currCM].sin_family = htons(AF_INET);	/*Internet family */
+ #endif
  	CMSktArray[currCM].sin_port = htons(7001);	/*Cache Manager port */
  	he = hostutil_GetHostByName(curr_item-&gt;data);
  	if (he == NULL) {
Index: openafs/src/xstat/xstat_fs.c
diff -c openafs/src/xstat/xstat_fs.c:1.9 openafs/src/xstat/xstat_fs.c:1.10
*** openafs/src/xstat/xstat_fs.c:1.9	Tue Jul 15 19:17:52 2003
--- openafs/src/xstat/xstat_fs.c	Sun Mar  5 22:11:31 2006
***************
*** 18,24 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_fs.c,v 1.9 2003/07/15 23:17:52 shadow Exp $");
  
  #include "xstat_fs.h"		/*Interface for this module */
  #include &lt;lwp.h&gt;		/*Lightweight process package */
--- 18,24 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_fs.c,v 1.10 2006/03/06 03:11:31 jaltman Exp $");
  
  #include "xstat_fs.h"		/*Interface for this module */
  #include &lt;lwp.h&gt;		/*Lightweight process package */
***************
*** 46,51 ****
--- 46,52 ----
  extern afs_int32 SRXAFSCB_CallBack();
  extern afs_int32 SRXAFSCB_InitCallBackState3();
  extern afs_int32 SRXAFSCB_Probe();
+ extern afs_int32 SRXAFSCB_ProbeUUID();
  extern afs_int32 SRXAFSCB_GetCE();
  extern afs_int32 SRXAFSCB_GetLock();
  
***************
*** 444,449 ****
--- 445,451 ----
      int conn_err;		/*Connection error? */
      int PortToUse;		/*Callback port to use */
      int collIDBytes;		/*Num bytes in coll ID array */
+     char hoststr[16];
  
      /*
       * If we've already been called, snicker at the bozo, gently
***************
*** 594,603 ****
  	 * printable name if possible.
  	 */
  	if (xstat_fs_debug) {
  	    printf("[%s] Copying in the following socket info:\n", rn);
! 	    printf("[%s] IP addr 0x%lx, port %d\n", rn,
! 		   (a_socketArray + curr_srv)-&gt;sin_addr.s_addr,
! 		   (a_socketArray + curr_srv)-&gt;sin_port);
  	}
  	memcpy(&amp;(curr_conn-&gt;skt), a_socketArray + curr_srv,
  	       sizeof(struct sockaddr_in));
--- 596,606 ----
  	 * printable name if possible.
  	 */
  	if (xstat_fs_debug) {
+ 	    char hoststr[16];
  	    printf("[%s] Copying in the following socket info:\n", rn);
! 	    printf("[%s] IP addr %s, port %d\n", rn,
! 		   afs_inet_ntoa_r((a_socketArray + curr_srv)-&gt;sin_addr.s_addr,hoststr),
! 		   ntohs((a_socketArray + curr_srv)-&gt;sin_port));
  	}
  	memcpy(&amp;(curr_conn-&gt;skt), a_socketArray + curr_srv,
  	       sizeof(struct sockaddr_in));
***************
*** 606,613 ****
  	    hostutil_GetNameByINet(curr_conn-&gt;skt.sin_addr.s_addr);
  	if (hostNameFound == NULL) {
  	    fprintf(stderr,
! 		    "[%s] Can't map Internet address %lu to a string name\n",
! 		    rn, curr_conn-&gt;skt.sin_addr.s_addr);
  	    curr_conn-&gt;hostName[0] = '\0';
  	} else {
  	    strcpy(curr_conn-&gt;hostName, hostNameFound);
--- 609,616 ----
  	    hostutil_GetNameByINet(curr_conn-&gt;skt.sin_addr.s_addr);
  	if (hostNameFound == NULL) {
  	    fprintf(stderr,
! 		    "[%s] Can't map Internet address %s to a string name\n",
! 		    rn, afs_inet_ntoa_r(curr_conn-&gt;skt.sin_addr.s_addr,hoststr));
  	    curr_conn-&gt;hostName[0] = '\0';
  	} else {
  	    strcpy(curr_conn-&gt;hostName, hostNameFound);
***************
*** 621,629 ****
  	 */
  	if (xstat_fs_debug)
  	    printf
! 		("[%s] Connecting to srv idx %d, IP addr 0x%lx, port %d, service 1\n",
! 		 rn, curr_srv, curr_conn-&gt;skt.sin_addr.s_addr,
! 		 curr_conn-&gt;skt.sin_port);
  
  	curr_conn-&gt;rxconn = rx_NewConnection(curr_conn-&gt;skt.sin_addr.s_addr,	/*Server addr */
  					     curr_conn-&gt;skt.sin_port,	/*Server port */
--- 624,632 ----
  	 */
  	if (xstat_fs_debug)
  	    printf
! 		("[%s] Connecting to srv idx %d, IP addr %s, port %d, service 1\n",
! 		 rn, curr_srv, afs_inet_ntoa_r(curr_conn-&gt;skt.sin_addr.s_addr,hoststr),
! 		 ntohs(curr_conn-&gt;skt.sin_port));
  
  	curr_conn-&gt;rxconn = rx_NewConnection(curr_conn-&gt;skt.sin_addr.s_addr,	/*Server addr */
  					     curr_conn-&gt;skt.sin_port,	/*Server port */
***************
*** 632,639 ****
  					     0);	/*# of above */
  	if (curr_conn-&gt;rxconn == (struct rx_connection *)0) {
  	    fprintf(stderr,
! 		    "[%s] Can't create Rx connection to server '%s' (%lu)\n",
! 		    rn, curr_conn-&gt;hostName, curr_conn-&gt;skt.sin_addr.s_addr);
  	    conn_err = 1;
  	}
  	if (xstat_fs_debug)
--- 635,642 ----
  					     0);	/*# of above */
  	if (curr_conn-&gt;rxconn == (struct rx_connection *)0) {
  	    fprintf(stderr,
! 		    "[%s] Can't create Rx connection to server '%s' (%s)\n",
! 		    rn, curr_conn-&gt;hostName, afs_inet_ntoa_r(curr_conn-&gt;skt.sin_addr.s_addr,hoststr));
  	    conn_err = 1;
  	}
  	if (xstat_fs_debug)
Index: openafs/src/xstat/xstat_fs.h
diff -c openafs/src/xstat/xstat_fs.h:1.3 openafs/src/xstat/xstat_fs.h:1.4
*** openafs/src/xstat/xstat_fs.h:1.3	Tue Jul 15 19:17:52 2003
--- openafs/src/xstat/xstat_fs.h	Sat Mar  4 16:39:39 2006
***************
*** 21,26 ****
--- 21,27 ----
   *------------------------------------------------------------------------*/
  
  #include &lt;sys/types.h&gt;		/*Basic system types */
+ #ifndef AFS_NT40_ENV
  #ifndef	IPPROTO_IP
  #include &lt;netinet/in.h&gt;		/*Internet definitions */
  #endif
***************
*** 34,39 ****
--- 35,41 ----
  #define _socket_h_
  #include &lt;sys/socket.h&gt;		/*Socket definitions */
  #endif
+ #endif /* AFS_NT40_ENV */
  
  #include &lt;rx/rx.h&gt;		/*Rx definitions */
  #include &lt;afs/afsint.h&gt;		/*AFS FileServer interface */
Index: openafs/src/xstat/xstat_fs_callback.c
diff -c openafs/src/xstat/xstat_fs_callback.c:1.14 openafs/src/xstat/xstat_fs_callback.c:1.15
*** openafs/src/xstat/xstat_fs_callback.c:1.14	Fri Oct  7 16:11:12 2005
--- openafs/src/xstat/xstat_fs_callback.c	Sun Mar  5 22:11:31 2006
***************
*** 24,32 ****
  
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_fs_callback.c,v 1.14 2005/10/07 20:11:12 shadow Exp $");
  
  #include &lt;errno.h&gt;
  #include &lt;stdio.h&gt;		/*Standard I/O stuff */
--- 24,36 ----
  
  #include &lt;afsconfig.h&gt;
  #include &lt;afs/param.h&gt;
+ #ifdef AFS_NT40_ENV
+ #include &lt;windows.h&gt;
+ #include &lt;rpc.h&gt;
+ #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_fs_callback.c,v 1.15 2006/03/06 03:11:31 jaltman Exp $");
  
  #include &lt;errno.h&gt;
  #include &lt;stdio.h&gt;		/*Standard I/O stuff */
***************
*** 54,60 ****
--- 58,68 ----
  {
      int count;
  
+ #ifdef AFS_NT40_ENV
+     UuidCreate((UUID *)&amp;afs_cb_interface.uuid);
+ #else
      afs_uuid_create(&amp;afs_cb_interface.uuid);
+ #endif
      count = rx_getAllAddr(&amp;afs_cb_interface.addr_in, AFS_MAX_INTERFACE_ADDR);
      if (count &lt;= 0)
  	afs_cb_interface.numberOfInterfaces = 0;
Index: openafs/src/xstat/xstat_fs_test.c
diff -c openafs/src/xstat/xstat_fs_test.c:1.9 openafs/src/xstat/xstat_fs_test.c:1.15
*** openafs/src/xstat/xstat_fs_test.c:1.9	Thu Jan 13 22:03:31 2005
--- openafs/src/xstat/xstat_fs_test.c	Mon Apr 10 11:42:34 2006
***************
*** 17,23 ****
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_fs_test.c,v 1.9 2005/01/14 03:03:31 shadow Exp $");
  
  #include "xstat_fs.h"		/*Interface for xstat_fs module */
  #include &lt;cmd.h&gt;		/*Command line interpreter */
--- 17,23 ----
  #include &lt;afs/param.h&gt;
  
  RCSID
!     ("$Header: /cvs/openafs/src/xstat/xstat_fs_test.c,v 1.15 2006/04/10 15:42:34 shadow Exp $");
  
  #include "xstat_fs.h"		/*Interface for xstat_fs module */
  #include &lt;cmd.h&gt;		/*Command line interpreter */
***************
*** 121,133 ****
      int numInt32s;		/*# int32words returned */
      afs_int32 *currInt32;	/*Ptr to current afs_int32 value */
      char *printableTime;	/*Ptr to printable time string */
  
      /*
       * Just print out the results of the particular probe.
       */
      numInt32s = xstat_fs_Results.data.AFS_CollData_len;
      currInt32 = (afs_int32 *) (xstat_fs_Results.data.AFS_CollData_val);
!     printableTime = ctime((time_t *) &amp; (xstat_fs_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
  
      printf("AFS_XSTATSCOLL_CALL_INFO (coll %d) for FS %s\n[Probe %d, %s]\n\n",
--- 121,134 ----
      int numInt32s;		/*# int32words returned */
      afs_int32 *currInt32;	/*Ptr to current afs_int32 value */
      char *printableTime;	/*Ptr to printable time string */
+     time_t probeTime = xstat_fs_Results.probeTime;
  
      /*
       * Just print out the results of the particular probe.
       */
      numInt32s = xstat_fs_Results.data.AFS_CollData_len;
      currInt32 = (afs_int32 *) (xstat_fs_Results.data.AFS_CollData_val);
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
  
      printf("AFS_XSTATSCOLL_CALL_INFO (coll %d) for FS %s\n[Probe %d, %s]\n\n",
***************
*** 249,255 ****
      printf("\t%10d rx_nFreeCallStructs\n", a_ovP-&gt;rx_nFreeCallStructs);
      printf("\t%10d rx_nBusies\n\n", a_ovP-&gt;rx_nBusies);
  
!     printf("\t%10d fs_nBusies\n\n", a_ovP-&gt;fs_nBusies);
      /*
       * Host module fields.
       */
--- 250,257 ----
      printf("\t%10d rx_nFreeCallStructs\n", a_ovP-&gt;rx_nFreeCallStructs);
      printf("\t%10d rx_nBusies\n\n", a_ovP-&gt;rx_nBusies);
  
!     printf("\t%10d fs_nBusies\n", a_ovP-&gt;fs_nBusies);
!     printf("\t%10d fs_GetCapabilities\n\n", a_ovP-&gt;fs_nGetCaps);
      /*
       * Host module fields.
       */
***************
*** 421,426 ****
--- 423,429 ----
      struct fs_stats_FullPerfStats *fullPerfP;	/*Ptr to full perf stats */
      char *printableTime;	/*Ptr to printable time
  				 * string */
+     time_t probeTime = xstat_fs_Results.probeTime;
  
      numInt32s = xstat_fs_Results.data.AFS_CollData_len;
      if (numInt32s != fullPerfInt32s) {
***************
*** 429,435 ****
  	return;
      }
  
!     printableTime = ctime((time_t *) &amp; (xstat_fs_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
      fullPerfP = (struct fs_stats_FullPerfStats *)
  	(xstat_fs_Results.data.AFS_CollData_val);
--- 432,438 ----
  	return;
      }
  
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
      fullPerfP = (struct fs_stats_FullPerfStats *)
  	(xstat_fs_Results.data.AFS_CollData_val);
***************
*** 472,477 ****
--- 475,481 ----
      afs_int32 numInt32s;	/*# int32words received */
      struct afs_PerfStats *perfP;	/*Ptr to performance stats */
      char *printableTime;	/*Ptr to printable time string */
+     time_t probeTime = xstat_fs_Results.probeTime;
  
      numInt32s = xstat_fs_Results.data.AFS_CollData_len;
      if (numInt32s != perfInt32s) {
***************
*** 480,486 ****
  	return;
      }
  
!     printableTime = ctime((time_t *) &amp; (xstat_fs_Results.probeTime));
      printableTime[strlen(printableTime) - 1] = '\0';
      perfP = (struct afs_PerfStats *)
  	(xstat_fs_Results.data.AFS_CollData_val);
--- 484,490 ----
  	return;
      }
  
!     printableTime = ctime(&amp;probeTime);
      printableTime[strlen(printableTime) - 1] = '\0';
      perfP = (struct afs_PerfStats *)
  	(xstat_fs_Results.data.AFS_CollData_val);
***************
*** 493,498 ****
--- 497,530 ----
      PrintOverallPerfInfo(perfP);
  }
  
+ static char *CbCounterStrings[] = {
+     "DeleteFiles",
+     "DeleteCallBacks",
+     "BreakCallBacks",
+     "AddCallBack",
+     "GotSomeSpaces",
+     "DeleteAllCallBacks",
+     "nFEs", "nCBs", "nblks",
+     "CBsTimedOut",
+     "nbreakers",
+     "GSS1", "GSS2", "GSS3", "GSS4", "GSS5"
+ };
+ 
+ 
+ void
+ PrintCbCounters() {
+     int numInt32s = sizeof(CbCounterStrings)/sizeof(char *);
+     int i;
+     afs_uint32 *val=xstat_fs_Results.data.AFS_CollData_val;
+ 
+     if (numInt32s &gt; xstat_fs_Results.data.AFS_CollData_len)
+ 	numInt32s = xstat_fs_Results.data.AFS_CollData_len;
+ 
+     for (i=0; i&lt;numInt32s; i++) {
+ 	printf("\t%10u %s\n", val[i], CbCounterStrings[i]);
+     }
+ }
+ 
  
  /*------------------------------------------------------------------------
   * FS_Handler
***************
*** 549,554 ****
--- 581,590 ----
  	PrintFullPerfInfo();
  	break;
  
+     case AFS_XSTATSCOLL_CBSTATS:
+ 	PrintCbCounters();
+ 	break;
+ 
      default:
  	printf("** Unknown collection: %d\n",
  	       xstat_fs_Results.collectionNumber);
***************
*** 687,693 ****
--- 723,733 ----
       */
      curr_item = a_s-&gt;parms[P_FS_NAMES].items;
      for (currFS = 0; currFS &lt; numFSs; currFS++) {
+ #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+ 	FSSktArray[currFS].sin_family = AF_INET;	/*Internet family */
+ #else
  	FSSktArray[currFS].sin_family = htons(AF_INET);	/*Internet family */
+ #endif
  	FSSktArray[currFS].sin_port = htons(7000);	/*FileServer port */
  	he = hostutil_GetHostByName(curr_item-&gt;data);
  	if (he == NULL) {
</pre></body></html>