freelance-misc-20040807
authorJeffrey Altman <jaltman@mit.edu>
Sat, 7 Aug 2004 06:44:05 +0000 (06:44 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 7 Aug 2004 06:44:05 +0000 (06:44 +0000)
Added a change monitor to the HKLM\SOFTWARE\OpenAFS\Client\Freelance
key.  When a change occurs mark the root.afs data as invalid and
for it to be reloaded on the next access.  This allows administrators
to modify the mount point list without restarting the service.

The freelance client used to provide a fake modification time for
the root.afs volume data and its mount points of 7/09/2001 14:24 EDT.
Added code to extract the last modification time of the Freelance
registry key and use that instead.  The time now represents the
most recent mount point change.

smb3.c: Fake the timestamp if we can't stat the file.  A zero FILETIME
value causes problems.

src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_freelance.c
src/WINNT/afsd/cm_freelance.h
src/WINNT/afsd/cm_scache.c
src/WINNT/afsd/cm_server.c
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb.h
src/WINNT/afsd/smb3.c

index f65e9bb..5128769 100644 (file)
@@ -1186,8 +1186,8 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up,
                afsStatus.ParentVnode = 0x1;
                afsStatus.ParentUnique = 0x1;
                afsStatus.ResidencyMask = 0;
-               afsStatus.ClientModTime = 0x3b49f6e2;
-               afsStatus.ServerModTime = 0x3b49f6e2;
+               afsStatus.ClientModTime = FakeFreelanceModTime;
+               afsStatus.ServerModTime = FakeFreelanceModTime;
                afsStatus.Group = 0;
                afsStatus.SyncCounter = 0;
                afsStatus.dataVersionHigh = 0;
index 0438f5c..ddbd0e6 100644 (file)
@@ -30,12 +30,59 @@ cm_localMountPoint_t* cm_localMountPoints;
 osi_mutex_t cm_Freelance_Lock;
 int cm_localMountPointChangeFlag = 0;
 int cm_freelanceEnabled = 0;
+afs_uint32    FakeFreelanceModTime = 0x3b49f6e2;
 
 void cm_InitFakeRootDir();
 
+#if !defined(DJGPP)
+void cm_FreelanceChangeNotifier(void * parmp) {
+    HANDLE hFreelanceChangeEvent = 0;
+    HKEY   hkFreelance = 0;
+
+    if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
+                      "SOFTWARE\\OpenAFS\\Client\\Freelance",
+                      0,
+                      KEY_NOTIFY,
+                      &hkFreelance) == ERROR_SUCCESS) {
+
+        hFreelanceChangeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        if (hFreelanceChangeEvent == NULL) {
+            RegCloseKey(hkFreelance);
+            return;
+        }
+    }
+
+    while ( TRUE ) {
+    /* check hFreelanceChangeEvent to see if it is set. 
+     * if so, call cm_noteLocalMountPointChange()
+     */
+        if (RegNotifyChangeKeyValue( hkFreelance,   /* hKey */
+                                     FALSE,         /* bWatchSubtree */
+                                     REG_NOTIFY_CHANGE_LAST_SET, /* dwNotifyFilter */
+                                     hFreelanceChangeEvent, /* hEvent */
+                                     TRUE          /* fAsynchronous */
+                                     ) != ERROR_SUCCESS) {
+            RegCloseKey(hkFreelance);
+            CloseHandle(hFreelanceChangeEvent);
+            return;
+        }
+
+        if (WaitForSingleObject(hFreelanceChangeEvent, INFINITE) == WAIT_OBJECT_0)
+        {
+            cm_noteLocalMountPointChange();
+        }
+    }
+}
+#endif
+
 void cm_InitFreelance() {
+#if !defined(DJGPP)
+    thread_t phandle;
+    int lpid;
+#endif
+
        lock_InitializeMutex(&cm_Freelance_Lock, "Freelance Lock");
-  
+
        // yj: first we make a call to cm_initLocalMountPoints
        // to read all the local mount points from an ini file
        cm_InitLocalMountPoints();
@@ -43,8 +90,15 @@ void cm_InitFreelance() {
        // then we make a call to InitFakeRootDir to create
        // a fake root directory based on the local mount points
        cm_InitFakeRootDir();
-
        // --- end of yj code
+
+#if !defined(DJGPP)
+    /* Start the registry monitor */
+    phandle = thrd_Create(NULL, 65536, (ThreadFunc) cm_FreelanceChangeNotifier,
+                          NULL, 0, &lpid, "cm_FreelanceChangeNotifier");
+       osi_assert(phandle != NULL);
+       thrd_CloseHandle(phandle);
+#endif
 }
 
 /* yj: Initialization of the fake root directory */
@@ -232,30 +286,29 @@ int cm_FakeRootFid(cm_fid_t *fidp)
       return 0;
 }
   
-int cm_getLocalMountPointChange() {
-  return cm_localMountPointChangeFlag;
+/* called directly from ioctl */
+/* called while not holding freelance lock */
+int cm_noteLocalMountPointChange() {
+    lock_ObtainMutex(&cm_Freelance_Lock);
+    cm_fakeDirVersion++;
+    cm_localMountPointChangeFlag = 1;
+    lock_ReleaseMutex(&cm_Freelance_Lock);
+    return 1;
 }
 
-int cm_clearLocalMountPointChange() {
-  cm_localMountPointChangeFlag = 0;
-  return 0;
+int cm_getLocalMountPointChange() {
+    return cm_localMountPointChangeFlag;
 }
 
-/* called directly from ioctl */
-/* called while not holding freelance lock */
-int cm_noteLocalMountPointChange() {
-  lock_ObtainMutex(&cm_Freelance_Lock);
-  cm_fakeDirVersion++;
-  cm_localMountPointChangeFlag = 1;
-  lock_ReleaseMutex(&cm_Freelance_Lock);
-  return 1;
+int cm_clearLocalMountPointChange() {
+    cm_localMountPointChangeFlag = 0;
+    return 0;
 }
 
 int cm_reInitLocalMountPoints() {
        cm_fid_t aFid;
        int i, hash;
        cm_scache_t *scp, **lscpp, *tscp;
-
        
        osi_Log0(afsd_logp,"----- freelance reinitialization starts ----- ");
 
@@ -339,8 +392,8 @@ int cm_reInitLocalMountPoints() {
 /* to be called while holding freelance lock unless during init. */
 long cm_InitLocalMountPoints() {
        FILE *fp;
+    int i;
        char line[512];
-       int i;
        char* t;
        cm_localMountPoint_t* aLocalMountPoint;
        char hdir[120];
@@ -351,6 +404,8 @@ long cm_InitLocalMountPoints() {
     DWORD dwType, dwSize;
     DWORD dwMountPoints;
     DWORD dwIndex;
+    FILETIME ftLastWriteTime;
+    afs_uint32 unixTime;
 #endif
 
 #if !defined(DJGPP)
@@ -371,9 +426,11 @@ long cm_InitLocalMountPoints() {
                          NULL,  /* lpcMaxValueNameLen */
                          NULL,  /* lpcMaxValueLen */
                          NULL,  /* lpcbSecurityDescriptor */
-                         NULL   /* lpftLastWriteTime */
+                         &ftLastWriteTime /* lpftLastWriteTime */
                          );
 
+        smb_UnixTimeFromLargeSearchTime(&FakeFreelanceModTime, &ftLastWriteTime);
+
         if ( dwMountPoints == 0 ) {
             sprintf(line,"%s#%s:root.cell.\n",rootCellName,rootCellName);
             dwType = REG_SZ;
@@ -413,9 +470,10 @@ long cm_InitLocalMountPoints() {
                 t = strchr(line, '%');
             // make sure that there is a '#' or '%' separator in the line
             if (!t) {
-                afsi_log("error occurred while parsing entry in %s: no # or %% separator in line %d", AFS_FREELANCE_INI, i);
-                fprintf(stderr, "error occurred while parsing entry in afs_freelance.ini: no # or %% separator in line %d", i);
-                return -1;
+                afsi_log("error occurred while parsing entry in %s: no # or %% separator in line %d", AFS_FREELANCE_INI, dwIndex);
+                fprintf(stderr, "error occurred while parsing entry in afs_freelance.ini: no # or %% separator in line %d", dwIndex);
+                cm_noLocalMountPoints--;
+                continue;
             }
             aLocalMountPoint->namep=malloc(t-line+1);
             memcpy(aLocalMountPoint->namep, line, t-line);
@@ -437,6 +495,9 @@ long cm_InitLocalMountPoints() {
     }
 #endif
 
+    /* What follows is the old code to read freelance mount points 
+     * out of a text file modified to copy the data into the registry
+     */
        cm_GetConfigDir(hdir);
        strcat(hdir, AFS_FREELANCE_INI);
        // open the ini file for reading
@@ -462,7 +523,6 @@ long cm_InitLocalMountPoints() {
        // we successfully opened the file
        osi_Log0(afsd_logp,"opened afs_freelance.ini");
        
-
 #if !defined(DJGPP)
     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
                     "SOFTWARE\\OpenAFS\\Client\\Freelance",
@@ -584,10 +644,11 @@ long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw,
        don't add the mount point.
        allow partial matches as a means of poor man's alias. */
     /* major performance issue? */
-    osi_Log3(afsd_logp,"Freelance Add Mount request: filename=%s cellname=%s volume=%s %s",
+    osi_Log4(afsd_logp,"Freelance Add Mount request: filename=%s cellname=%s volume=%s %s",
               osi_LogSaveString(afsd_logp,filename), 
               osi_LogSaveString(afsd_logp,cellname), 
-              osi_LogSaveString(afsd_logp,volume), rw ? "rw" : "ro");
+              osi_LogSaveString(afsd_logp,volume), 
+              rw ? "rw" : "ro");
     if (cellname[0] == '.') {
         if (!cm_GetCell_Gen(&cellname[1], fullname, CM_FLAG_CREATE))
             return -1;
index ddef113..b7d90e3 100644 (file)
@@ -22,4 +22,6 @@ extern int cm_clearLocalMountPointChange();
 #define AFS_FREELANCE_INI "afs_freelance.ini"
 #define AFS_FAKE_ROOT_CELL_ID 0xFFFFFFFF
 #define AFS_FAKE_ROOT_VOL_ID  0xFFFFFFFF
+
+extern afs_uint32 FakeFreelanceModTime;
 #endif // _CM_FREELANCE_H
index 9228c6b..54d6e75 100644 (file)
@@ -316,8 +316,8 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
 
                scp->owner=0x0;
                scp->unixModeBits=0x1ff;
-               scp->clientModTime=0x3b49f6e2;
-               scp->serverModTime=0x3b49f6e2;
+               scp->clientModTime=FakeFreelanceModTime;
+               scp->serverModTime=FakeFreelanceModTime;
                scp->parentUnique = 0x1;
                scp->parentVnode=0x1;
                scp->group=0;
@@ -819,8 +819,8 @@ void cm_MergeStatus(cm_scache_t *scp, AFSFetchStatus *statusp, AFSVolSync *volp,
                statusp->ParentVnode = 0x1;
                statusp->ParentUnique = 0x1;
                statusp->ResidencyMask = 0;
-               statusp->ClientModTime = 0x3b49f6e2;
-               statusp->ServerModTime = 0x3b49f6e2;
+               statusp->ClientModTime = FakeFreelanceModTime;
+               statusp->ServerModTime = FakeFreelanceModTime;
                statusp->Group = 0;
                statusp->SyncCounter = 0;
                statusp->dataVersionHigh = 0;
index e5df624..d92e0a1 100644 (file)
@@ -432,19 +432,19 @@ void cm_FreeServer(cm_server_t* server)
 
 void cm_FreeServerList(cm_serverRef_t** list)
 {
-    cm_serverRef_t  *current = *list;
+    cm_serverRef_t  **current = list;
     cm_serverRef_t  *next = 0;
 
     lock_ObtainWrite(&cm_serverLock);
 
-    while (current)
+    while (*current)
     {
-        next = current->next;
-        if (--current->refCount == 0) {
-            cm_FreeServer(current->server);
-            free(current);
+        next = (*current)->next;
+        if (--((*current)->refCount) == 0) {
+            cm_FreeServer((*current)->server);
+            free(*current);
         }
-        current = next;
+        *current = next;
     }
   
     lock_ReleaseWrite(&cm_serverLock);
index 98404e9..5fb9e5b 100644 (file)
@@ -156,7 +156,7 @@ extern HANDLE WaitToTerminate;
  * Time in Unix format of midnight, 1/1/1970 local time.
  * When added to dosUTime, gives Unix (AFS) time.
  */
-long smb_localZero;
+long smb_localZero = 0;
 
 /* Time difference for converting to kludge-GMT */
 int smb_NowTZ;
@@ -432,7 +432,7 @@ static int ExtractBits(WORD bits, short start, short len)
 }
 
 #ifndef DJGPP
-void ShowUnixTime(char *FuncName, long unixTime)
+void ShowUnixTime(char *FuncName, afs_uint32 unixTime)
 {
        FILETIME ft;
        WORD wDate, wTime;
@@ -583,7 +583,7 @@ smb_CalculateNowTZ()
 }
 
 #ifndef DJGPP
-void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, long unixTime)
+void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, afs_uint32 unixTime)
 {
        struct tm *ltp;
        SYSTEMTIME stm;
@@ -623,7 +623,7 @@ void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, long unixTime)
        SystemTimeToFileTime(&stm, largeTimep);
 }
 #else /* DJGPP */
-void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, long unixTime)
+void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, afs_uint32 unixTime)
 {
        /* unixTime: seconds since 1/1/1970 00:00:00 GMT */
        /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 ??? */
@@ -645,7 +645,7 @@ void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, long unixTime)
 #endif /* !DJGPP */
 
 #ifndef DJGPP
-void smb_UnixTimeFromLargeSearchTime(long *unixTimep, FILETIME *largeTimep)
+void smb_UnixTimeFromLargeSearchTime(afs_uint32 *unixTimep, FILETIME *largeTimep)
 {
        SYSTEMTIME stm;
        struct tm lt;
@@ -668,7 +668,7 @@ void smb_UnixTimeFromLargeSearchTime(long *unixTimep, FILETIME *largeTimep)
        _timezone = save_timezone;
 }
 #else /* DJGPP */
-void smb_UnixTimeFromLargeSearchTime(long *unixTimep, FILETIME *largeTimep)
+void smb_UnixTimeFromLargeSearchTime(afs_uint32 *unixTimep, FILETIME *largeTimep)
 {
        /* unixTime: seconds since 1/1/1970 00:00:00 GMT */
        /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 GMT? */
@@ -689,7 +689,7 @@ void smb_UnixTimeFromLargeSearchTime(long *unixTimep, FILETIME *largeTimep)
 }
 #endif /* !DJGPP */
 
-void smb_SearchTimeFromUnixTime(long *dosTimep, long unixTime)
+void smb_SearchTimeFromUnixTime(long *dosTimep, afs_uint32 unixTime)
 {
        struct tm *ltp;
        int dosDate;
@@ -714,7 +714,7 @@ void smb_SearchTimeFromUnixTime(long *dosTimep, long unixTime)
        *dosTimep = (dosDate<<16) | dosTime;
 }      
 
-void smb_UnixTimeFromSearchTime(long *unixTimep, long searchTime)
+void smb_UnixTimeFromSearchTime(afs_uint32 *unixTimep, long searchTime)
 {
        unsigned short dosDate;
        unsigned short dosTime;
@@ -734,12 +734,12 @@ void smb_UnixTimeFromSearchTime(long *unixTimep, long searchTime)
        *unixTimep = mktime(&localTm);
 }
 
-void smb_DosUTimeFromUnixTime(long *dosUTimep, long unixTime)
+void smb_DosUTimeFromUnixTime(afs_uint32 *dosUTimep, afs_uint32 unixTime)
 {
        *dosUTimep = unixTime - smb_localZero;
 }
 
-void smb_UnixTimeFromDosUTime(long *unixTimep, long dosTime)
+void smb_UnixTimeFromDosUTime(afs_uint32 *unixTimep, afs_uint32 dosTime)
 {
 #ifndef DJGPP
        *unixTimep = dosTime + smb_localZero;
@@ -2813,13 +2813,14 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 
 void smb_Daemon(void *parmp)
 {
-       int count = 0;
+       afs_uint32 count = 0;
 
        while(1) {
                count++;
                thrd_Sleep(10000);
-               if ((count % 360) == 0) {       /* every hour */
+               if ((count % 72) == 0)  {       /* every five minutes */
             struct tm myTime;
+            long old_localZero = smb_localZero;
                 
             /* Initialize smb_localZero */
             myTime.tm_isdst = -1;              /* compute whether on DST or not */
@@ -2832,6 +2833,11 @@ void smb_Daemon(void *parmp)
             smb_localZero = mktime(&myTime);
 
             smb_CalculateNowTZ();
+
+#ifdef AFS_FREELANCE
+            if ( smb_localZero != old_localZero )
+                cm_noteLocalMountPointChange();
+#endif
         }
                /* XXX GC dir search entries */
        }
@@ -7113,8 +7119,8 @@ void smb_NetbiosInit()
         code = Netbios(ncbp, dos_ncb);
 #endif /* !DJGPP */
           
-        osi_Log3(smb_logp, "Netbios NCBADDNAME lana=%d code=%d retcode=%d complete=%d",
-                 lana, code, ncbp->ncb_retcode,ncbp->ncb_cmd_cplt);
+        osi_Log4(smb_logp, "Netbios NCBADDNAME lana=%d code=%d retcode=%d complete=%d",
+                 lana, code, ncbp->ncb_retcode, ncbp->ncb_cmd_cplt);
         {
             char name[NCBNAMSZ+1];
             name[NCBNAMSZ]=0;
@@ -7247,6 +7253,11 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
        /* Initialize kludge-GMT */
        smb_CalculateNowTZ();
 
+#ifdef AFS_FREELANCE_CLIENT
+    /* Make sure the root.afs volume has the correct time */
+    cm_noteLocalMountPointChange();
+#endif
+
        /* initialize the remote debugging log */
        smb_logp = logp;
         
index 904b146..0f72f37 100644 (file)
@@ -378,17 +378,17 @@ extern void smb_Init(osi_log_t *logp, char *smbNamep, int useV3, int LANadapt,
 #endif
   );
 
-extern void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, long unixTime);
+extern void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, afs_uint32 unixTime);
 
-extern void smb_UnixTimeFromLargeSearchTime(long *unixTimep, FILETIME *largeTimep);
+extern void smb_UnixTimeFromLargeSearchTime(afs_uint32 *unixTimep, FILETIME *largeTimep);
 
-extern void smb_SearchTimeFromUnixTime(long *dosTimep, long unixTime);
+extern void smb_SearchTimeFromUnixTime(long *dosTimep, afs_uint32 unixTime);
 
-extern void smb_UnixTimeFromSearchTime(long *unixTimep, long searchTime);
+extern void smb_UnixTimeFromSearchTime(afs_uint32 *unixTimep, long searchTime);
 
-extern void smb_DosUTimeFromUnixTime(long *dosUTimep, long unixTime);
+extern void smb_DosUTimeFromUnixTime(afs_uint32 *dosUTimep, afs_uint32 unixTime);
 
-extern void smb_UnixTimeFromDosUTime(long *unixTimep, long dosUTime);
+extern void smb_UnixTimeFromDosUTime(afs_uint32 *unixTimep, afs_uint32 dosUTime);
 
 extern smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana);
 
index 1c0bd26..31450bc 100644 (file)
@@ -2992,6 +2992,65 @@ long smb_ApplyV3DirListPatches(cm_scache_t *dscp,
                if (code) { 
                        lock_ReleaseMutex(&scp->mx);
                        cm_ReleaseSCache(scp);
+
+            dptr = patchp->dptr;
+
+            /* Plug in fake timestamps. A time stamp of 0 causes 'invalid parameter'
+               errors in the client. */
+            if (infoLevel >= 0x101) {
+                /* 1969-12-31 23:59:59 +00 */
+                ft.dwHighDateTime = 0x19DB200;
+                ft.dwLowDateTime = 0x5BB78980;
+
+                           /* copy to Creation Time */
+                           *((FILETIME *)dptr) = ft;
+                           dptr += 8;
+
+                           /* copy to Last Access Time */
+                           *((FILETIME *)dptr) = ft;
+                           dptr += 8;
+
+                           /* copy to Last Write Time */
+                           *((FILETIME *)dptr) = ft;
+                           dptr += 8;
+
+                           /* copy to Change Time */
+                           *((FILETIME *)dptr) = ft;
+
+            } else {
+                /* 1969-12-31 23:59:58 +00*/
+                dosTime = 0xEBBFBF7D;
+
+                           /* and copy out date */
+                           shortTemp = (dosTime>>16) & 0xffff;
+                           *((u_short *)dptr) = shortTemp;
+                           dptr += 2;
+
+                           /* copy out creation time */
+                           shortTemp = dosTime & 0xffff;
+                           *((u_short *)dptr) = shortTemp;
+                           dptr += 2;
+
+                           /* and copy out date */
+                           shortTemp = (dosTime>>16) & 0xffff;
+                           *((u_short *)dptr) = shortTemp;
+                           dptr += 2;
+                       
+                           /* copy out access time */
+                           shortTemp = dosTime & 0xffff;
+                           *((u_short *)dptr) = shortTemp;
+                           dptr += 2;
+
+                           /* and copy out date */
+                           shortTemp = (dosTime>>16) & 0xffff;
+                           *((u_short *)dptr) = shortTemp;
+                           dptr += 2;
+                       
+                           /* copy out mod time */
+                           shortTemp = dosTime & 0xffff;
+                           *((u_short *)dptr) = shortTemp;
+                           dptr += 2;
+            }
                        continue;
         }