Add locking around operations which change the configuration. (#1644)

* Add locking around operations which change the configuration.
Avoid any potential race conditions when changing the configuration
by putting a lock around any non-GET operations.

* Add a sync before a 'reboot' operation
This commit is contained in:
Tim Wilkinson 2024-10-23 18:32:48 -07:00 committed by GitHub
parent 1edfae6dae
commit a814f8b0ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 14 deletions

View File

@ -54,12 +54,11 @@ import * as constants from "./constants.uc";
const pageCache = {}; const pageCache = {};
const resourceVersions = {}; const resourceVersions = {};
const lockfile = "/tmp/ui.lock";
log.openlog("uhttpd.aredn", log.LOG_PID, log.LOG_USER); log.openlog("uhttpd.aredn", log.LOG_PID, log.LOG_USER);
const light = fs.readfile(`${config.application}/resource/css/themes/light.css`); fs.writefile(`${config.application}/resource/css/themes/default.css`, `${fs.readfile(`${config.application}/resource/css/themes/light.css`)}@media (prefers-color-scheme: dark) {\n${fs.readfile(`${config.application}/resource/css/themes/dark.css`)}\n}`);
const dark = fs.readfile(`${config.application}/resource/css/themes/dark.css`);
fs.writefile(`${config.application}/resource/css/themes/default.css`, `${light}@media (prefers-color-scheme: dark) {\n${dark}\n}`);
if (!fs.access(`${config.application}/resource/css/theme.css`)) { if (!fs.access(`${config.application}/resource/css/theme.css`)) {
fs.symlink("themes/default.css", `${config.application}/resource/css/theme.css`); fs.symlink("themes/default.css", `${config.application}/resource/css/theme.css`);
} }
@ -80,8 +79,6 @@ if (config.preload) {
} }
cp("/main/"); cp("/main/");
cp("/partial/"); cp("/partial/");
radios.getCommonConfiguration();
} }
if (config.resourcehash) { if (config.resourcehash) {
@ -145,6 +142,8 @@ else {
fs.unlink(`${config.application}/resource/css/theme.version`); fs.unlink(`${config.application}/resource/css/theme.version`);
} }
fs.writefile(lockfile, "");
global._R = function(path, arg) global._R = function(path, arg)
{ {
const tpath = `${config.application}/partial/${path}.ut`; const tpath = `${config.application}/partial/${path}.ut`;
@ -452,6 +451,14 @@ global.handle_request = function(env)
return; return;
} }
} }
let changelock = null;
if (env.REQUEST_METHOD !== "GET") {
changelock = fs.open(lockfile);
if (!(changelock && changelock.lock("x"))) {
uhttpd.send("Status: 500 Internal server error\r\n\r\n");
return;
}
}
const args = {}; const args = {};
if (env.CONTENT_TYPE === "application/x-www-form-urlencoded") { if (env.CONTENT_TYPE === "application/x-www-form-urlencoded") {
let b = ""; let b = "";
@ -590,8 +597,11 @@ global.handle_request = function(env)
res res
); );
} }
if (changelock) {
changelock.close();
}
if (response.reboot) { if (response.reboot) {
system(`(sleep 2; ${response.reboot})&`); system(`(sleep 2; sync; ${response.reboot})&`);
} }
return; return;
} }

View File

@ -102,15 +102,12 @@ function initSetup()
setupKeys = []; setupKeys = [];
const f = fs.open("/etc/config.mesh/_setup"); const f = fs.open("/etc/config.mesh/_setup");
if (f) { if (f) {
for (;;) { for (let l = f.read("line"); length(l); l = f.read("line")) {
const line = f.read("line"); const kv = split(l, "=", 2);
if (!length(line)) {
break;
}
const kv = split(line, " =", 2);
if (length(kv) === 2) { if (length(kv) === 2) {
setup[kv[0]] = trim(kv[1]); const k = trim(kv[0]);
push(setupKeys, kv[0]); setup[k] = trim(kv[1]);
push(setupKeys, k);
} }
} }
f.close(); f.close();
@ -121,7 +118,9 @@ function initSetup()
export function reset() export function reset()
{ {
setup = null; setup = null;
setupKeys = null;
cursor = null; cursor = null;
setupChanged = false;
}; };
export function getSettingAsString(key, def) export function getSettingAsString(key, def)