From 7dd7a5d7d682505826031dca018560615e0a8789 Mon Sep 17 00:00:00 2001 From: Li Cao Date: Thu, 14 Oct 2021 01:39:30 +0800 Subject: [PATCH] [posix] minimize system initialization when dry-run option is set (#7031) This commit adds a member mDryRun in otPlatformConfig, allowing the app to initialize in 'DryRun' mode. In this mode, many modules won't be initialized. For example, the settings file and the tun device. Background: The otbr-agent provides a way to query the RCP version in a single run which we call as 'DryRun'. During this process, the full posix daemon initialization will be done (including initialization of the settings file, access the tun device, create the sock file, etc). This will cause such problem - In production, otbr-agent usually runs as a service in some non-root user and is granted with the capability and access it requires. But otbr-agent could sometimes also run by other users to query the RCP version. For example, developers do that from the console with the root user. In such case, otbr-agent will create some files owned by the root user first. And then when the service tries to start (with a non-root user), otbr-agent will find that it doesn't have enough permission to open the file. So in this commit, we try to prevent otbr-agent from touching any files and other permission related stuffs if the DryRun option is set. However it still needs to access the radio device (for example, the 'spi') since it needs to get the radio version. But accessing the radio device with the root user doesn't affect the upcoming usage by other non-root users. --- src/posix/main.c | 5 +-- .../include/openthread/openthread-system.h | 2 + src/posix/platform/settings.cpp | 12 ++++++ src/posix/platform/system.cpp | 14 +++++++ src/posix/platform/system.hpp | 41 +++++++++++++++++++ 5 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 src/posix/platform/system.hpp diff --git a/src/posix/main.c b/src/posix/main.c index b6ea5b96b..ebecb4777 100644 --- a/src/posix/main.c +++ b/src/posix/main.c @@ -129,7 +129,6 @@ typedef struct PosixConfig { otPlatformConfig mPlatformConfig; ///< Platform configuration. otLogLevel mLogLevel; ///< Debug level of logging. - bool mIsDryRun; ///< Dry run. bool mPrintRadioVersion; ///< Whether to print radio firmware version. bool mIsVerbose; ///< Whether to print log to stderr. } PosixConfig; @@ -232,7 +231,7 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig) aConfig->mPlatformConfig.mBackboneInterfaceName = optarg; break; case OT_POSIX_OPT_DRY_RUN: - aConfig->mIsDryRun = true; + aConfig->mPlatformConfig.mDryRun = true; break; case OT_POSIX_OPT_TIME_SPEED: { @@ -308,7 +307,7 @@ static otInstance *InitInstance(PosixConfig *aConfig) syslog(LOG_INFO, "RCP version: %s", otPlatRadioGetVersionString(instance)); } - if (aConfig->mIsDryRun) + if (aConfig->mPlatformConfig.mDryRun) { exit(OT_EXIT_SUCCESS); } diff --git a/src/posix/platform/include/openthread/openthread-system.h b/src/posix/platform/include/openthread/openthread-system.h index 1170bda44..7b2a1f2a7 100644 --- a/src/posix/platform/include/openthread/openthread-system.h +++ b/src/posix/platform/include/openthread/openthread-system.h @@ -78,6 +78,8 @@ typedef struct otPlatformConfig uint8_t mRadioUrlNum; ///< Number of Radio URLs. int mRealTimeSignal; ///< The real-time signal for microsecond timer. uint32_t mSpeedUpFactor; ///< Speed up factor. + bool mDryRun; ///< If 'DryRun' is set, the posix daemon will exit + ///< directly after initialization. } otPlatformConfig; /** diff --git a/src/posix/platform/settings.cpp b/src/posix/platform/settings.cpp index c2750ffe4..eac81c235 100644 --- a/src/posix/platform/settings.cpp +++ b/src/posix/platform/settings.cpp @@ -54,6 +54,8 @@ #include "common/code_utils.hpp" #include "common/encoding.hpp" +#include "system.hpp" + static const size_t kMaxFileNameSize = sizeof(OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH) + 32; static int sSettingsFd = -1; @@ -168,6 +170,9 @@ void otPlatSettingsInit(otInstance *aInstance) { otError error = OT_ERROR_NONE; + // Don't touch the settings file the system runs in dry-run mode. + VerifyOrExit(!IsSystemDryRun()); + #if OPENTHREAD_POSIX_CONFIG_SECURE_SETTINGS_ENABLE otPosixSecureSettingsInit(aInstance); #endif @@ -233,6 +238,7 @@ otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint const off_t size = lseek(sSettingsFd, 0, SEEK_END); off_t offset = lseek(sSettingsFd, 0, SEEK_SET); + VerifyOrExit(!IsSystemDryRun()); #if OPENTHREAD_POSIX_CONFIG_SECURE_SETTINGS_ENABLE if (isCriticalKey(aKey)) { @@ -494,6 +500,12 @@ void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) memset(aIeeeEui64, 0, sizeof(uint64_t)); } +// Stub implementation for testing +bool IsSystemDryRun(void) +{ + return false; +} + int main() { otInstance *instance = nullptr; diff --git a/src/posix/platform/system.cpp b/src/posix/platform/system.cpp index 26b340166..8b78f9be5 100644 --- a/src/posix/platform/system.cpp +++ b/src/posix/platform/system.cpp @@ -55,6 +55,7 @@ #include "posix/platform/udp.hpp" otInstance *gInstance = nullptr; +bool gDryRun = false; #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE || OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE static void processStateChange(otChangedFlags aFlags, void *aContext) @@ -122,6 +123,10 @@ void platformInit(otPlatformConfig *aPlatformConfig) { platformAlarmInit(aPlatformConfig->mSpeedUpFactor, aPlatformConfig->mRealTimeSignal); platformRadioInit(get802154RadioUrl(aPlatformConfig)); + + // For Dry-Run option, only init the radio. + VerifyOrExit(!aPlatformConfig->mDryRun); + #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE platformTrelInit(getTrelRadioUrl(aPlatformConfig)); #endif @@ -148,6 +153,9 @@ void platformInit(otPlatformConfig *aPlatformConfig) ot::Posix::Udp::Get().Init(aPlatformConfig->mInterfaceName); #endif #endif + +exit: + return; } void platformSetUp(void) @@ -183,6 +191,7 @@ otInstance *otSysInit(otPlatformConfig *aPlatformConfig) platformInit(aPlatformConfig); + gDryRun = aPlatformConfig->mDryRun; gInstance = otInstanceInitSingle(); OT_ASSERT(gInstance != nullptr); @@ -377,3 +386,8 @@ void otPlatOtnsStatus(const char *aStatus) } #endif + +bool IsSystemDryRun(void) +{ + return gDryRun; +} diff --git a/src/posix/platform/system.hpp b/src/posix/platform/system.hpp new file mode 100644 index 000000000..871226a43 --- /dev/null +++ b/src/posix/platform/system.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @brief + * This file includes posix-specific system methods. + */ + +/* + * This method returns if the system will run in dry-run mode. + * + * @returns If the system runs in dry-run mode. + * + */ +bool IsSystemDryRun(void);