MVC/Config - change exclusive to shared lock as discussed in https://github.com/opnsense/core/issues/6565 (minor rework on bebf3a2a7c)

Also replace copy() with a locked version for restoreBackup().
This commit is contained in:
Ad Schellevis 2023-05-17 20:15:38 +02:00
parent 3a6c79d4bc
commit 4d0eb9d323

View File

@ -366,9 +366,9 @@ class Config extends Singleton
{
/**
* load data from stream in shared mode unless no valid xml data is returned
* (in which case the writer holds a lock and we should wait for it [LOCK_EX])
* (in which case the writer holds a lock and we should wait for it [LOCK_SH])
*/
foreach ([LOCK_SH | LOCK_NB, LOCK_EX] as $idx => $mode) {
foreach ([LOCK_SH | LOCK_NB, LOCK_SH] as $idx => $mode) {
flock($fp, $mode);
fseek($fp, 0);
$xml = trim(stream_get_contents($fp));
@ -585,6 +585,21 @@ class Config extends Singleton
return array();
}
/**
* Overwrite current config with contents of new file
* @param $filename
*/
private function overwrite($filename)
{
$fhandle = fopen($this->config_file, "r+");
if (flock($fhandle, LOCK_EX)) {
fseek($fhandle, 0);
ftruncate($fhandle, 0);
fwrite($fhandle, file_get_contents($filename));
fclose($fhandle);
}
}
/**
* restore and load backup config
* @param $filename
@ -600,7 +615,7 @@ class Config extends Singleton
$config_file_handle = $this->config_file_handle;
try {
// try to restore config
copy($filename, $this->config_file);
$this->overwrite($filename);
$this->load();
return true;
} catch (ConfigException $e) {
@ -613,7 +628,7 @@ class Config extends Singleton
}
} else {
// we don't have a valid config loaded, just copy and load the requested one
copy($filename, $this->config_file);
$this->overwrite($filename);
$this->load();
return true;
}