blob: 383dc515f32ed4289c27ed8a1534069b10639ee3 [file] [log] [blame]
Lei YU9b21efc2019-02-21 15:52:53 +08001#include "activation_ubi.hpp"
2
3#include "item_updater.hpp"
4#include "serialize.hpp"
5
6#include <experimental/filesystem>
Jayashankar Padath4d3d9122019-07-24 16:46:22 +05307#include <phosphor-logging/log.hpp>
Lei YU9b21efc2019-02-21 15:52:53 +08008
9namespace openpower
10{
11namespace software
12{
13namespace updater
14{
15namespace fs = std::experimental::filesystem;
16namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
Jayashankar Padath4d3d9122019-07-24 16:46:22 +053017using namespace phosphor::logging;
Lei YU9b21efc2019-02-21 15:52:53 +080018
19uint8_t RedundancyPriorityUbi::priority(uint8_t value)
20{
21 storeToFile(parent.versionId, value);
22 return RedundancyPriority::priority(value);
23}
24
25auto ActivationUbi::activation(Activations value) -> Activations
26{
27
28 if (value != softwareServer::Activation::Activations::Active)
29 {
30 redundancyPriority.reset(nullptr);
31 }
32
33 if (value == softwareServer::Activation::Activations::Activating)
34 {
35 parent.freeSpace();
36 softwareServer::Activation::activation(value);
37
38 if (ubiVolumesCreated == false)
39 {
40 // Enable systemd signals
41 subscribeToSystemdSignals();
42
43#ifdef WANT_SIGNATURE_VERIFY
44 // Validate the signed image.
Lei YU2b2d2292019-03-18 15:22:56 +080045 if (!validateSignature(squashFSImage))
Lei YU9b21efc2019-02-21 15:52:53 +080046 {
47 // Cleanup
48 activationBlocksTransition.reset(nullptr);
49 activationProgress.reset(nullptr);
50
51 return softwareServer::Activation::activation(
52 softwareServer::Activation::Activations::Failed);
53 }
54#endif
55 startActivation();
56 return softwareServer::Activation::activation(value);
57 }
58 else if (ubiVolumesCreated == true)
59 {
60 // Only when the squashfs image is finished loading AND the RW
61 // volumes have been created do we proceed with activation. To
62 // verify that this happened, we check for the mount dirs PNOR_PRSV
63 // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
64
65 if ((fs::is_directory(PNOR_PRSV)) &&
66 (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
67 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
68 {
69 finishActivation();
Jayashankar Padath4d3d9122019-07-24 16:46:22 +053070 if (Activation::checkApplyTimeImmediate())
71 {
72 log<level::INFO>("Image Active. ApplyTime is immediate, "
73 "rebooting Host.");
74 Activation::rebootHost();
75 }
Lei YU9b21efc2019-02-21 15:52:53 +080076 return softwareServer::Activation::activation(
77 softwareServer::Activation::Activations::Active);
78 }
79 else
80 {
81 activationBlocksTransition.reset(nullptr);
82 activationProgress.reset(nullptr);
83 return softwareServer::Activation::activation(
84 softwareServer::Activation::Activations::Failed);
85 }
86 }
87 }
88 else
89 {
90 activationBlocksTransition.reset(nullptr);
91 activationProgress.reset(nullptr);
92 }
93
94 return softwareServer::Activation::activation(value);
95}
96
97auto ActivationUbi::requestedActivation(RequestedActivations value)
98 -> RequestedActivations
99{
100 ubiVolumesCreated = false;
101 return Activation::requestedActivation(value);
102}
103
104void ActivationUbi::startActivation()
105{
106 // Since the squashfs image has not yet been loaded to pnor and the
107 // RW volumes have not yet been created, we need to start the
108 // service files for each of those actions.
109
110 if (!activationProgress)
111 {
112 activationProgress = std::make_unique<ActivationProgress>(bus, path);
113 }
114
115 if (!activationBlocksTransition)
116 {
117 activationBlocksTransition =
118 std::make_unique<ActivationBlocksTransition>(bus, path);
119 }
120
121 constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
122 auto ubimountServiceFile =
123 std::string(ubimountService) + versionId + ".service";
124 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
125 SYSTEMD_INTERFACE, "StartUnit");
126 method.append(ubimountServiceFile, "replace");
127 bus.call_noreply(method);
128
129 activationProgress->progress(10);
130}
131
132void ActivationUbi::unitStateChange(sdbusplus::message::message& msg)
133{
134 uint32_t newStateID{};
135 sdbusplus::message::object_path newStateObjPath;
136 std::string newStateUnit{};
137 std::string newStateResult{};
138
139 // Read the msg and populate each variable
140 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
141
142 auto ubimountServiceFile =
143 "obmc-flash-bios-ubimount@" + versionId + ".service";
144
145 if (newStateUnit == ubimountServiceFile && newStateResult == "done")
146 {
147 ubiVolumesCreated = true;
148 activationProgress->progress(activationProgress->progress() + 50);
149 }
150
151 if (ubiVolumesCreated)
152 {
153 activation(softwareServer::Activation::Activations::Activating);
154 }
155
156 if ((newStateUnit == ubimountServiceFile) &&
157 (newStateResult == "failed" || newStateResult == "dependency"))
158 {
159 activation(softwareServer::Activation::Activations::Failed);
160 }
161
162 return;
163}
164
165void ActivationUbi::finishActivation()
166{
167 activationProgress->progress(90);
168
169 // Set Redundancy Priority before setting to Active
170 if (!redundancyPriority)
171 {
172 redundancyPriority =
173 std::make_unique<RedundancyPriorityUbi>(bus, path, *this, 0);
174 }
175
176 activationProgress->progress(100);
177
178 activationBlocksTransition.reset(nullptr);
179 activationProgress.reset(nullptr);
180
181 ubiVolumesCreated = false;
182 unsubscribeFromSystemdSignals();
183 // Remove version object from image manager
184 deleteImageManagerObject();
185 // Create active association
186 parent.createActiveAssociation(path);
Adriana Kobylak3c810372020-07-15 16:47:03 -0500187 // Create updateable association as this
188 // can be re-programmed.
189 parent.createUpdateableAssociation(path);
Lei YU9b21efc2019-02-21 15:52:53 +0800190}
191
192} // namespace updater
193} // namespace software
194} // namespace openpower