Windows: Freelance Import CellServDB
authorJeffrey Altman <jaltman@your-file-system.com>
Thu, 3 Jun 2010 15:59:45 +0000 (11:59 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Sat, 5 Jun 2010 18:31:08 +0000 (11:31 -0700)
Add a new registry option that permits automatic generation of
Freelance mountpoints for every cell listed in the CellServDB info
(file and registry).  "FreelanceImportCellServDB".  This functionality
is only triggered when the afsd_service is started.   The operation
is performed in the background by the daemon thread after the firewall
configuration is set.

LICENSE MIT

Change-Id: Ic6cc0738f8c185d77f9cf69d4997b8044522e50e
Reviewed-on: http://gerrit.openafs.org/2079
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>

src/WINNT/afsd/afsd.h
src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_config.c
src/WINNT/afsd/cm_config.h
src/WINNT/afsd/cm_daemon.c
src/WINNT/afsd/cm_freelance.c
src/WINNT/afsd/cm_freelance.h

index 17835ae..bed8269 100644 (file)
@@ -110,7 +110,6 @@ extern int cm_fakeGettingCallback;                  // 1 if currently updating the fake root.af
 #endif /* AFS_FREELANCE_CLIENT */
 
 extern int cm_dnsEnabled;
-extern int cm_freelanceEnabled;
 extern int cm_readonlyVolumeVersioning;
 
 extern long rx_mtu;
index 5b79c6d..854624a 100644 (file)
@@ -970,13 +970,14 @@ afsd_InitCM(char **reasonP)
     dummyLen = sizeof(cm_freelanceEnabled);
     code = RegQueryValueEx(parmKey, "FreelanceClient", NULL, NULL,
                             (BYTE *) &cm_freelanceEnabled, &dummyLen);
-    if (code == ERROR_SUCCESS) {
-        afsi_log("Freelance client feature %s activated",
-                  cm_freelanceEnabled ? "is" : "is not");
-    }       
-    else {
-        cm_freelanceEnabled = 1;  /* default on */
-    }
+    afsi_log("Freelance client feature %s activated",
+              cm_freelanceEnabled ? "is" : "is not");
+
+    dummyLen = sizeof(cm_freelanceImportCellServDB);
+    code = RegQueryValueEx(parmKey, "FreelanceImportCellServDB", NULL, NULL,
+                            (BYTE *) &cm_freelanceImportCellServDB, &dummyLen);
+    afsi_log("Freelance client %s import CellServDB",
+              cm_freelanceImportCellServDB ? "does" : "does not");
 #endif /* AFS_FREELANCE_CLIENT */
 
     dummyLen = sizeof(smb_UseUnicode);
index 7c23629..de17596 100644 (file)
@@ -377,6 +377,69 @@ long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
     return (foundCell) ? 0 : -11;
 }
 
+long
+cm_EnumerateCellFile(afs_uint32 client, cm_enumCellProc_t *procp, void *rockp)
+{
+    char wdir[MAX_PATH]="";
+    FILE *tfilep = NULL;
+    char *tp;
+    char lineBuffer[257];
+
+    if (!procp)
+        return 0;
+
+    cm_GetCellServDB(wdir, sizeof(wdir));
+    if (*wdir)
+        tfilep = fopen(wdir, "r");
+
+    if (!tfilep)
+        return -2;
+
+#ifdef CELLSERV_DEBUG
+    osi_Log2(afsd_logp,"cm_enumfile fopen handle[%p], wdir[%s]", tfilep,
+            osi_LogSaveString(afsd_logp,wdir));
+#endif
+    while (1) {
+        tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
+        if (tp == NULL && feof(tfilep)) {
+            /* hit EOF */
+            fclose(tfilep);
+            return (0);
+        }
+
+        /* turn trailing cr or lf into null */
+        tp = strrchr(lineBuffer, '\r');
+        if (tp) *tp = 0;
+        tp = strrchr(lineBuffer, '\n');
+        if (tp) *tp = 0;
+
+       /* skip blank lines */
+        if (lineBuffer[0] == 0)
+            continue;
+
+        /*
+         * The format is:
+         *   >[cell] [linked-cell] #[Description]
+         * where linked-cell and Description are optional
+         * but we are only going to use the initial cell name
+         */
+        if (lineBuffer[0] == '>') {
+            /*
+             * terminate the cellname at the first white space
+             * leaving 'tp' pointing to the next string if any
+             */
+            for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
+            if (tp)
+                *tp = '\0';
+
+            /* Now process the cell */
+            (*procp)(rockp, &lineBuffer[1]);
+        }
+    }          /* while loop processing all lines */
+
+    return 0;
+}
+
 /*
  * The CellServDB registry schema is as follows:
  *
index a6b0a57..2882907 100644 (file)
@@ -28,7 +28,7 @@ typedef FILE cm_configFile_t;
 
 typedef long (cm_configProc_t)(void *rockp, struct sockaddr_in *addrp, char *namep, unsigned short);
 
-typedef long (cm_enumCellRegistryProc_t)(void *rockp, char *cellNamep);
+typedef long (cm_enumCellProc_t)(void *rockp, char *cellNamep);
 
 extern long cm_GetRootCellName(char *namep);
 
@@ -39,13 +39,17 @@ extern long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
                                 char *linkedNamep,
                                 cm_configProc_t *procp, void *rockp);
 
+extern long cm_EnumerateCellFile(afs_uint32 client,
+                                 cm_enumCellProc_t *procp,
+                                 void *rockp);
+
 extern long cm_SearchCellRegistry(afs_uint32 client, 
                                   char *cellNamep, char *newCellNamep,
                                   char *linkedNamep,
                                   cm_configProc_t *procp, void *rockp);
 
 extern long cm_EnumerateCellRegistry(afs_uint32 client, 
-                                     cm_enumCellRegistryProc_t *procp, 
+                                     cm_enumCellProc_t *procp,
                                      void *rockp);
 
 extern long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
index 4c45cc3..fac1be3 100644 (file)
@@ -386,6 +386,9 @@ void cm_Daemon(long parm)
        afsi_log("No Windows Firewall detected");
     }
 
+    if (cm_freelanceEnabled && cm_freelanceImportCellServDB)
+        cm_FreelanceImportCellServDB();
+
     /* ping all file servers, up or down, with unauthenticated connection,
      * to find out whether we have all our callbacks from the server still.
      * Also, ping down VLDBs.
index 115daaa..fb0be30 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <malloc.h>
 #include <string.h>
+#include <cm_nls.h>
 
 #include <WINNT/afsreg.h>
 #include "afsd.h"
 
 #ifdef AFS_FREELANCE_CLIENT
 #include "cm_freelance.h"
-#include "stdio.h"
+#include <stdio.h>
+#define STRSAFE_NO_DEPRECATE
+#include <strsafe.h>
 
 extern void afsi_log(char *pattern, ...);
 
-static int cm_noLocalMountPoints = 0;
+static unsigned int cm_noLocalMountPoints = 0;
 char * cm_FakeRootDir = NULL;
 int cm_fakeDirSize = 0;
 int cm_fakeDirCallback=0;
@@ -27,6 +30,7 @@ static cm_localMountPoint_t* cm_localMountPoints;
 osi_mutex_t cm_Freelance_Lock;
 static int cm_localMountPointChangeFlag = 0;
 int cm_freelanceEnabled = 1;
+int cm_freelanceImportCellServDB = 0;
 time_t FakeFreelanceModTime = 0x3b49f6e2;
 
 static int freelance_ShutdownFlag = 0;
@@ -133,7 +137,29 @@ cm_FreelanceShutdown(void)
         thrd_SetEvent(hFreelanceChangeEvent); 
     if (hFreelanceSymlinkChangeEvent != 0)           
         thrd_SetEvent(hFreelanceSymlinkChangeEvent); 
-}                                             
+}
+
+static long
+cm_FreelanceAddCSDBMountPoints(void *rockp, char *cellNamep)
+{
+    char szCellName[CELL_MAXNAMELEN+1] = ".";
+
+    cm_FsStrCpy( &szCellName[1], CELL_MAXNAMELEN, cellNamep);
+    /* create readonly mount point */
+    cm_FreelanceAddMount( cellNamep, cellNamep, "root.cell", 0, NULL);
+
+    /* create read/write mount point */
+    cm_FreelanceAddMount( szCellName, szCellName, "root.cell", 1, NULL);
+
+    return 0;
+}
+
+void
+cm_FreelanceImportCellServDB(void)
+{
+    cm_EnumerateCellRegistry( TRUE, cm_FreelanceAddCSDBMountPoints, NULL);
+    cm_EnumerateCellFile( TRUE, cm_FreelanceAddCSDBMountPoints, NULL);
+}
 
 void cm_InitFreelance() {
     thread_t phandle;
@@ -142,6 +168,7 @@ void cm_InitFreelance() {
     lock_InitializeMutex(&cm_Freelance_Lock, "Freelance Lock", LOCK_HIERARCHY_FREELANCE_GLOBAL);
 
     lock_ObtainMutex(&cm_Freelance_Lock);
+
     // yj: first we make a call to cm_initLocalMountPoints
     // to read all the local mount points from the registry
     cm_InitLocalMountPoints();
@@ -194,7 +221,7 @@ void cm_InitFakeRootDir() {
     int curChunk = 13; // chunks 0 - 12 are used for header stuff
                         // of the first page in the directory
     int curPage = 0;
-    int curDirEntry = 0;
+    unsigned int curDirEntry = 0;
     int curDirEntryInPage = 0;
     int sizeOfCurEntry;
     int dirSize;
@@ -379,7 +406,7 @@ int cm_clearLocalMountPointChange() {
 
 int cm_reInitLocalMountPoints() {
     cm_fid_t aFid;
-    int i, hash;
+    unsigned int i, hash;
     cm_scache_t *scp, **lscpp, *tscp;
        
     osi_Log0(afsd_logp,"----- freelance reinitialization starts ----- ");
@@ -462,7 +489,7 @@ int cm_reInitLocalMountPoints() {
 /* to be called while holding freelance lock. */
 long cm_InitLocalMountPoints() {
     FILE *fp;
-    int i;
+    unsigned int i;
     char line[512];
     char*t, *t2;
     cm_localMountPoint_t* aLocalMountPoint;
@@ -988,6 +1015,12 @@ long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw,
     if ( filename[0] == '\0' || cellname[0] == '\0' || volume[0] == '\0' )
         return CM_ERROR_INVAL;
 
+    if ( cm_FreelanceMountPointExists(filename, 0) ||
+         cm_FreelanceSymlinkExists(filename, 0) ) {
+        code = CM_ERROR_EXISTS;
+        goto done;
+    }
+
     if (cellname[0] == '.') {
         if (!cm_GetCell_Gen(&cellname[1], fullname, CM_FLAG_CREATE))
             return CM_ERROR_INVAL;
@@ -996,12 +1029,6 @@ long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw,
             return CM_ERROR_INVAL;
     }
 
-    if ( cm_FreelanceMountPointExists(filename, 0) ||
-         cm_FreelanceSymlinkExists(filename, 0) ) {
-        code = CM_ERROR_EXISTS;
-        goto done;
-    }
-    
     osi_Log1(afsd_logp,"Freelance Adding Mount for Cell: %s", 
               osi_LogSaveString(afsd_logp,cellname));
 
@@ -1224,7 +1251,7 @@ long cm_FreelanceRemoveMount(char *toremove)
 long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
 {
     char line[512];
-    char fullname[CELL_MAXNAMELEN];
+    char fullname[CELL_MAXNAMELEN] = "";
     int alias = 0;
     HKEY hkFreelanceSymlinks = 0;
     DWORD dwType, dwSize;
@@ -1247,7 +1274,12 @@ long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
     if ( filename[strlen(filename)-1] == '.')
         return CM_ERROR_INVAL;
 
-    fullname[0] = '\0';
+    if ( cm_FreelanceMountPointExists(filename, 0) ||
+         cm_FreelanceSymlinkExists(filename, 0) ) {
+        code = CM_ERROR_EXISTS;
+        goto done;
+    }
+
     if (filename[0] == '.') {
         cm_GetCell_Gen(&filename[1], fullname, CM_FLAG_CREATE);
         if (cm_stricmp_utf8(&filename[1],fullname) == 0) {
@@ -1262,12 +1294,6 @@ long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
         }
     }
 
-    if ( cm_FreelanceMountPointExists(filename, 0) ||
-         cm_FreelanceSymlinkExists(filename, 0) ) {
-        code = CM_ERROR_EXISTS;
-        goto done;
-    }
-
     lock_ObtainMutex(&cm_Freelance_Lock);
 
     if (RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
index 9a98064..6b92f4c 100644 (file)
@@ -23,6 +23,7 @@ extern long cm_FreelanceMountPointExists(char * filename, int prefix_ok);
 extern long cm_FreelanceSymlinkExists(char * filename, int prefix_ok);
 extern long cm_FreelanceFetchMountPointString(cm_scache_t *scp);
 extern long cm_FreelanceFetchFileType(cm_scache_t *scp);
+extern void cm_FreelanceImportCellServDB(void);
 
 extern int cm_clearLocalMountPointChange();
 extern int cm_FakeRootFid(cm_fid_t *fidp);
@@ -32,4 +33,6 @@ extern int cm_FakeRootFid(cm_fid_t *fidp);
 #define AFS_FAKE_ROOT_VOL_ID  0xFFFFFFFF
 
 extern time_t FakeFreelanceModTime;
+extern int cm_freelanceEnabled;
+extern int cm_freelanceImportCellServDB;
 #endif // _CM_FREELANCE_H