blob: d4f83294990af738c53415e0a2a63eca93c8fd5a [file] [log] [blame]
Lei YUb53425d2019-02-22 11:38:40 +08001#include "activation_static.hpp"
2
Lei YUa2e67162019-02-22 17:35:24 +08003#include "item_updater.hpp"
4
Lei YUa2e67162019-02-22 17:35:24 +08005#include <phosphor-logging/log.hpp>
6
Lei YUb53425d2019-02-22 11:38:40 +08007namespace openpower
8{
9namespace software
10{
11namespace updater
12{
13namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
14
Lei YUa2e67162019-02-22 17:35:24 +080015using namespace phosphor::logging;
16
17auto ActivationStatic::activation(Activations value) -> Activations
18{
Lei YU6da3dae2019-02-28 14:26:37 +080019 auto ret = value;
Lei YUa2e67162019-02-22 17:35:24 +080020 if (value != softwareServer::Activation::Activations::Active)
21 {
22 redundancyPriority.reset(nullptr);
23 }
24
25 if (value == softwareServer::Activation::Activations::Activating)
26 {
Lei YU2b2d2292019-03-18 15:22:56 +080027 fs::path imagePath(IMG_DIR);
28 imagePath /= versionId;
29
30 for (const auto& entry : fs::directory_iterator(imagePath))
31 {
32 if (entry.path().extension() == ".pnor")
33 {
34 pnorFilePath = entry;
35 break;
36 }
37 }
38 if (pnorFilePath.empty())
39 {
40 log<level::ERR>("Unable to find pnor file",
41 entry("DIR=%s", imagePath.c_str()));
42 ret = softwareServer::Activation::Activations::Failed;
43 goto out;
44 }
45#ifdef WANT_SIGNATURE_VERIFY
46 // Validate the signed image.
47 if (!validateSignature(pnorFilePath.filename()))
48 {
49 // Cleanup
50 activationBlocksTransition.reset(nullptr);
51 activationProgress.reset(nullptr);
52
53 ret = softwareServer::Activation::Activations::Failed;
54 goto out;
55 }
56#endif
Lei YU6da3dae2019-02-28 14:26:37 +080057 if (parent.freeSpace())
58 {
59 startActivation();
60 }
61 else
62 {
63 ret = softwareServer::Activation::Activations::Failed;
64 }
Lei YUa2e67162019-02-22 17:35:24 +080065 }
66 else
67 {
68 activationBlocksTransition.reset(nullptr);
69 activationProgress.reset(nullptr);
70 }
71
Lei YU2b2d2292019-03-18 15:22:56 +080072out:
Lei YU6da3dae2019-02-28 14:26:37 +080073 return softwareServer::Activation::activation(ret);
Lei YUa2e67162019-02-22 17:35:24 +080074}
75
Lei YUb53425d2019-02-22 11:38:40 +080076void ActivationStatic::startActivation()
77{
Lei YUa2e67162019-02-22 17:35:24 +080078 if (!activationProgress)
79 {
80 activationProgress = std::make_unique<ActivationProgress>(bus, path);
81 }
82
83 if (!activationBlocksTransition)
84 {
85 activationBlocksTransition =
86 std::make_unique<ActivationBlocksTransition>(bus, path);
87 }
88
89 // TODO: check why the signal is still received without calling this
90 // function?
91 subscribeToSystemdSignals();
92
93 log<level::INFO>("Start programming...",
Lei YU2b2d2292019-03-18 15:22:56 +080094 entry("PNOR=%s", pnorFilePath.c_str()));
Lei YUa2e67162019-02-22 17:35:24 +080095
Lei YU2b2d2292019-03-18 15:22:56 +080096 std::string pnorFileEscaped = pnorFilePath.string();
Lei YUa2e67162019-02-22 17:35:24 +080097 // Escape all '/' to '-'
98 std::replace(pnorFileEscaped.begin(), pnorFileEscaped.end(), '/', '-');
99
100 constexpr auto updatePNORService = "openpower-pnor-update@";
Patrick Williams7fb6c342023-05-10 07:50:18 -0500101 pnorUpdateUnit = std::string(updatePNORService) + pnorFileEscaped +
102 ".service";
Lei YUa2e67162019-02-22 17:35:24 +0800103 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
104 SYSTEMD_INTERFACE, "StartUnit");
105 method.append(pnorUpdateUnit, "replace");
106 bus.call_noreply(method);
107
108 activationProgress->progress(10);
Lei YUb53425d2019-02-22 11:38:40 +0800109}
110
Patrick Williams0dea1992022-07-22 19:26:52 -0500111void ActivationStatic::unitStateChange(sdbusplus::message_t& msg)
Lei YUb53425d2019-02-22 11:38:40 +0800112{
Lei YUa2e67162019-02-22 17:35:24 +0800113 uint32_t newStateID{};
114 sdbusplus::message::object_path newStateObjPath;
115 std::string newStateUnit{};
116 std::string newStateResult{};
117
118 // Read the msg and populate each variable
119 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
120
121 if (newStateUnit == pnorUpdateUnit)
122 {
123 if (newStateResult == "done")
124 {
125 finishActivation();
126 }
127 if (newStateResult == "failed" || newStateResult == "dependency")
128 {
129 Activation::activation(
130 softwareServer::Activation::Activations::Failed);
131 }
132 }
Lei YUb53425d2019-02-22 11:38:40 +0800133}
134
135void ActivationStatic::finishActivation()
136{
Lei YUa2e67162019-02-22 17:35:24 +0800137 activationProgress->progress(90);
138
139 // Set Redundancy Priority before setting to Active
140 if (!redundancyPriority)
141 {
Patrick Williams7fb6c342023-05-10 07:50:18 -0500142 redundancyPriority = std::make_unique<RedundancyPriority>(bus, path,
143 *this, 0);
Lei YUa2e67162019-02-22 17:35:24 +0800144 }
145
146 activationProgress->progress(100);
147
148 activationBlocksTransition.reset();
149 activationProgress.reset();
150
151 unsubscribeFromSystemdSignals();
152 // Remove version object from image manager
153 deleteImageManagerObject();
154 // Create active association
155 parent.createActiveAssociation(path);
Adriana Kobylak3c810372020-07-15 16:47:03 -0500156 // Create updateable association as this
157 // can be re-programmed.
158 parent.createUpdateableAssociation(path);
Lei YUa2e67162019-02-22 17:35:24 +0800159 // Create functional assocaition
160 parent.updateFunctionalAssociation(versionId);
161
162 Activation::activation(Activation::Activations::Active);
Lei YUb53425d2019-02-22 11:38:40 +0800163}
164
165} // namespace updater
166} // namespace software
167} // namespace openpower