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