move-up-cell-initialization-in-cachemgr-20030323
[openafs.git] / src / afsd / afsd.c
index 5d4fb28..46296c8 100644 (file)
@@ -154,10 +154,14 @@ void set_staticaddrs(void);
 #if AFS_HAVE_STATVFS
 #include <sys/statvfs.h>
 #else
+#if defined(AFS_SUN_ENV)
+#include <sys/vfs.h>
+#else
 #if !defined(AFS_OSF_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
 #include <sys/statfs.h>
 #endif
 #endif
+#endif
 
 #undef VIRTUE
 #undef VICE
@@ -166,6 +170,7 @@ void set_staticaddrs(void);
 #define        AFSLOGFILE      "AFSLog"
 #define        DCACHEFILE      "CacheItems"
 #define        VOLINFOFILE     "VolumeItems"
+#define CELLINFOFILE   "CellItems"
 
 #define MAXIPADDRS 1024
 
@@ -207,6 +212,7 @@ char cacheBaseDir[1024];            /*Where the workstation AFS cache lives*/
 char confDir[1024];                    /*Where the workstation AFS configuration lives*/
 char fullpn_DCacheFile[1024];          /*Full pathname of DCACHEFILE*/
 char fullpn_VolInfoFile[1024];         /*Full pathname of VOLINFOFILE*/
+char fullpn_CellInfoFile[1024];                /*Full pathanem of CELLINFOFILE*/
 char fullpn_AFSLogFile[1024];          /*Full pathname of AFSLOGFILE*/
 char fullpn_CacheInfo[1024];           /*Full pathname of CACHEINFO*/
 char fullpn_VFile[1024];               /*Full pathname of data cache files*/
@@ -220,8 +226,11 @@ char cacheMountDir[1024];          /*Mount directory for AFS*/
 char rootVolume[64] = "root.afs";      /*AFS root volume name*/
 afs_int32 cacheSetTime = 1;                    /*Keep checking time to avoid drift?*/
 afs_int32 isHomeCell;                  /*Is current cell info for the home cell?*/
-afs_int32 lookingForHomeCell;          /*Are we still looking for the home cell?*/
+#ifdef AFS_XBSD_ENV
+int createAndTrunc = O_RDWR | O_CREAT | O_TRUNC; /*Create & truncate on open*/
+#else
 int createAndTrunc = O_CREAT | O_TRUNC; /*Create & truncate on open*/
+#endif
 int ownerRWmode        = 0600;                 /*Read/write OK by owner*/
 static int filesSet = 0;               /*True if number of files explicitly set*/
 static int nFilesPerDir = 2048;                /* # files per cache dir */
@@ -240,6 +249,7 @@ static int enable_process_stats = 0;        /* enable rx stats */
 static int enable_afsdb = 0;           /* enable AFSDB support */
 #endif
 static int enable_dynroot = 0;         /* enable dynroot support */
+static int enable_fakestat = 0;                /* enable fakestat support */
 #ifdef notdef
 static int inodes = 60;                        /* VERY conservative, but has to be */
 #endif
@@ -265,10 +275,11 @@ int *dir_for_V = NULL;                    /* Array: dir of each cache file.
                                         */
 AFSD_INO_T *inode_for_V;               /* Array of inodes for desired
                                         * cache files */
-int missing_DCacheFile = 1;            /*Is the DCACHEFILE missing?*/
-int missing_VolInfoFile        = 1;            /*Is the VOLINFOFILE missing?*/
-int afsd_rmtsys = 0;                           /* Default: don't support rmtsys */
-struct afs_cacheParams cparams;          /* params passed to cache manager */
+int missing_DCacheFile  = 1;           /*Is the DCACHEFILE missing?*/
+int missing_VolInfoFile  = 1;          /*Is the VOLINFOFILE missing?*/
+int missing_CellInfoFile = 1;          /*Is the CELLINFOFILE missing?*/
+int afsd_rmtsys = 0;                   /* Default: don't support rmtsys */
+struct afs_cacheParams cparams;         /* params passed to cache manager */
 
 static int HandleMTab();
 
@@ -341,8 +352,6 @@ int ParseCacheInfoFile()
            printf("\t%d out of 3 fields successfully parsed.\n",
                   parseResult);
 
-       printf("\tcacheMountDir: '%s'\n\tcacheBaseDir: '%s'\n\tcacheBlocks: %d\n",
-              cacheMountDir, cacheBaseDir, cacheBlocks);
        return(1);
     }
 
@@ -623,6 +632,16 @@ int CreateCacheFile(fname, statp)
     return(0);
 }
 
+static void CreateFileIfMissing(char *fullpn, int missing)
+{
+    if (missing) {
+       if (afsd_verbose)
+           printf("CreateFileIfMissing: Creating '%s'\n", fullpn);
+       if (CreateCacheFile(fullpn, NULL))
+           printf("CreateFileIfMissing: Can't create '%s'\n", fullpn);
+    }
+}
+
 /*-----------------------------------------------------------------------------
   * SweepAFSCache
   *
@@ -799,6 +818,12 @@ static int doSweepAFSCache(vFilesFound,directory,dirNum,maxDir)
             */
            missing_VolInfoFile = 0;
        }
+       else if (dirNum < 0 && strcmp(currp->d_name, CELLINFOFILE) == 0) {
+           /*
+            * Found the file holding the cell info.
+            */
+           missing_CellInfoFile = 0;
+       }
        else  if ((strcmp(currp->d_name,          ".") == 0) ||
                  (strcmp(currp->d_name,         "..") == 0) ||
 #ifdef AFS_DECOSF_ENV
@@ -807,6 +832,10 @@ static int doSweepAFSCache(vFilesFound,directory,dirNum,maxDir)
                  (strcmp(currp->d_name,         "quota.user") == 0) ||
                  (strcmp(currp->d_name,         "quota.group") == 0) ||
 #endif
+#ifdef AFS_LINUX22_ENV
+                 /* this is the ext3 journal file */
+                 (strcmp(currp->d_name,         ".journal") == 0) ||
+#endif
                  (strcmp(currp->d_name, "lost+found") == 0)) {
            /*
             * Don't do anything - this file is legit, and is to be left alone.
@@ -835,25 +864,12 @@ static int doSweepAFSCache(vFilesFound,directory,dirNum,maxDir)
 
     if (dirNum < 0) {
 
-        /*
+       /*
         * Create all the cache files that are missing.
         */
-        if (missing_DCacheFile) {
-           if (afsd_verbose)
-               printf("%s: Creating '%s'\n",
-                      rn, fullpn_DCacheFile);
-           if (CreateCacheFile(fullpn_DCacheFile, NULL))
-               printf("%s: Can't create '%s'\n",
-                      rn, fullpn_DCacheFile);
-       }
-       if (missing_VolInfoFile) {
-           if (afsd_verbose)
-               printf("%s: Creating '%s'\n",
-                      rn, fullpn_VolInfoFile);
-           if (CreateCacheFile(fullpn_VolInfoFile, NULL))
-               printf("%s: Can't create '%s'\n",
-                      rn, fullpn_VolInfoFile);
-       }
+       CreateFileIfMissing(fullpn_DCacheFile, missing_DCacheFile);
+       CreateFileIfMissing(fullpn_VolInfoFile, missing_VolInfoFile);
+       CreateFileIfMissing(fullpn_CellInfoFile, missing_CellInfoFile);
 
        /* ADJUST CACHE FILES */
 
@@ -1028,19 +1044,14 @@ register struct afsconf_cell *aci;
 char *arock;
 struct afsconf_dir *adir; {
     register int isHomeCell;
-    register int i;
-    afs_int32 cellFlags;
+    register int i, code;
+    afs_int32 cellFlags = 0;
     afs_int32 hosts[MAXHOSTSPERCELL];
     
     /* figure out if this is the home cell */
     isHomeCell = (strcmp(aci->name, LclCellName) == 0);
-    if (isHomeCell) {
-       lookingForHomeCell = 0;
-       cellFlags = 1;      /* home cell, suid is ok */
-    }
-    else {
+    if (!isHomeCell)
        cellFlags = 2;      /* not home, suid is forbidden */
-    }
     
     /* build address list */
     for(i=0;i<MAXHOSTSPERCELL;i++)
@@ -1050,11 +1061,13 @@ struct afsconf_dir *adir; {
                                            for upwards compatibility */
 
     /* configure one cell */
-    call_syscall(AFSOP_ADDCELL2,
+    code = call_syscall(AFSOP_ADDCELL2,
             hosts,                     /* server addresses */
             aci->name,                 /* cell name */
             cellFlags,                 /* is this the home cell? */
             aci->linkedCell);          /* Linked cell, if any */
+    if (code)
+       printf("Adding cell '%s': error %d\n", aci->name, code);
     return 0;
 }
 
@@ -1286,7 +1299,11 @@ mainproc(as, arock)
         * Cold shutdown is the default
         */
        printf("afsd: Shutting down all afs processes and afs state\n");
-       call_syscall(AFSOP_SHUTDOWN, 1);
+       code = call_syscall(AFSOP_SHUTDOWN, 1);
+       if (code) {
+           printf("afsd: AFS still mounted; Not shutting down\n");
+           exit(1);
+       }
        exit(0);
     }
     if (as->parms[21].items) {
@@ -1322,6 +1339,14 @@ mainproc(as, arock)
        /* -dynroot */
        enable_dynroot = 1;
     }
+    if (as->parms[27].items) {
+       /* -fakestat */
+       enable_fakestat = 2;
+    }
+    if (as->parms[28].items) {
+       /* -fakestat-all */
+       enable_fakestat = 1;
+    }
 
     /*
      * Pull out all the configuration info for the workstation's AFS cache and
@@ -1453,11 +1478,43 @@ mainproc(as, arock)
     /*
      * Set up all the pathnames we'll need for later.
      */
-    sprintf(fullpn_DCacheFile,  "%s/%s", cacheBaseDir, DCACHEFILE);
-    sprintf(fullpn_VolInfoFile, "%s/%s", cacheBaseDir, VOLINFOFILE);
+    sprintf(fullpn_DCacheFile,   "%s/%s", cacheBaseDir, DCACHEFILE);
+    sprintf(fullpn_VolInfoFile,  "%s/%s", cacheBaseDir, VOLINFOFILE);
+    sprintf(fullpn_CellInfoFile, "%s/%s", cacheBaseDir, CELLINFOFILE);
     sprintf(fullpn_VFile,       "%s/",  cacheBaseDir);
     vFilePtr = fullpn_VFile + strlen(fullpn_VFile);
 
+#ifdef AFS_SUN5_ENV
+    {
+       FILE *vfstab;
+       struct mnttab mnt;
+       struct stat statmnt, statci;
+
+       if ((stat(cacheBaseDir, &statci) == 0) &&
+           ((vfstab = fopen(MNTTAB, "r")) != NULL)) {
+           while (getmntent(vfstab, &mnt) == 0) {
+               if (strcmp(cacheBaseDir, mnt.mnt_mountp) != 0) {
+                   char *cp;
+                   int rdev = 0;
+
+                   if (cp = hasmntopt(&mnt, "dev="))
+                       rdev=(int)strtol(cp+strlen("dev="), (char **)NULL, 16);
+
+                   if ((rdev == 0) && (stat(mnt.mnt_mountp, &statmnt) == 0))
+                       rdev=statmnt.st_dev;
+
+                   if ((rdev == statci.st_dev) &&
+                       (hasmntopt (&mnt, "logging") != NULL)) {
+                       printf("WARNING: Mounting a multi-use partition which contains the AFS cache with the\n\"logging\" option may deadlock your system.\n\n");
+                       fflush(stdout);
+                   }
+               }
+           }
+           fclose(vfstab);
+       }
+    }
+#endif
+
 #if 0
     fputs(AFS_GOVERNMENT_MESSAGE, stdout); 
     fflush(stdout);
@@ -1553,6 +1610,83 @@ mainproc(as, arock)
     }
 #endif
 
+    code = call_syscall(AFSOP_BASIC_INIT, 1);
+    if (code)
+       printf("%s: Error %d in basic initialization.\n", rn, code);
+
+    /*
+     * Tell the kernel some basic information about the workstation's cache.
+     */
+    if (afsd_verbose)
+       printf("%s: Calling AFSOP_CACHEINIT: %d stat cache entries, %d optimum cache files, %d blocks in the cache, flags = 0x%x, dcache entries %d\n",
+              rn, cacheStatEntries, cacheFiles, cacheBlocks, cacheFlags,
+              dCacheSize);
+    memset(&cparams, '\0', sizeof(cparams));
+    cparams.cacheScaches = cacheStatEntries;
+    cparams.cacheFiles = cacheFiles;
+    cparams.cacheBlocks = cacheBlocks;
+    cparams.cacheDcaches = dCacheSize;
+    cparams.cacheVolumes = vCacheSize;
+    cparams.chunkSize = chunkSize;
+    cparams.setTimeFlag = cacheSetTime;
+    cparams.memCacheFlag = cacheFlags;
+#ifdef notdef
+    cparams.inodes       = inodes;
+#endif
+    call_syscall(AFSOP_CACHEINIT, &cparams);
+    if (afsd_CloseSynch) 
+       call_syscall(AFSOP_CLOSEWAIT);
+
+    /*
+     * Sweep the workstation AFS cache directory, remembering the inodes of
+     * valid files and deleting extraneous files.  Keep sweeping until we
+     * have the right number of data cache files or we've swept too many
+     * times.
+     *
+     * This also creates files in the cache directory like VolumeItems and
+     * CellItems, and thus must be ran before those are sent to the kernel.
+     */
+    if (afsd_verbose)
+       printf("%s: Sweeping workstation's AFS cache directory.\n",
+              rn);
+    cacheIteration = 0;
+    /* Memory-cache based system doesn't need any of this */
+    if(!(cacheFlags & AFSCALL_INIT_MEMCACHE)) {
+       do {
+           cacheIteration++;
+           if (SweepAFSCache(&vFilesFound)) {
+               printf("%s: Error on sweep %d of workstation AFS cache \
+                       directory.\n", rn, cacheIteration);
+               exit(1);
+           }
+           if (afsd_verbose)
+               printf("%s: %d out of %d data cache files found in sweep %d.\n",
+                      rn, vFilesFound, cacheFiles, cacheIteration);
+       } while ((vFilesFound < cacheFiles) &&
+                (cacheIteration < MAX_CACHE_LOOPS));
+    } else if(afsd_verbose)
+       printf("%s: Using memory cache, not swept\n", rn);
+
+    /*
+     * Pass the kernel the name of the workstation cache file holding the 
+     * dcache entries.
+     */
+    if (afsd_debug)
+       printf("%s: Calling AFSOP_CACHEINFO: dcache file is '%s'\n",
+              rn, fullpn_DCacheFile);
+    /* once again, meaningless for a memory-based cache. */
+    if(!(cacheFlags & AFSCALL_INIT_MEMCACHE))
+       call_syscall(AFSOP_CACHEINFO, fullpn_DCacheFile);
+
+    /*
+     * Pass the kernel the name of the workstation cache file holding the
+     * cell information.
+     */
+    if (afsd_debug)
+       printf("%s: Calling AFSOP_CELLINFO: cell info file is '%s'\n",
+              rn, fullpn_CellInfoFile);
+    call_syscall(AFSOP_CELLINFO, fullpn_CellInfoFile);
+
     if (enable_dynroot) {
        if (afsd_verbose)
            printf("%s: Enabling dynroot support in kernel.\n", rn);
@@ -1561,6 +1695,25 @@ mainproc(as, arock)
            printf("%s: Error enabling dynroot support.\n", rn);
     }
 
+    if (enable_fakestat) {
+       if (afsd_verbose)
+           printf("%s: Enabling fakestat support in kernel.\n", rn);
+       code = call_syscall(AFSOP_SET_FAKESTAT, enable_fakestat);
+       if (code)
+           printf("%s: Error enabling fakestat support.\n", rn);
+    }
+
+    /*
+     * Tell the kernel about each cell in the configuration.
+     */
+    afsconf_CellApply(cdir, ConfigCell, NULL);
+    afsconf_CellAliasApply(cdir, ConfigCellAlias, NULL);
+
+    /*
+     * Set the primary cell name.
+     */
+    call_syscall(AFSOP_SET_THISCELL, LclCellName);
+
     /* Initialize AFS daemon threads. */
     if (afsd_verbose)
        printf("%s: Forking AFS daemon.\n", rn);
@@ -1617,23 +1770,6 @@ mainproc(as, arock)
 #endif
 
     /*
-     * Tell the kernel about each cell in the configuration.
-     */
-    lookingForHomeCell = 1;
-
-    afsconf_CellApply(cdir, ConfigCell, (char *) 0);
-    afsconf_CellAliasApply(cdir, ConfigCellAlias, (char *) 0);
-
-    /*
-     * If we're still looking for the home cell after the whole cell configuration database
-     * has been parsed, there's something wrong.
-     */
-    if (lookingForHomeCell) {
-       printf("%s: Can't find information for home cell '%s' in cell database!\n",
-              rn, LclCellName);
-    }
-
-    /*
      * If the root volume has been explicitly set, tell the kernel.
      */
     if (rootVolSet) {
@@ -1644,67 +1780,6 @@ mainproc(as, arock)
     }
 
     /*
-     * Tell the kernel some basic information about the workstation's cache.
-     */
-    if (afsd_verbose)
-       printf("%s: Calling AFSOP_CACHEINIT: %d stat cache entries, %d optimum cache files, %d blocks in the cache, flags = 0x%x, dcache entries %d\n",
-              rn, cacheStatEntries, cacheFiles, cacheBlocks, cacheFlags,
-              dCacheSize);
-    memset(&cparams, '\0', sizeof(cparams));
-    cparams.cacheScaches = cacheStatEntries;
-    cparams.cacheFiles = cacheFiles;
-    cparams.cacheBlocks = cacheBlocks;
-    cparams.cacheDcaches = dCacheSize;
-    cparams.cacheVolumes = vCacheSize;
-    cparams.chunkSize = chunkSize;
-    cparams.setTimeFlag = cacheSetTime;
-    cparams.memCacheFlag = cacheFlags;
-#ifdef notdef
-    cparams.inodes       = inodes;
-#endif
-    call_syscall(AFSOP_CACHEINIT, &cparams);
-    if (afsd_CloseSynch) 
-      call_syscall(AFSOP_CLOSEWAIT);
-
-    /*
-     * Sweep the workstation AFS cache directory, remembering the inodes of
-     * valid files and deleting extraneous files.  Keep sweeping until we
-     * have the right number of data cache files or we've swept too many
-     * times.
-     */
-    if (afsd_verbose)
-       printf("%s: Sweeping workstation's AFS cache directory.\n",
-              rn);
-    cacheIteration = 0;
-    /* Memory-cache based system doesn't need any of this */
-    if(!(cacheFlags & AFSCALL_INIT_MEMCACHE)) {
-       do {
-           cacheIteration++;
-           if (SweepAFSCache(&vFilesFound)) {
-               printf("%s: Error on sweep %d of workstation AFS cache \
-                       directory.\n", rn, cacheIteration);
-               exit(1);
-           }
-           if (afsd_verbose)
-               printf("%s: %d out of %d data cache files found in sweep %d.\n",
-                      rn, vFilesFound, cacheFiles, cacheIteration);
-       } while ((vFilesFound < cacheFiles) &&
-                (cacheIteration < MAX_CACHE_LOOPS));
-    } else if(afsd_verbose)
-       printf("%s: Using memory cache, not swept\n", rn);
-
-    /*
-     * Pass the kernel the name of the workstation cache file holding the 
-     * dcache entries.
-     */
-    if (afsd_debug)
-       printf("%s: Calling AFSOP_CACHEINFO: dcache file is '%s'\n",
-              rn, fullpn_DCacheFile);
-    /* once again, meaningless for a memory-based cache. */
-    if(!(cacheFlags & AFSCALL_INIT_MEMCACHE))
-       call_syscall(AFSOP_CACHEINFO, fullpn_DCacheFile);
-
-    /*
      * Pass the kernel the name of the workstation cache file holding the
      * volume information.
      */
@@ -1800,7 +1875,7 @@ mainproc(as, arock)
     if (aix_vmount()) {
 #else
 #if defined(AFS_HPUX100_ENV)
-    if ((mount("",cacheMountDir,mountFlags,"afs", (char *)0, 0)) < 0) {
+    if ((mount("",cacheMountDir,mountFlags,"afs", NULL, 0)) < 0) {
 #else
 #ifdef AFS_HPUX_ENV
 #if    defined(AFS_HPUX90_ENV)
@@ -1826,7 +1901,7 @@ mainproc(as, arock)
 #endif
 #else
 #ifdef AFS_SUN5_ENV
-    if ((mount("AFS",cacheMountDir,mountFlags,"afs", (char *)0, 0)) < 0) {
+    if ((mount("AFS",cacheMountDir,mountFlags,"afs", NULL, 0)) < 0) {
 #else
 #if defined(AFS_SGI_ENV)
     mountFlags = MS_FSS;
@@ -1878,7 +1953,7 @@ int argc;
 char **argv; {
     register struct cmd_syndesc *ts;
 
-    ts = cmd_CreateSyntax((char *) 0, mainproc, (char *) 0, "start AFS");
+    ts = cmd_CreateSyntax(NULL, mainproc, NULL, "start AFS");
     cmd_AddParm(ts, "-blocks", CMD_SINGLE, CMD_OPTIONAL, "1024 byte blocks in cache");
     cmd_AddParm(ts, "-files", CMD_SINGLE, CMD_OPTIONAL, "files in cache");
     cmd_AddParm(ts, "-rootvol", CMD_SINGLE, CMD_OPTIONAL, "name of AFS root volume");
@@ -1914,6 +1989,8 @@ char **argv; {
                ), "Enable AFSDB support");
     cmd_AddParm(ts, "-files_per_subdir", CMD_SINGLE, CMD_OPTIONAL, "log(2) of the number of cache files per cache subdirectory");
     cmd_AddParm(ts, "-dynroot", CMD_FLAG, CMD_OPTIONAL, "Enable dynroot support");
+    cmd_AddParm(ts, "-fakestat", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support for cross-cell mounts");
+    cmd_AddParm(ts, "-fakestat-all", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support for all mounts");
     return (cmd_Dispatch(argc, argv));
 }