Skip to content

Store lock files in /dev/shm/osrm -> ~/.osrm/ instead of /tmp to prevent systemd cleanup#7443

Merged
DennisOSRM merged 2 commits intoProject-OSRM:masterfrom
Charmik:move-shared-memory-lock-to-home-dir
Apr 10, 2026
Merged

Store lock files in /dev/shm/osrm -> ~/.osrm/ instead of /tmp to prevent systemd cleanup#7443
DennisOSRM merged 2 commits intoProject-OSRM:masterfrom
Charmik:move-shared-memory-lock-to-home-dir

Conversation

@Charmik
Copy link
Copy Markdown
Contributor

@Charmik Charmik commented Apr 3, 2026

Issue

Move shared memory lock files out of /tmp to prevent cleanup

Lock files used by ftok() to locate System V shared memory segments were
stored in /tmp, which is cleaned by systemd-tmpfiles-clean (Linux, ~10
days) and periodic scripts (macOS, ~3 days). The shared memory segments
themselves survive cleanup as kernel resources, leaving OSRM unable to
reconnect: "lock file does not exist, exiting".

Lock directory is now selected with graceful fallback:

  1. SHM_LOCK_DIR env var (explicit override, unchanged)
  2. /dev/shm/osrm-/ (Linux only — RAM-backed tmpfs, never
    cleaned, cleared on reboot together with shared memory segments)
  3. ~/.osrm/ (macOS, Windows via %USERPROFILE%)

The selected directory is logged at startup. /tmp is no longer used.

Validated locally on Mac & Linux:

➜  ~  ls -l ~/.osrm
total 0
-rw-r--r--  1 charm  staff  0 Apr  3 16:19 osrm-0.lock
-rw-r--r--  1 charm  staff  0 Apr  3 16:19 osrm-1.lock
-rw-r--r--  1 charm  staff  0 Apr  3 16:19 osrm-datastore.lock

This change was developed with assistance from Claude (Opus 4.6).

Tasklist

Requirements / Relations

None

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates OSRM shared-memory lock file directory selection to avoid /tmp cleanup on long-running Linux systems (e.g., systemd tmpfiles), and adds unit tests covering the new priority order.

Changes:

  • Prefer $HOME/.osrm/ for lock files when SHM_LOCK_DIR is not set, with /tmp as a fallback.
  • Add unit tests for getLockDir() behavior (env override, home default, and tmp fallback).
  • Update getLockDir() documentation to describe the new priority.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
src/storage/shared_memory.cpp Implements $HOME/.osrm default lock directory and ensures the directory exists.
include/storage/shared_memory.hpp Updates API documentation to reflect lock directory priority and rationale.
unit_tests/storage/shared_memory.cpp Adds unit tests validating getLockDir() selection logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/storage/shared_memory.cpp Outdated
Comment on lines 241 to 245
std::filesystem::create_directories(lock_dir);
return lock_dir;
}

return std::filesystem::temp_directory_path();
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getLockDir() unconditionally calls std::filesystem::create_directories(lock_dir) and will throw std::filesystem::filesystem_error if $HOME exists but is not writable (or if ~/.osrm is an existing non-directory). This can abort makeSharedMemory() / Storage::Run() rather than falling back to the system temp directory. Consider using the error_code overload (or catching filesystem_error) and falling back to temp_directory_path() with a clear log / exception message suggesting SHM_LOCK_DIR.

Suggested change
std::filesystem::create_directories(lock_dir);
return lock_dir;
}
return std::filesystem::temp_directory_path();
std::error_code ec;
const bool exists = std::filesystem::exists(lock_dir, ec);
if (!ec)
{
if (exists)
{
if (std::filesystem::is_directory(lock_dir, ec) && !ec)
{
return lock_dir;
}
util::Log(logWARNING)
<< "Cannot use shared memory lock directory " << lock_dir
<< ": path exists but is not a directory. Falling back to temporary "
"directory. Set SHM_LOCK_DIR to override.";
}
else
{
std::filesystem::create_directories(lock_dir, ec);
if (!ec)
{
return lock_dir;
}
util::Log(logWARNING)
<< "Cannot create shared memory lock directory " << lock_dir << ": "
<< ec.message()
<< ". Falling back to temporary directory. Set SHM_LOCK_DIR to override.";
}
}
else
{
util::Log(logWARNING)
<< "Cannot inspect shared memory lock directory " << lock_dir << ": "
<< ec.message()
<< ". Falling back to temporary directory. Set SHM_LOCK_DIR to override.";
}
}
std::error_code ec;
auto temp_dir = std::filesystem::temp_directory_path(ec);
if (ec)
{
throw util::exception("Could not determine a shared memory lock directory; "
"failed to use HOME/USERPROFILE and temp_directory_path(): " +
ec.message() +
". Set SHM_LOCK_DIR to a writable directory." + SOURCE_REF);
}
return temp_dir;

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added check of error_code

Comment thread include/storage/shared_memory.hpp Outdated
Comment on lines +44 to +46
* Priority: SHM_LOCK_DIR env var > $HOME/.osrm/ > system temp directory.
* Using $HOME/.osrm/ by default avoids lock files being cleaned by
* systemd-tmpfiles-clean, which would break shared memory access.
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc comment describes the default as $HOME/.osrm/, but on Windows the implementation also falls back to %USERPROFILE%. Consider updating the comment to reflect the Windows behavior (or avoid platform-specific env var names in the public header).

Suggested change
* Priority: SHM_LOCK_DIR env var > $HOME/.osrm/ > system temp directory.
* Using $HOME/.osrm/ by default avoids lock files being cleaned by
* systemd-tmpfiles-clean, which would break shared memory access.
* Priority: SHM_LOCK_DIR env var > user-specific .osrm directory in the
* home/profile directory > system temp directory.
* Using a user-specific .osrm directory by default avoids lock files being
* cleaned by system temp directory cleanup tools, which would break shared
* memory access.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added "home/profile directory"

Comment thread unit_tests/storage/shared_memory.cpp Outdated
Comment on lines +16 to +24
const char *home = std::getenv("HOME");
// Skip if HOME is not set (e.g. in containers)
if (!home)
return;

auto lock_dir = getLockDir();
auto expected = std::filesystem::path(home) / ".osrm";
BOOST_CHECK_EQUAL(lock_dir, expected);
BOOST_CHECK(std::filesystem::exists(lock_dir));
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test calls getLockDir() using the real HOME and can create ~/.osrm on the developer/CI machine. To keep unit tests hermetic, consider setting HOME to a temporary directory for the duration of the test (and restoring it afterward).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added auto temp_home = std::filesystem::temp_directory_path() / "osrm-test-home";

Comment thread unit_tests/storage/shared_memory.cpp Outdated
Comment on lines +13 to +15
// Ensure SHM_LOCK_DIR is not set
::unsetenv("SHM_LOCK_DIR");

Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test unsets SHM_LOCK_DIR but does not restore its previous value. If the environment running the test had SHM_LOCK_DIR set, this can leak across test cases and cause order-dependent failures. Consider an RAII env-var guard that saves/restores the previous value.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added RAII EnvGuard

Comment on lines +29 to +37
auto temp = std::filesystem::temp_directory_path() / "osrm-test-lock-dir";
std::filesystem::create_directories(temp);

::setenv("SHM_LOCK_DIR", temp.c_str(), 1);
auto lock_dir = getLockDir();
BOOST_CHECK_EQUAL(lock_dir, temp);

::unsetenv("SHM_LOCK_DIR");
std::filesystem::remove(temp);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setenv/unsetenv are POSIX APIs and will not compile on Windows; additionally std::filesystem::path::c_str() is wchar_t* on Windows. If these unit tests are built cross-platform, consider using a small portability wrapper (e.g., _putenv_s on Windows) and passing temp.string().

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, but didn't test windows


#include <boost/test/unit_test.hpp>

#include <cstdlib>
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file uses std::filesystem and std::string directly but only includes <cstdlib>. Consider adding explicit includes for <filesystem> and <string> to avoid relying on transitive headers.

Suggested change
#include <cstdlib>
#include <cstdlib>
#include <filesystem>
#include <string>

Copilot uses AI. Check for mistakes.
@Charmik Charmik force-pushed the move-shared-memory-lock-to-home-dir branch from ab27c49 to 95088d8 Compare April 6, 2026 18:30
Lock files used by ftok() to locate System V shared memory segments were
stored in /tmp, which is cleaned by systemd-tmpfiles-clean (Linux, ~10
days) and periodic scripts (macOS, ~3 days). The shared memory segments
themselves survive cleanup as kernel resources, leaving OSRM unable to
reconnect: "lock file does not exist, exiting".

Lock directory is now selected with graceful fallback:
  1. SHM_LOCK_DIR env var (explicit override, unchanged)
  2. /dev/shm/osrm-<uid>/ (Linux only — RAM-backed tmpfs, never
     cleaned, cleared on reboot together with shared memory segments)
  3. ~/.osrm/ (macOS, Windows via %USERPROFILE%)

The selected directory is logged at startup. /tmp is no longer used.
@Charmik Charmik force-pushed the move-shared-memory-lock-to-home-dir branch from 95088d8 to ded37fe Compare April 6, 2026 18:51
@Charmik Charmik changed the title Store lock files in ~/.osrm/ instead of /tmp to prevent systemd cleanup Store lock files in /dev/shm/osrm -> ~/.osrm/ instead of /tmp to prevent systemd cleanup Apr 7, 2026
@DennisOSRM DennisOSRM enabled auto-merge (squash) April 10, 2026 17:03
@DennisOSRM DennisOSRM merged commit 738d412 into Project-OSRM:master Apr 10, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants