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 <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit
0da5ac4d9fb2a9b46c7415403a3cd26e711554e2)
Change-Id: I00b0d3dac1f4d8edc46389fe3c59501fd23c18f8
Reviewed-on: https://gerrit.openafs.org/13307
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Marcio Brito Barbosa <mbarbosa@sinenomine.net>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
* \param aflags
*
*/
-void
+int
afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk, int aflags)
{
struct dcache *tdp;
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);
cacheDiskType = AFS_FCACHE_TYPE_UFS;
afs_cacheType = &afs_UfsCacheOps;
}
+ return 0;
}
/*!
afs_int32 dynamic_vcaches)
{
afs_int32 i;
+ int code;
struct volume *tv;
AFS_STATCNT(afs_CacheInit);
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.
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);
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) {