[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
This commit is contained in:
MaikVermeulen
2026-03-24 09:38:47 -05:00
committed by GitHub
parent 37c6808380
commit 683086776f
7 changed files with 65 additions and 10 deletions
+6
View File
@@ -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] == '+')
@@ -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;
/**
+3 -2
View File
@@ -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.
+15 -5
View File
@@ -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<uint8_t *>(&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<uint8_t *>(&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);
+23 -2
View File
@@ -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;
+15
View File
@@ -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;
};
+1 -1
View File
@@ -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();