• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "updater/hardware_fault_retry.h"
17 #include <unistd.h>
18 #include "init_reboot.h"
19 #include "log/log.h"
20 #include "misc_info/misc_info.h"
21 #include "updater/updater.h"
22 #include "updater/updater_const.h"
23 #include "utils.h"
24 #include "securec.h"
25 
26 namespace Updater {
GetInstance()27 HardwareFaultRetry &HardwareFaultRetry::GetInstance()
28 {
29     static HardwareFaultRetry instance;
30     return instance;
31 }
32 
HardwareFaultRetry()33 HardwareFaultRetry::HardwareFaultRetry()
34 {
35     RetryFunc rebootFunc = [this]() {
36                                 return this->RebootRetry();
37                             };
38     RegisterFunc(VERIFY_FAILED_REBOOT, rebootFunc);
39     RegisterFunc(IO_FAILED_REBOOT, rebootFunc);
40     RegisterFunc(BLOCK_UPDATE_FAILED_REBOOT, rebootFunc);
41 }
42 
RegisterFunc(const std::string & faultInfo,RetryFunc func)43 void HardwareFaultRetry::RegisterFunc(const std::string &faultInfo, RetryFunc func)
44 {
45     if (!retryMap_.emplace(faultInfo, func).second) {
46         LOG(ERROR) << "emplace: " << faultInfo.c_str() << " fail";
47     }
48 }
49 
RegisterDefaultFunc(const std::string & faultInfo)50 void HardwareFaultRetry::RegisterDefaultFunc(const std::string &faultInfo)
51 {
52     if (!retryMap_.emplace(faultInfo, [this]() {
53                                 return this->RebootRetry();
54                             }).second) {
55         LOG(ERROR) << "emplace: " << faultInfo.c_str() << " fail";
56     }
57 }
58 
RemoveFunc(const std::string & faultInfo)59 void HardwareFaultRetry::RemoveFunc(const std::string &faultInfo)
60 {
61     if (retryMap_.erase(faultInfo) == 0) {
62         LOG(ERROR) << "erase " << faultInfo.c_str() << " fail";
63     }
64 }
65 
DoRetryAction()66 void HardwareFaultRetry::DoRetryAction()
67 {
68     auto it = retryMap_.find(faultInfo_);
69     if (it == retryMap_.end() || it->second == nullptr) {
70         LOG(ERROR) << "GetRepair func for: " << faultInfo_.c_str() << " fail";
71         return;
72     }
73     return (it->second)();
74 }
75 
SetFaultInfo(const std::string & faultInfo)76 void HardwareFaultRetry::SetFaultInfo(const std::string &faultInfo)
77 {
78     faultInfo_ = faultInfo;
79 }
80 
SetRetryCount(const uint32_t count)81 void HardwareFaultRetry::SetRetryCount(const uint32_t count)
82 {
83     retryCount_ = count;
84 }
85 
SetEffectiveValue(bool value)86 void HardwareFaultRetry::SetEffectiveValue(bool value)
87 {
88     effective_ = value;
89 }
90 
SetRebootCmd(const std::string & rebootCmd)91 void HardwareFaultRetry::SetRebootCmd(const std::string &rebootCmd)
92 {
93     rebootCmd_ = rebootCmd;
94 }
95 
IsRetry(void)96 bool HardwareFaultRetry::IsRetry(void)
97 {
98     return isRetry_;
99 }
100 
RebootRetry()101 void HardwareFaultRetry::RebootRetry()
102 {
103     if (!effective_) {
104         LOG(WARNING) << "Special scenarios do not take effect, not need retry.";
105         return;
106     }
107     if (retryCount_ >= MAX_RETRY_COUNT) {
108         LOG(INFO) << "retry more than 3 times, no need retry";
109         return;
110     }
111     LOG(INFO) << "enter into reboot retry";
112     Utils::AddUpdateInfoToMisc("retry_count", retryCount_ + 1);
113     Utils::SetFaultInfoToMisc(faultInfo_);
114     isRetry_ = true;
115 
116     PostUpdater(false);
117     sync();
118 #ifndef UPDATER_UT
119     if (rebootCmd_.empty()) {
120         DoReboot("updater:Updater fault retry");
121     } else {
122         DoReboot(rebootCmd_.c_str());
123     }
124     while (true) {
125         pause();
126     }
127 #endif
128 }
129 } // Updater
130