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