diff --git a/lib/setup.php b/lib/setup.php index 419f83fb172..306a9642f77 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -666,6 +666,12 @@ $bootstrapcachefile = $CFG->localcachedir . '/bootstrap.php'; if (is_readable($bootstrapcachefile)) { try { require_once($bootstrapcachefile); + // Verify the file is not stale. + if (!isset($CFG->bootstraphash) || $CFG->bootstraphash !== hash_local_config_cache()) { + // Something has changed, the bootstrap.php file is stale. + unset($CFG->siteidentifier); + @unlink($bootstrapcachefile); + } } catch (Throwable $e) { // If it is corrupted then attempt to delete it and it will be rebuilt. @unlink($bootstrapcachefile); diff --git a/lib/setuplib.php b/lib/setuplib.php index ddcc4b04d1b..040d589965c 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -809,7 +809,11 @@ function initialise_local_config_cache() { $contents = "<?php // ********** This file is generated DO NOT EDIT ********** \$CFG->siteidentifier = '" . addslashes($CFG->siteidentifier) . "'; -define('SYSCONTEXTID', ".SYSCONTEXTID."); +\$CFG->bootstraphash = '" . hash_local_config_cache() . "'; +// Only if the file is not stale and has not been defined. +if (\$CFG->bootstraphash === hash_local_config_cache() && !defined('SYSCONTEXTID')) { + define('SYSCONTEXTID', ".SYSCONTEXTID."); +} "; $temp = $bootstrapcachefile . '.tmp' . uniqid(); @@ -819,6 +823,25 @@ define('SYSCONTEXTID', ".SYSCONTEXTID."); } } +/** + * Calculate a proper hash to be able to invalidate stale cached configs. + * + * Only to be used to verify bootstrap.php status. + * + * @return string md5 hash of all the sensible bits deciding if cached config is stale or no. + */ +function hash_local_config_cache() { + global $CFG; + + // This is pretty much {@see moodle_database::get_settings_hash()} that is used + // as identifier for the database meta information MUC cache. Should be enough to + // react against any of the normal changes (new prefix, change of DB type) while + // *incorrectly* keeping the old dataroot directory unmodified with stale data. + // This may need more stuff to be considered if it's discovered that there are + // more variables making the file stale. + return md5($CFG->dbtype . $CFG->dbhost . $CFG->dbuser . $CFG->dbname . $CFG->prefix); +} + /** * Initialises $FULLME and friends. Private function. Should only be called from * setup.php.