xref: /aosp_15_r20/system/update_engine/update_boot_flags_action.cc (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
1*5a923131SAndroid Build Coastguard Worker //
2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2018 The Android Open Source Project
3*5a923131SAndroid Build Coastguard Worker //
4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*5a923131SAndroid Build Coastguard Worker //
8*5a923131SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
9*5a923131SAndroid Build Coastguard Worker //
10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*5a923131SAndroid Build Coastguard Worker // limitations under the License.
15*5a923131SAndroid Build Coastguard Worker //
16*5a923131SAndroid Build Coastguard Worker 
17*5a923131SAndroid Build Coastguard Worker #include "update_engine/update_boot_flags_action.h"
18*5a923131SAndroid Build Coastguard Worker 
19*5a923131SAndroid Build Coastguard Worker #include <base/bind.h>
20*5a923131SAndroid Build Coastguard Worker #include <base/logging.h>
21*5a923131SAndroid Build Coastguard Worker 
22*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/boot_control.h"
23*5a923131SAndroid Build Coastguard Worker 
24*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine {
25*5a923131SAndroid Build Coastguard Worker 
26*5a923131SAndroid Build Coastguard Worker bool UpdateBootFlagsAction::updated_boot_flags_ = false;
27*5a923131SAndroid Build Coastguard Worker bool UpdateBootFlagsAction::is_running_ = false;
28*5a923131SAndroid Build Coastguard Worker 
PerformAction()29*5a923131SAndroid Build Coastguard Worker void UpdateBootFlagsAction::PerformAction() {
30*5a923131SAndroid Build Coastguard Worker   if (is_running_) {
31*5a923131SAndroid Build Coastguard Worker     LOG(INFO) << "Update boot flags running, nothing to do.";
32*5a923131SAndroid Build Coastguard Worker     processor_->ActionComplete(this, ErrorCode::kSuccess);
33*5a923131SAndroid Build Coastguard Worker     return;
34*5a923131SAndroid Build Coastguard Worker   }
35*5a923131SAndroid Build Coastguard Worker   if (updated_boot_flags_) {
36*5a923131SAndroid Build Coastguard Worker     LOG(INFO) << "Already updated boot flags. Skipping.";
37*5a923131SAndroid Build Coastguard Worker     processor_->ActionComplete(this, ErrorCode::kSuccess);
38*5a923131SAndroid Build Coastguard Worker     return;
39*5a923131SAndroid Build Coastguard Worker   }
40*5a923131SAndroid Build Coastguard Worker 
41*5a923131SAndroid Build Coastguard Worker   // This is purely best effort. Failures should be logged by Subprocess. Run
42*5a923131SAndroid Build Coastguard Worker   // the script asynchronously to avoid blocking the event loop regardless of
43*5a923131SAndroid Build Coastguard Worker   // the script runtime.
44*5a923131SAndroid Build Coastguard Worker   is_running_ = true;
45*5a923131SAndroid Build Coastguard Worker   LOG(INFO) << "Marking booted slot as good.";
46*5a923131SAndroid Build Coastguard Worker   if (!boot_control_->MarkBootSuccessfulAsync(
47*5a923131SAndroid Build Coastguard Worker           base::Bind(&UpdateBootFlagsAction::CompleteUpdateBootFlags,
48*5a923131SAndroid Build Coastguard Worker                      base::Unretained(this)))) {
49*5a923131SAndroid Build Coastguard Worker     CompleteUpdateBootFlags(false);
50*5a923131SAndroid Build Coastguard Worker   }
51*5a923131SAndroid Build Coastguard Worker }
52*5a923131SAndroid Build Coastguard Worker 
TerminateProcessing()53*5a923131SAndroid Build Coastguard Worker void UpdateBootFlagsAction::TerminateProcessing() {
54*5a923131SAndroid Build Coastguard Worker   is_running_ = false;
55*5a923131SAndroid Build Coastguard Worker }
56*5a923131SAndroid Build Coastguard Worker 
CompleteUpdateBootFlags(bool successful)57*5a923131SAndroid Build Coastguard Worker void UpdateBootFlagsAction::CompleteUpdateBootFlags(bool successful) {
58*5a923131SAndroid Build Coastguard Worker   if (!successful) {
59*5a923131SAndroid Build Coastguard Worker     // We ignore the failure for now because if the updating boot flags is flaky
60*5a923131SAndroid Build Coastguard Worker     // or has a bug in a specific release, then blocking the update can cause
61*5a923131SAndroid Build Coastguard Worker     // devices to stay behind even though we could have updated the system and
62*5a923131SAndroid Build Coastguard Worker     // fixed the issue regardless of this failure.
63*5a923131SAndroid Build Coastguard Worker     //
64*5a923131SAndroid Build Coastguard Worker     // TODO(ahassani): Add new error code metric for kUpdateBootFlagsFailed.
65*5a923131SAndroid Build Coastguard Worker     LOG(ERROR) << "Updating boot flags failed, but ignoring its failure.";
66*5a923131SAndroid Build Coastguard Worker   }
67*5a923131SAndroid Build Coastguard Worker 
68*5a923131SAndroid Build Coastguard Worker   // As the callback to MarkBootSuccessfulAsync, this function can still be
69*5a923131SAndroid Build Coastguard Worker   // called even after the current UpdateBootFlagsAction object get destroyed by
70*5a923131SAndroid Build Coastguard Worker   // the action processor. In this case, check the value of the static variable
71*5a923131SAndroid Build Coastguard Worker   // |is_running_| and skip executing the callback function.
72*5a923131SAndroid Build Coastguard Worker   if (!is_running_) {
73*5a923131SAndroid Build Coastguard Worker     LOG(INFO) << "UpdateBootFlagsAction is no longer running.";
74*5a923131SAndroid Build Coastguard Worker     return;
75*5a923131SAndroid Build Coastguard Worker   }
76*5a923131SAndroid Build Coastguard Worker 
77*5a923131SAndroid Build Coastguard Worker   is_running_ = false;
78*5a923131SAndroid Build Coastguard Worker 
79*5a923131SAndroid Build Coastguard Worker   updated_boot_flags_ = true;
80*5a923131SAndroid Build Coastguard Worker   processor_->ActionComplete(this, ErrorCode::kSuccess);
81*5a923131SAndroid Build Coastguard Worker }
82*5a923131SAndroid Build Coastguard Worker 
83*5a923131SAndroid Build Coastguard Worker }  // namespace chromeos_update_engine
84