afs: Return memcache allocation errors 73/13273/2
authorAndrew Deason <adeason@sinenomine.net>
Tue, 7 Aug 2018 22:08:26 +0000 (17:08 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 10 Aug 2018 11:46:40 +0000 (07:46 -0400)
During cache initialization, we can fail to allocate our dcache
entries for memcache. Currently when this happens, we just log a
message and try to disable dcache access. However, this results in at
least one code path that causes a panic anyway during startup, since
afs_CacheTruncateDaemon will try to trim the cache, and afs_GetDownD
will call afs_MemGetDSlot, and we cannot find the given dslot.

To avoid this, change our cache initialization to return an error,
instead of trying to continue without a functional dcache. This causes
afs_dcacheInit to return an error in this case, and by extension
afs_CacheInit and the AFSOP_CACHEINIT syscall. Also change afsd to
actually detect errors from AFSOP_CACHEINIT, and to bail out when it
does.

Thanks to gsgatlin@ncsu.edu for reporting the relevant panic.

Change-Id: Ic89ff9638201faae6c4399a2344d4da3e251d537
Reviewed-on: https://gerrit.openafs.org/13273
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/afs_dcache.c
src/afs/afs_init.c
src/afs/afs_prototypes.h
src/afsd/afsd.c

index 3c437bd..64f88a9 100644 (file)
@@ -3319,7 +3319,7 @@ afs_InitCacheFile(char *afile, ino_t ainode)
  * \param aflags
  *
  */
-void
+int
 afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk, int aflags)
 {
     struct dcache *tdp;
@@ -3446,6 +3446,7 @@ afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk, int aflags)
            afs_warn("afsd: memory cache too large for available memory.\n");
            afs_warn("afsd: AFS files cannot be accessed.\n\n");
            dcacheDisabled = 1;
+            return code;
        } else
            afs_warn("Memory cache: Allocating %d dcache entries...",
                   aDentries);
@@ -3453,6 +3454,7 @@ afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk, int aflags)
        cacheDiskType = AFS_FCACHE_TYPE_UFS;
        afs_cacheType = &afs_UfsCacheOps;
     }
+    return 0;
 }
 
 /*!
index 476d5bd..9a6c5b8 100644 (file)
@@ -99,6 +99,7 @@ afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks,
              afs_int32 dynamic_vcaches)
 {
     afs_int32 i;
+    int code;
     struct volume *tv;
 
     AFS_STATCNT(afs_CacheInit);
@@ -152,7 +153,10 @@ afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks,
     afs_cacheFiles = afiles;
     afs_cacheStats = astatSize;
     afs_vcacheInit(astatSize);
-    afs_dcacheInit(afiles, ablocks, aDentries, achunk, aflags);
+    code = afs_dcacheInit(afiles, ablocks, aDentries, achunk, aflags);
+    if (code) {
+        return code;
+    }
 #if defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED)
     /*
      * Save current credentials for later access to disk cache files.
index 1f371fc..6e3ac54 100644 (file)
@@ -247,8 +247,8 @@ extern afs_dcache_id_t cacheInode;
 extern struct osi_file *afs_cacheInodep;
 extern int DCHash(struct VenusFid *fid, afs_int32 chunk);
 extern int DVHash(struct VenusFid *fid);
-extern void afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk,
-                          int aflags);
+extern int afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk,
+                         int aflags);
 extern int afs_PutDCache(struct dcache *adc);
 extern void afs_FlushDCache(struct dcache *adc);
 extern void shutdown_dcache(void);
index b3f2fc5..a93db05 100644 (file)
@@ -2250,7 +2250,11 @@ afsd_run(void)
     cparams.setTimeFlag = 0;
     cparams.memCacheFlag = cacheFlags;
     cparams.dynamic_vcaches = afsd_dynamic_vcaches;
-    afsd_syscall(AFSOP_CACHEINIT, &cparams);
+    code = afsd_syscall(AFSOP_CACHEINIT, &cparams);
+    if (code) {
+       printf("%s: Error %d during cache init.\n", rn, code);
+        exit(1);
+    }
 
     /* do it before we init the cache inodes */
     if (enable_splitcache) {