]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
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 f65e9bb9aadbf2ff90e45cf60c49bb5b67b55bea..512876930c788f198fce662fc7d16e892c7fe6f5 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 0438f5c6be8c9349cc2121068c43d718ae7c6ded..ddbd0e6a66ae384586dd59cbcbbbd6149825da35 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 ddef113d1ba5a468c689b738340f7be190f0ceb9..b7d90e3e7ea66061043b2e943df1d7623f3f04b2 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 9228c6b952e92407166b9392b854ba2f3c070794..54d6e75a7928aafb3b555c752966531d68aed18b 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 e5df624a0539baed3007924072f3f090e734e2be..d92e0a167b7fd0f959561cc1d9d6878e539e294a 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 98404e9492296c31f0cd30e7f7e38df21ebc0e77..5fb9e5ba8a7d935f9578453e9b0fc0ae7e1add73 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 904b14613a6838b9fdbf11393d38fd3ea26d7842..0f72f37c265b984cadaca0d4fca5d214c0366eb0 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 1c0bd262af46cb6c6fb4862fd275dfd0e25e1558..31450bc263f4718de589b9f5633d72eab96d941f 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;
         }