Fix race condition when creating socket folder

If two processes call `mkdir` at the same time, the second one will fail
and wrongly assume the folder wasn't created properly.

We now first check if the folder really doesn't exist and we also catch
any IPC initialization errors and disable IPC instead of crashing the
whole bar.
This commit is contained in:
patrick96 2022-01-25 00:18:04 +01:00 committed by Patrick Ziegler
parent f428b7bb2f
commit 28af6bb493
2 changed files with 10 additions and 2 deletions

View File

@ -20,7 +20,10 @@ namespace ipc {
string ensure_runtime_path() { string ensure_runtime_path() {
string runtime_path = get_runtime_path(); string runtime_path = get_runtime_path();
if (!file_util::exists(runtime_path) && mkdir(runtime_path.c_str(), 0700) == -1) { if (!file_util::exists(runtime_path) && mkdir(runtime_path.c_str(), 0700) == -1) {
throw system_error("Failed to create ipc socket folders"); // It's possible the folder was created in the meantime, we have to check again.
if (!file_util::exists(runtime_path)) {
throw system_error("Failed to create ipc socket folders");
}
} }
return runtime_path; return runtime_path;

View File

@ -148,7 +148,12 @@ int main(int argc, char** argv) {
unique_ptr<ipc::ipc> ipc{}; unique_ptr<ipc::ipc> ipc{};
if (conf.get(conf.section(), "enable-ipc", false)) { if (conf.get(conf.section(), "enable-ipc", false)) {
ipc = ipc::ipc::make(loop); try {
ipc = ipc::ipc::make(loop);
} catch (const std::exception& e) {
ipc.reset();
logger.err("Disabling IPC channels due to error: %s", e.what());
}
} }
auto ctrl = controller::make((bool)ipc, loop); auto ctrl = controller::make((bool)ipc, loop);