blob: 350bf5ad15ef63f5d336015d8a71a7b31c8b1ab5 [file] [log] [blame]
Adriana Kobylak55f9e832017-05-14 16:13:00 -05001#include <experimental/filesystem>
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -05002#include "activation.hpp"
Adriana Kobylak692b5552017-04-17 14:02:58 -05003#include "config.h"
Saqib Khan81bac882017-06-08 12:17:01 -05004#include "item_updater.hpp"
Michael Tritz60bc20f2017-07-29 23:32:21 -05005#include "serialize.hpp"
Saqib Khan7f80e0b2017-10-22 11:29:07 -05006#include <phosphor-logging/log.hpp>
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -05007
8namespace openpower
9{
10namespace software
11{
12namespace updater
13{
14
Adriana Kobylak55f9e832017-05-14 16:13:00 -050015namespace fs = std::experimental::filesystem;
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050016namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
17
Saqib Khan7f80e0b2017-10-22 11:29:07 -050018using namespace phosphor::logging;
19
Adriana Kobylak70dcb632018-02-27 15:46:52 -060020constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
21constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
Michael Tritz9d25b602017-06-14 14:41:43 -050022
23void Activation::subscribeToSystemdSignals()
24{
Adriana Kobylak70dcb632018-02-27 15:46:52 -060025 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
26 SYSTEMD_INTERFACE, "Subscribe");
Michael Tritz9d25b602017-06-14 14:41:43 -050027 this->bus.call_noreply(method);
28
29 return;
30}
31
Michael Tritz1cb127f2017-07-26 15:40:38 -050032void Activation::unsubscribeFromSystemdSignals()
33{
Adriana Kobylak70dcb632018-02-27 15:46:52 -060034 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
35 SYSTEMD_INTERFACE, "Unsubscribe");
Michael Tritz1cb127f2017-07-26 15:40:38 -050036 this->bus.call_noreply(method);
37
38 return;
39}
40
Michael Tritz1cb127f2017-07-26 15:40:38 -050041void Activation::startActivation()
42{
43 // Since the squashfs image has not yet been loaded to pnor and the
44 // RW volumes have not yet been created, we need to start the
45 // service files for each of those actions.
46
47 if (!activationProgress)
48 {
Adriana Kobylak70dcb632018-02-27 15:46:52 -060049 activationProgress = std::make_unique<ActivationProgress>(bus, path);
Michael Tritz1cb127f2017-07-26 15:40:38 -050050 }
51
52 if (!activationBlocksTransition)
53 {
54 activationBlocksTransition =
Adriana Kobylak70dcb632018-02-27 15:46:52 -060055 std::make_unique<ActivationBlocksTransition>(bus, path);
Michael Tritz1cb127f2017-07-26 15:40:38 -050056 }
57
Michael Tritz1cb127f2017-07-26 15:40:38 -050058 constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
Adriana Kobylak70dcb632018-02-27 15:46:52 -060059 auto ubimountServiceFile =
60 std::string(ubimountService) + versionId + ".service";
61 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
62 SYSTEMD_INTERFACE, "StartUnit");
Michael Tritz1cb127f2017-07-26 15:40:38 -050063 method.append(ubimountServiceFile, "replace");
64 bus.call_noreply(method);
65
66 activationProgress->progress(10);
67}
68
69void Activation::finishActivation()
70{
71 activationProgress->progress(90);
Michael Tritz1cb127f2017-07-26 15:40:38 -050072
73 // Set Redundancy Priority before setting to Active
74 if (!redundancyPriority)
75 {
Adriana Kobylak70dcb632018-02-27 15:46:52 -060076 redundancyPriority =
77 std::make_unique<RedundancyPriority>(bus, path, *this, 0);
Michael Tritz1cb127f2017-07-26 15:40:38 -050078 }
79
80 activationProgress->progress(100);
81
82 activationBlocksTransition.reset(nullptr);
83 activationProgress.reset(nullptr);
84
Saqib Khan1e0aa5c2017-08-31 11:04:17 -050085 ubiVolumesCreated = false;
Michael Tritz1cb127f2017-07-26 15:40:38 -050086 Activation::unsubscribeFromSystemdSignals();
Saqib Khan7f80e0b2017-10-22 11:29:07 -050087 // Remove version object from image manager
88 Activation::deleteImageManagerObject();
Gunnar Mills9741cd12017-08-28 15:09:00 -050089 // Create active association
90 parent.createActiveAssociation(path);
Michael Tritz1cb127f2017-07-26 15:40:38 -050091}
92
Adriana Kobylak70dcb632018-02-27 15:46:52 -060093auto Activation::activation(Activations value) -> Activations
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -050094{
Saqib Khan942df8a2017-06-01 14:09:27 -050095
96 if (value != softwareServer::Activation::Activations::Active)
97 {
98 redundancyPriority.reset(nullptr);
99 }
100
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500101 if (value == softwareServer::Activation::Activations::Activating)
102 {
Saqib Khan2cbfa032017-08-17 14:52:37 -0500103 parent.freeSpace();
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500104 softwareServer::Activation::activation(value);
105
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500106 if (ubiVolumesCreated == false)
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500107 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500108 Activation::startActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500109 return softwareServer::Activation::activation(value);
110 }
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500111 else if (ubiVolumesCreated == true)
Michael Tritz9d25b602017-06-14 14:41:43 -0500112 {
113 // Only when the squashfs image is finished loading AND the RW
Michael Tritz1cb127f2017-07-26 15:40:38 -0500114 // volumes have been created do we proceed with activation. To
115 // verify that this happened, we check for the mount dirs PNOR_PRSV
116 // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
Michael Tritz9d25b602017-06-14 14:41:43 -0500117
Michael Tritz9d25b602017-06-14 14:41:43 -0500118 if ((fs::is_directory(PNOR_PRSV)) &&
119 (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
120 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
121 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500122 Activation::finishActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500123 return softwareServer::Activation::activation(
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600124 softwareServer::Activation::Activations::Active);
Michael Tritz9d25b602017-06-14 14:41:43 -0500125 }
126 else
127 {
Saqib Khancb9df4e2017-06-26 11:06:07 -0500128 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500129 activationProgress.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500130 return softwareServer::Activation::activation(
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600131 softwareServer::Activation::Activations::Failed);
Michael Tritz9d25b602017-06-14 14:41:43 -0500132 }
Adriana Kobylak55f9e832017-05-14 16:13:00 -0500133 }
Adriana Kobylak692b5552017-04-17 14:02:58 -0500134 }
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500135 else
136 {
137 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500138 activationProgress.reset(nullptr);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500139 }
Michael Tritz1cb127f2017-07-26 15:40:38 -0500140
141 return softwareServer::Activation::activation(value);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500142}
143
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600144auto Activation::requestedActivation(RequestedActivations value)
145 -> RequestedActivations
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500146{
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500147 ubiVolumesCreated = false;
Michael Tritz9d25b602017-06-14 14:41:43 -0500148
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500149 if ((value == softwareServer::Activation::RequestedActivations::Active) &&
150 (softwareServer::Activation::requestedActivation() !=
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600151 softwareServer::Activation::RequestedActivations::Active))
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500152 {
153 if ((softwareServer::Activation::activation() ==
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600154 softwareServer::Activation::Activations::Ready) ||
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500155 (softwareServer::Activation::activation() ==
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600156 softwareServer::Activation::Activations::Failed))
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500157 {
158 Activation::activation(
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600159 softwareServer::Activation::Activations::Activating);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500160 }
161 }
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500162 return softwareServer::Activation::requestedActivation(value);
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500163}
164
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500165void Activation::deleteImageManagerObject()
166{
167 // Get the Delete object for <versionID> inside image_manager
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600168 auto method = this->bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
169 MAPPER_INTERFACE, "GetObject");
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500170
171 method.append(path);
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600172 method.append(
173 std::vector<std::string>({"xyz.openbmc_project.Object.Delete"}));
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500174 auto mapperResponseMsg = bus.call(method);
175 if (mapperResponseMsg.is_method_error())
176 {
177 log<level::ERR>("Error in Get Delete Object",
178 entry("VERSIONPATH=%s", path));
179 return;
180 }
181 std::map<std::string, std::vector<std::string>> mapperResponse;
182 mapperResponseMsg.read(mapperResponse);
183 if (mapperResponse.begin() == mapperResponse.end())
184 {
185 log<level::ERR>("ERROR in reading the mapper response",
186 entry("VERSIONPATH=%s", path));
187 return;
188 }
189
190 // Call the Delete object for <versionID> inside image_manager
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600191 method = this->bus.new_method_call(
192 (mapperResponse.begin()->first).c_str(), path.c_str(),
193 "xyz.openbmc_project.Object.Delete", "Delete");
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500194 mapperResponseMsg = bus.call(method);
195
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600196 // Check that the bus call didn't result in an error
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500197 if (mapperResponseMsg.is_method_error())
198 {
199 log<level::ERR>("Error in Deleting image from image manager",
200 entry("VERSIONPATH=%s", path));
201 return;
202 }
203}
204
Saqib Khan2021b4c2017-06-07 14:37:36 -0500205uint8_t RedundancyPriority::priority(uint8_t value)
206{
Saqib Khanb8e7f312017-08-12 10:24:10 -0500207 parent.parent.freePriority(value, parent.versionId);
Michael Tritz60bc20f2017-07-29 23:32:21 -0500208 storeToFile(parent.versionId, value);
Saqib Khan2021b4c2017-06-07 14:37:36 -0500209 return softwareServer::RedundancyPriority::priority(value);
210}
211
Michael Tritz9d25b602017-06-14 14:41:43 -0500212void Activation::unitStateChange(sdbusplus::message::message& msg)
213{
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600214 uint32_t newStateID{};
Michael Tritz9d25b602017-06-14 14:41:43 -0500215 sdbusplus::message::object_path newStateObjPath;
216 std::string newStateUnit{};
217 std::string newStateResult{};
218
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600219 // Read the msg and populate each variable
Michael Tritz9d25b602017-06-14 14:41:43 -0500220 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
221
Michael Tritz9d25b602017-06-14 14:41:43 -0500222 auto ubimountServiceFile =
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600223 "obmc-flash-bios-ubimount@" + versionId + ".service";
Michael Tritz9d25b602017-06-14 14:41:43 -0500224
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600225 if (newStateUnit == ubimountServiceFile && newStateResult == "done")
Michael Tritz9d25b602017-06-14 14:41:43 -0500226 {
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500227 ubiVolumesCreated = true;
Michael Tritz1793b642017-06-28 18:35:58 -0500228 activationProgress->progress(activationProgress->progress() + 50);
Michael Tritz9d25b602017-06-14 14:41:43 -0500229 }
230
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600231 if (ubiVolumesCreated)
Michael Tritz9d25b602017-06-14 14:41:43 -0500232 {
233 Activation::activation(
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600234 softwareServer::Activation::Activations::Activating);
Michael Tritz9d25b602017-06-14 14:41:43 -0500235 }
236
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600237 if ((newStateUnit == ubimountServiceFile) &&
Michael Tritz9d25b602017-06-14 14:41:43 -0500238 (newStateResult == "failed" || newStateResult == "dependency"))
239 {
240 Activation::activation(softwareServer::Activation::Activations::Failed);
241 }
242
243 return;
244}
245
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500246} // namespace updater
247} // namespace software
248} // namespace openpower