From f32beac5743f2cce02757ec15145639d64cf23aa Mon Sep 17 00:00:00 2001 From: Tongze Wang Date: Thu, 1 Jan 2026 07:06:30 +0800 Subject: [PATCH] [posix] allow set settings path at runtime (#12176) This commit allows users to pass the settings path through a command line flag (`--data-path`) when starting the daemon / cli. - It introduces `ot::Posix::PlatformSettingsGetPath()` and `ot::Posix::PlatformSettingsSetPath` to unify the method of getting / setting the settings file path. - If users doesn't not set this flag, the settings path will be default to OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH. --- src/posix/main.c | 13 +++++-- .../include/openthread/openthread-system.h | 1 + src/posix/platform/platform-posix.h | 9 +++++ src/posix/platform/settings.cpp | 9 +++-- src/posix/platform/settings_file.cpp | 23 ++++++++++--- src/posix/platform/settings_file.hpp | 34 ++++++++++++++----- src/posix/platform/system.cpp | 2 ++ src/posix/platform/tmp_storage.cpp | 10 +++--- 8 files changed, 75 insertions(+), 26 deletions(-) diff --git a/src/posix/main.c b/src/posix/main.c index c934ddab9..88e373d98 100644 --- a/src/posix/main.c +++ b/src/posix/main.c @@ -138,6 +138,7 @@ enum OT_POSIX_OPT_SHORT_MAX = 128, + OT_POSIX_OPT_DATA_PATH, OT_POSIX_OPT_RADIO_VERSION, OT_POSIX_OPT_REAL_TIME_SIGNAL, #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE @@ -146,10 +147,8 @@ enum }; static const struct option kOptions[] = { -#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE - {"tun-device", required_argument, NULL, OT_POSIX_OPT_TUN_DEVICE}, -#endif {"backbone-interface-name", required_argument, NULL, OT_POSIX_OPT_BACKBONE_INTERFACE_NAME}, + {"data-path", required_argument, NULL, OT_POSIX_OPT_DATA_PATH}, {"debug-level", required_argument, NULL, OT_POSIX_OPT_DEBUG_LEVEL}, {"dry-run", no_argument, NULL, OT_POSIX_OPT_DRY_RUN}, {"help", no_argument, NULL, OT_POSIX_OPT_HELP}, @@ -158,6 +157,9 @@ static const struct option kOptions[] = { {"radio-version", no_argument, NULL, OT_POSIX_OPT_RADIO_VERSION}, {"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL}, {"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}, +#endif {"verbose", no_argument, NULL, OT_POSIX_OPT_VERBOSE}, {0, 0, 0, 0}}; @@ -167,6 +169,7 @@ static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode) "Syntax:\n" " %s [Options] RadioURL [RadioURL]\n" "Options:\n" + " --data-path Path of directory to store data.\n" #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE " --tun-device POSIX TUN Device.\n" #endif @@ -198,6 +201,7 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig) aConfig->mPlatformConfig.mSpeedUpFactor = 1; aConfig->mLogLevel = OT_LOG_LEVEL_CRIT; aConfig->mPlatformConfig.mInterfaceName = OPENTHREAD_POSIX_CONFIG_THREAD_NETIF_DEFAULT_NAME; + aConfig->mPlatformConfig.mDataPath = OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH; #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE aConfig->mPlatformConfig.mTunDevice = NULL; #endif @@ -256,6 +260,9 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig) case OT_POSIX_OPT_RADIO_VERSION: aConfig->mPrintRadioVersion = true; break; + case OT_POSIX_OPT_DATA_PATH: + aConfig->mPlatformConfig.mDataPath = 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 a94073fde..fc4d51d8d 100644 --- a/src/posix/platform/include/openthread/openthread-system.h +++ b/src/posix/platform/include/openthread/openthread-system.h @@ -95,6 +95,7 @@ typedef struct otPlatformConfig ///< directly after initialization. CoprocessorType mCoprocessorType; ///< The co-processor type. This field is used to pass ///< the type to the app layer. + const char *mDataPath; ///< Data path. } otPlatformConfig; /** diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h index b6055ec3c..0e01c64ea 100644 --- a/src/posix/platform/platform-posix.h +++ b/src/posix/platform/platform-posix.h @@ -170,6 +170,15 @@ void platformRadioProcess(otInstance *aInstance, const otSysMainloopContext *aCo */ void platformRandomInit(void); +/** + * Initializes the platform settings. + * + * @note This function is called before OpenThread instance is created. + * + * @param[in] aDataPath The data path to store setting files. + */ +void platformSettingsInit(const char *aDataPath); + /** * Initializes the logging service used by OpenThread. * diff --git a/src/posix/platform/settings.cpp b/src/posix/platform/settings.cpp index 8faef601d..3ae37f1bf 100644 --- a/src/posix/platform/settings.cpp +++ b/src/posix/platform/settings.cpp @@ -82,16 +82,15 @@ exit: static otError settingsFileInit(otInstance *aInstance) { - static constexpr size_t kMaxFileBaseNameSize = 32; - char fileBaseName[kMaxFileBaseNameSize]; - const char *offset = getenv("PORT_OFFSET"); - uint64_t nodeId; + char fileBaseName[ot::Posix::SettingsFile::kMaxFileBaseNameSize]; + 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); - VerifyOrDie(strlen(fileBaseName) < kMaxFileBaseNameSize, OT_EXIT_FAILURE); + 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 b885b6586..008c917e1 100644 --- a/src/posix/platform/settings_file.cpp +++ b/src/posix/platform/settings_file.cpp @@ -46,16 +46,27 @@ #include "common/debug.hpp" #include "posix/platform/settings_file.hpp" +void platformSettingsInit(const char *aDataPath) { ot::Posix::SettingsFile::SetSettingsPath(aDataPath); } + namespace ot { namespace Posix { +char SettingsFile::sSettingsPath[] = OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH; + +const char *SettingsFile::GetSettingsPath(void) { return sSettingsPath; } +void SettingsFile::SetSettingsPath(const char *aSettingsPath) +{ + snprintf(sSettingsPath, sizeof(sSettingsPath), "%s", aSettingsPath); +} + otError SettingsFile::Init(const char *aSettingsFileBaseName) { otError error = OT_ERROR_NONE; - const char *directory = OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH; + const char *directory = GetSettingsPath(); - OT_ASSERT((aSettingsFileBaseName != nullptr) && (strlen(aSettingsFileBaseName) < kMaxFileBaseNameSize)); - strncpy(mSettingFileBaseName, aSettingsFileBaseName, sizeof(mSettingFileBaseName) - 1); + OT_ASSERT(strlen(directory) < kMaxFileBasePathNameSize); + OT_ASSERT((aSettingsFileBaseName != nullptr) && strlen(aSettingsFileBaseName) < kMaxFileBaseNameSize); + snprintf(mSettingsFileFullPathName, sizeof(mSettingsFileFullPathName), "%s/%s", directory, aSettingsFileBaseName); { struct stat st; @@ -306,8 +317,10 @@ void SettingsFile::Wipe(void) { VerifyOrDie(0 == ftruncate(mSettingsFd, 0), OT_E void SettingsFile::GetSettingsFilePath(char aFileName[kMaxFilePathSize], bool aSwap) { - snprintf(aFileName, kMaxFilePathSize, OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH "/%s.%s", mSettingFileBaseName, - (aSwap ? "Swap" : "data")); + int length; + + length = snprintf(aFileName, kMaxFilePathSize, "%s.%s", mSettingsFileFullPathName, (aSwap ? "Swap" : "data")); + VerifyOrDie(length > 0 && static_cast(length) < kMaxFilePathSize, OT_EXIT_FAILURE); } int SettingsFile::SwapOpen(void) diff --git a/src/posix/platform/settings_file.hpp b/src/posix/platform/settings_file.hpp index 2cb50351a..ffa8b373a 100644 --- a/src/posix/platform/settings_file.hpp +++ b/src/posix/platform/settings_file.hpp @@ -29,6 +29,8 @@ #ifndef OT_POSIX_PLATFORM_SETTINGS_FILE_HPP_ #define OT_POSIX_PLATFORM_SETTINGS_FILE_HPP_ +#include + #include "openthread-posix-config.h" #include "platform-posix.h" @@ -38,6 +40,22 @@ namespace Posix { class SettingsFile { public: + static constexpr size_t kMaxFileBaseNameSize = 32; + + /** + * Gets the path to store setting files. + * + * @returns Path for setting files. + */ + static const char *GetSettingsPath(void); + + /** + * Sets the path to store setting files. + * + * @param[in] aSettingsPath Path for setting files. + */ + static void SetSettingsPath(const char *aSettingsPath); + SettingsFile(void) : mSettingsFd(-1) { @@ -107,12 +125,11 @@ public: void Wipe(void); private: - static const size_t kMaxFileDirectorySize = sizeof(OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH); - static const size_t kSlashLength = 1; - static const size_t kMaxFileBaseNameSize = 64; - static const size_t kMaxFileExtensionLength = 5; ///< The length of `.Swap` or `.data`. - static const size_t kMaxFilePathSize = - kMaxFileDirectorySize + kSlashLength + kMaxFileBaseNameSize + kMaxFileExtensionLength; + static constexpr size_t kSlashLength = 1; + static constexpr size_t kMaxFileExtensionLength = 5; ///< The length of `.Swap` or `.data`. + static constexpr size_t kMaxFileFullPathNameSize = PATH_MAX - kMaxFileExtensionLength; + static constexpr size_t kMaxFileBasePathNameSize = kMaxFileFullPathNameSize - kSlashLength - kMaxFileBaseNameSize; + static constexpr size_t kMaxFilePathSize = PATH_MAX; otError Delete(uint16_t aKey, int aIndex, int *aSwapFd); void GetSettingsFilePath(char aFileName[kMaxFilePathSize], bool aSwap); @@ -121,8 +138,9 @@ private: void SwapPersist(int aFd); void SwapDiscard(int aFd); - char mSettingFileBaseName[kMaxFileBaseNameSize]; - int mSettingsFd; + static char sSettingsPath[kMaxFileBasePathNameSize]; + char mSettingsFileFullPathName[kMaxFileFullPathNameSize]; + int mSettingsFd; }; } // namespace Posix diff --git a/src/posix/platform/system.cpp b/src/posix/platform/system.cpp index 799bc4d79..9dfc22d1b 100644 --- a/src/posix/platform/system.cpp +++ b/src/posix/platform/system.cpp @@ -180,6 +180,8 @@ void platformInitNcpMode(otPlatformConfig *aPlatformConfig) void platformInit(otPlatformConfig *aPlatformConfig) { + platformSettingsInit(aPlatformConfig->mDataPath); + #if OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE platformBacktraceInit(); #endif diff --git a/src/posix/platform/tmp_storage.cpp b/src/posix/platform/tmp_storage.cpp index 5f07162dc..ab228821b 100644 --- a/src/posix/platform/tmp_storage.cpp +++ b/src/posix/platform/tmp_storage.cpp @@ -49,6 +49,7 @@ #include "common/code_utils.hpp" #include "common/debug.hpp" #include "common/encoding.hpp" +#include "posix/platform/settings_file.hpp" #if OPENTHREAD_POSIX_CONFIG_TMP_STORAGE_ENABLE namespace ot { @@ -94,16 +95,15 @@ otError TmpStorage::RestoreRadioSpinelMetrics(otRadioSpinelMetrics &aMetrics) otError TmpStorage::SettingsFileInit(void) { - static constexpr size_t kMaxFileBaseNameSize = 32; - char fileBaseName[kMaxFileBaseNameSize]; - const char *offset = getenv("PORT_OFFSET"); - uint64_t eui64; + char fileBaseName[SettingsFile::kMaxFileBaseNameSize]; + const char *offset = getenv("PORT_OFFSET"); + uint64_t eui64; otPlatRadioGetIeeeEui64(gInstance, reinterpret_cast(&eui64)); eui64 = ot::BigEndian::HostSwap64(eui64); snprintf(fileBaseName, sizeof(fileBaseName), "%s_%" PRIx64 "-tmp", ((offset == nullptr) ? "0" : offset), eui64); - VerifyOrDie(strlen(fileBaseName) < kMaxFileBaseNameSize, OT_EXIT_FAILURE); + VerifyOrDie(strlen(fileBaseName) < SettingsFile::kMaxFileBaseNameSize, OT_EXIT_FAILURE); return mStorageFile.Init(fileBaseName); }