From 3274c5db896171d0d17c671cab376902a9d62b3c Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Tue, 3 Sep 2013 21:26:15 +0800 Subject: [PATCH] MDL-41460 core_component: Validate cache against version.php --- admin/index.php | 10 ++++++++++ lib/classes/component.php | 29 +++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/admin/index.php b/admin/index.php index 466832c5357..1f186b6417a 100644 --- a/admin/index.php +++ b/admin/index.php @@ -66,6 +66,16 @@ if (empty($_GET['cache']) and empty($_POST['cache']) and empty($_GET['sesskey']) } require('../config.php'); + +// Invalidate the cache of version.php in any circumstances to help core_component +// detecting if the version has changed and component cache should be reset. +if (function_exists('opcache_invalidate')) { + opcache_invalidate($CFG->dirroot . '/version.php', true); +} +// Make sure the component cache gets rebuilt if necessary, any method that +// indirectly calls the protected init() method is good here. +core_component::get_core_subsystems(); + require_once($CFG->libdir.'/adminlib.php'); // various admin-only functions require_once($CFG->libdir.'/upgradelib.php'); // general upgrade/install related functions require_once($CFG->libdir.'/pluginlib.php'); // available updates notifications diff --git a/lib/classes/component.php b/lib/classes/component.php index 0fa7c30d5fe..f9e46ec3a81 100644 --- a/lib/classes/component.php +++ b/lib/classes/component.php @@ -43,6 +43,8 @@ class core_component { protected static $classmap = null; /** @var null list of some known files that can be included. */ protected static $filemap = null; + /** @var int|float core version. */ + protected static $version = null; /** @var array list of the files to map. */ protected static $filestomap = array('lib.php', 'settings.php'); @@ -133,8 +135,11 @@ class core_component { include($cachefile); if (!is_array($cache)) { // Something is very wrong. - } else if (!isset($cache['plugintypes']) or !isset($cache['plugins']) or !isset($cache['subsystems']) or !isset($cache['classmap'])) { + } else if (!isset($cache['version'])) { // Something is very wrong. + } else if ((float) $cache['version'] !== (float) self::fetch_core_version()) { + // Outdated cache. We trigger an error log to track an eventual repetitive failure of float comparison. + error_log('Resetting core_component cache after core upgrade to version ' . self::fetch_core_version()); } else if ($cache['plugintypes']['mod'] !== "$CFG->dirroot/mod") { // $CFG->dirroot was changed. } else { @@ -227,6 +232,7 @@ class core_component { 'plugins' => self::$plugins, 'classmap' => self::$classmap, 'filemap' => self::$filemap, + 'version' => self::$version, ); return 'dirroot . '/version.php'); + self::$version = $version; + } + return self::$version; } /** @@ -867,9 +890,7 @@ $cache = '.var_export($cache, true).'; $versions = array(); // Main version first. - $version = null; - include($CFG->dirroot.'/version.php'); - $versions['core'] = $version; + $versions['core'] = self::fetch_core_version(); // The problem here is tha the component cache might be stable, // we want this to work also on frontpage without resetting the component cache.