From 683086776f092d2cdbb05fdb7c224330982a005e Mon Sep 17 00:00:00 2001 From: MaikVermeulen Date: Tue, 24 Mar 2026 15:38:47 +0100 Subject: [PATCH] [posix] add --settings-file option for fixed settings file name (#12719) This adds a new --settings-file launch option that allows specifying a fixed base name for the settings file, overriding the default EUI64-based naming scheme. When an RCP device is replaced, the new device has a different EUI64, which causes the host to lose access to its previously stored dataset. By using --settings-file, the settings file name remains stable across RCP replacements, preserving the Thread network configuration. Ref: https://github.com/orgs/openthread/discussions/12428 --- src/posix/main.c | 6 +++++ .../include/openthread/openthread-system.h | 2 ++ src/posix/platform/platform-posix.h | 5 ++-- src/posix/platform/settings.cpp | 20 +++++++++++---- src/posix/platform/settings_file.cpp | 25 +++++++++++++++++-- src/posix/platform/settings_file.hpp | 15 +++++++++++ src/posix/platform/system.cpp | 2 +- 7 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/posix/main.c b/src/posix/main.c index 88e373d98..3fe53530b 100644 --- a/src/posix/main.c +++ b/src/posix/main.c @@ -141,6 +141,7 @@ enum OT_POSIX_OPT_DATA_PATH, OT_POSIX_OPT_RADIO_VERSION, OT_POSIX_OPT_REAL_TIME_SIGNAL, + OT_POSIX_OPT_SETTINGS_FILE, #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE OT_POSIX_OPT_TUN_DEVICE, #endif @@ -156,6 +157,7 @@ static const struct option kOptions[] = { {"persistent-interface", no_argument, NULL, OT_POSIX_OPT_PERSISTENT_INTERFACE}, {"radio-version", no_argument, NULL, OT_POSIX_OPT_RADIO_VERSION}, {"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL}, + {"settings-file", required_argument, NULL, OT_POSIX_OPT_SETTINGS_FILE}, {"time-speed", required_argument, NULL, OT_POSIX_OPT_TIME_SPEED}, #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE {"tun-device", required_argument, NULL, OT_POSIX_OPT_TUN_DEVICE}, @@ -170,6 +172,7 @@ static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode) " %s [Options] RadioURL [RadioURL]\n" "Options:\n" " --data-path Path of directory to store data.\n" + " --settings-file Fixed settings file base name (overrides EUI64-based naming).\n" #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE " --tun-device POSIX TUN Device.\n" #endif @@ -263,6 +266,9 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig) case OT_POSIX_OPT_DATA_PATH: aConfig->mPlatformConfig.mDataPath = optarg; break; + case OT_POSIX_OPT_SETTINGS_FILE: + aConfig->mPlatformConfig.mSettingsFile = optarg; + break; #ifdef SIGRTMIN case OT_POSIX_OPT_REAL_TIME_SIGNAL: if (optarg[0] == '+') diff --git a/src/posix/platform/include/openthread/openthread-system.h b/src/posix/platform/include/openthread/openthread-system.h index adc7caa33..2c6afa38b 100644 --- a/src/posix/platform/include/openthread/openthread-system.h +++ b/src/posix/platform/include/openthread/openthread-system.h @@ -96,6 +96,8 @@ typedef struct otPlatformConfig CoprocessorType mCoprocessorType; ///< The co-processor type. This field is used to pass ///< the type to the app layer. const char *mDataPath; ///< Data path. + const char *mSettingsFile; ///< Fixed settings file base name. When set, this + ///< overrides the default EUI64-based file naming. } otPlatformConfig; /** diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h index 0e01c64ea..04a89e009 100644 --- a/src/posix/platform/platform-posix.h +++ b/src/posix/platform/platform-posix.h @@ -175,9 +175,10 @@ void platformRandomInit(void); * * @note This function is called before OpenThread instance is created. * - * @param[in] aDataPath The data path to store setting files. + * @param[in] aDataPath The data path to store setting files. + * @param[in] aSettingsFileName The fixed settings file base name, or nullptr to use EUI-64 based naming. */ -void platformSettingsInit(const char *aDataPath); +void platformSettingsInit(const char *aDataPath, const char *aSettingsFileName); /** * Initializes the logging service used by OpenThread. diff --git a/src/posix/platform/settings.cpp b/src/posix/platform/settings.cpp index 3ae37f1bf..9e65e2dfc 100644 --- a/src/posix/platform/settings.cpp +++ b/src/posix/platform/settings.cpp @@ -83,13 +83,23 @@ exit: static otError settingsFileInit(otInstance *aInstance) { char fileBaseName[ot::Posix::SettingsFile::kMaxFileBaseNameSize]; - const char *offset = getenv("PORT_OFFSET"); - uint64_t nodeId; + const char *settingsFile = ot::Posix::SettingsFile::GetSettingsFileName(); - otPlatRadioGetIeeeEui64(aInstance, reinterpret_cast(&nodeId)); - nodeId = ot::BigEndian::HostSwap64(nodeId); + if (settingsFile != nullptr) + { + snprintf(fileBaseName, sizeof(fileBaseName), "%s", settingsFile); + } + else + { + const char *offset = getenv("PORT_OFFSET"); + uint64_t nodeId; + + otPlatRadioGetIeeeEui64(aInstance, reinterpret_cast(&nodeId)); + nodeId = ot::BigEndian::HostSwap64(nodeId); + + snprintf(fileBaseName, sizeof(fileBaseName), "%s_%" PRIx64, offset == nullptr ? "0" : offset, nodeId); + } - snprintf(fileBaseName, sizeof(fileBaseName), "%s_%" PRIx64, offset == nullptr ? "0" : offset, nodeId); VerifyOrDie(strlen(fileBaseName) < ot::Posix::SettingsFile::kMaxFileBaseNameSize, OT_EXIT_FAILURE); return sSettingsFile.Init(fileBaseName); diff --git a/src/posix/platform/settings_file.cpp b/src/posix/platform/settings_file.cpp index 512cdbf3d..e76c41a83 100644 --- a/src/posix/platform/settings_file.cpp +++ b/src/posix/platform/settings_file.cpp @@ -46,12 +46,17 @@ #include "common/debug.hpp" #include "posix/platform/settings_file.hpp" -void platformSettingsInit(const char *aDataPath) { ot::Posix::SettingsFile::SetSettingsPath(aDataPath); } +void platformSettingsInit(const char *aDataPath, const char *aSettingsFileName) +{ + ot::Posix::SettingsFile::SetSettingsPath(aDataPath); + ot::Posix::SettingsFile::SetSettingsFileName(aSettingsFileName); +} namespace ot { namespace Posix { -char SettingsFile::sSettingsPath[] = OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH; +char SettingsFile::sSettingsPath[] = OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH; +char SettingsFile::sSettingsFileName[kMaxFileBaseNameSize] = ""; const char *SettingsFile::GetSettingsPath(void) { return sSettingsPath; } void SettingsFile::SetSettingsPath(const char *aSettingsPath) @@ -60,6 +65,22 @@ void SettingsFile::SetSettingsPath(const char *aSettingsPath) aSettingsPath == nullptr ? OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH : aSettingsPath); } +const char *SettingsFile::GetSettingsFileName(void) +{ + return sSettingsFileName[0] != '\0' ? sSettingsFileName : nullptr; +} +void SettingsFile::SetSettingsFileName(const char *aSettingsFileName) +{ + if (aSettingsFileName != nullptr) + { + snprintf(sSettingsFileName, sizeof(sSettingsFileName), "%s", aSettingsFileName); + } + else + { + sSettingsFileName[0] = '\0'; + } +} + otError SettingsFile::Init(const char *aSettingsFileBaseName) { otError error = OT_ERROR_NONE; diff --git a/src/posix/platform/settings_file.hpp b/src/posix/platform/settings_file.hpp index ffa8b373a..1ada6e9de 100644 --- a/src/posix/platform/settings_file.hpp +++ b/src/posix/platform/settings_file.hpp @@ -56,6 +56,20 @@ public: */ static void SetSettingsPath(const char *aSettingsPath); + /** + * Gets the fixed settings file base name. + * + * @returns The fixed settings file base name, or nullptr if not set. + */ + static const char *GetSettingsFileName(void); + + /** + * Sets the fixed settings file base name. + * + * @param[in] aSettingsFileName The settings file base name, or nullptr to clear. + */ + static void SetSettingsFileName(const char *aSettingsFileName); + SettingsFile(void) : mSettingsFd(-1) { @@ -139,6 +153,7 @@ private: void SwapDiscard(int aFd); static char sSettingsPath[kMaxFileBasePathNameSize]; + static char sSettingsFileName[kMaxFileBaseNameSize]; char mSettingsFileFullPathName[kMaxFileFullPathNameSize]; int mSettingsFd; }; diff --git a/src/posix/platform/system.cpp b/src/posix/platform/system.cpp index 42017045f..8decdb14d 100644 --- a/src/posix/platform/system.cpp +++ b/src/posix/platform/system.cpp @@ -180,7 +180,7 @@ void platformInitNcpMode(otPlatformConfig *aPlatformConfig) void platformInit(otPlatformConfig *aPlatformConfig) { - platformSettingsInit(aPlatformConfig->mDataPath); + platformSettingsInit(aPlatformConfig->mDataPath, aPlatformConfig->mSettingsFile); #if OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE platformBacktraceInit();