From fc9211be1b242e7026a679a41e5f53f3b4a7e818 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Tue, 7 Aug 2018 17:08:26 -0500 Subject: [PATCH] afs: Return memcache allocation errors 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. Reviewed-on: https://gerrit.openafs.org/13273 Tested-by: BuildBot Reviewed-by: Michael Meffie Reviewed-by: Benjamin Kaduk (cherry picked from commit 0da5ac4d9fb2a9b46c7415403a3cd26e711554e2) Change-Id: I00b0d3dac1f4d8edc46389fe3c59501fd23c18f8 Reviewed-on: https://gerrit.openafs.org/13307 Reviewed-by: Michael Meffie Reviewed-by: Marcio Brito Barbosa Reviewed-by: Mark Vitale Tested-by: BuildBot Reviewed-by: Stephan Wiesand --- src/afs/afs_dcache.c | 4 +++- src/afs/afs_init.c | 6 +++++- src/afs/afs_prototypes.h | 4 ++-- src/afsd/afsd.c | 6 +++++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 303bfca28..eb07a4aa6 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -3298,7 +3298,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; @@ -3425,6 +3425,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); @@ -3432,6 +3433,7 @@ afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk, int aflags) cacheDiskType = AFS_FCACHE_TYPE_UFS; afs_cacheType = &afs_UfsCacheOps; } + return 0; } /*! diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index 476d5bdfc..9a6c5b8fe 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -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. diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index fb8ddf41c..c38b0b9c0 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -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); diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index b3f2fc56b..a93db051e 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -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) { -- 2.39.5