blob: 8842f0581e32bbf8320d409c9389f04341fc1b9f [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{
19
Lei YU6da3dae2019-02-28 14:26:37 +080020 auto ret = value;
Lei YUa2e67162019-02-22 17:35:24 +080021 if (value != softwareServer::Activation::Activations::Active)
22 {
23 redundancyPriority.reset(nullptr);
24 }
25
26 if (value == softwareServer::Activation::Activations::Activating)
27 {
Lei YU2b2d2292019-03-18 15:22:56 +080028 fs::path imagePath(IMG_DIR);
29 imagePath /= versionId;
30
31 for (const auto& entry : fs::directory_iterator(imagePath))
32 {
33 if (entry.path().extension() == ".pnor")
34 {
35 pnorFilePath = entry;
36 break;
37 }
38 }
39 if (pnorFilePath.empty())
40 {
41 log<level::ERR>("Unable to find pnor file",
42 entry("DIR=%s", imagePath.c_str()));
43 ret = softwareServer::Activation::Activations::Failed;
44 goto out;
45 }
46#ifdef WANT_SIGNATURE_VERIFY
47 // Validate the signed image.
48 if (!validateSignature(pnorFilePath.filename()))
49 {
50 // Cleanup
51 activationBlocksTransition.reset(nullptr);
52 activationProgress.reset(nullptr);
53
54 ret = softwareServer::Activation::Activations::Failed;
55 goto out;
56 }
57#endif
Lei YU6da3dae2019-02-28 14:26:37 +080058 if (parent.freeSpace())
59 {
60 startActivation();
61 }
62 else
63 {
64 ret = softwareServer::Activation::Activations::Failed;
65 }
Lei YUa2e67162019-02-22 17:35:24 +080066 }
67 else
68 {
69 activationBlocksTransition.reset(nullptr);
70 activationProgress.reset(nullptr);
71 }
72
Lei YU2b2d2292019-03-18 15:22:56 +080073out:
Lei YU6da3dae2019-02-28 14:26:37 +080074 return softwareServer::Activation::activation(ret);
Lei YUa2e67162019-02-22 17:35:24 +080075}
76
Lei YUb53425d2019-02-22 11:38:40 +080077void ActivationStatic::startActivation()
78{
Lei YUa2e67162019-02-22 17:35:24 +080079 if (!activationProgress)
80 {
81 activationProgress = std::make_unique<ActivationProgress>(bus, path);
82 }
83
84 if (!activationBlocksTransition)
85 {
86 activationBlocksTransition =
87 std::make_unique<ActivationBlocksTransition>(bus, path);
88 }
89
90 // TODO: check why the signal is still received without calling this
91 // function?
92 subscribeToSystemdSignals();
93
94 log<level::INFO>("Start programming...",
Lei YU2b2d2292019-03-18 15:22:56 +080095 entry("PNOR=%s", pnorFilePath.c_str()));
Lei YUa2e67162019-02-22 17:35:24 +080096
Lei YU2b2d2292019-03-18 15:22:56 +080097 std::string pnorFileEscaped = pnorFilePath.string();
Lei YUa2e67162019-02-22 17:35:24 +080098 // Escape all '/' to '-'
99 std::replace(pnorFileEscaped.begin(), pnorFileEscaped.end(), '/', '-');
100
101 constexpr auto updatePNORService = "openpower-pnor-update@";
102 pnorUpdateUnit =
103 std::string(updatePNORService) + pnorFileEscaped + ".service";
104 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
105 SYSTEMD_INTERFACE, "StartUnit");
106 method.append(pnorUpdateUnit, "replace");
107 bus.call_noreply(method);
108
109 activationProgress->progress(10);
Lei YUb53425d2019-02-22 11:38:40 +0800110}
111
112void ActivationStatic::unitStateChange(sdbusplus::message::message& msg)
113{
Lei YUa2e67162019-02-22 17:35:24 +0800114 uint32_t newStateID{};
115 sdbusplus::message::object_path newStateObjPath;
116 std::string newStateUnit{};
117 std::string newStateResult{};
118
119 // Read the msg and populate each variable
120 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
121
122 if (newStateUnit == pnorUpdateUnit)
123 {
124 if (newStateResult == "done")
125 {
126 finishActivation();
127 }
128 if (newStateResult == "failed" || newStateResult == "dependency")
129 {
130 Activation::activation(
131 softwareServer::Activation::Activations::Failed);
132 }
133 }
Lei YUb53425d2019-02-22 11:38:40 +0800134}
135
136void ActivationStatic::finishActivation()
137{
Lei YUa2e67162019-02-22 17:35:24 +0800138 activationProgress->progress(90);
139
140 // Set Redundancy Priority before setting to Active
141 if (!redundancyPriority)
142 {
143 redundancyPriority =
144 std::make_unique<RedundancyPriority>(bus, path, *this, 0);
145 }
146
147 activationProgress->progress(100);
148
149 activationBlocksTransition.reset();
150 activationProgress.reset();
151
152 unsubscribeFromSystemdSignals();
153 // Remove version object from image manager
154 deleteImageManagerObject();
155 // Create active association
156 parent.createActiveAssociation(path);
Adriana Kobylak3c810372020-07-15 16:47:03 -0500157 // Create updateable association as this
158 // can be re-programmed.
159 parent.createUpdateableAssociation(path);
Lei YUa2e67162019-02-22 17:35:24 +0800160 // Create functional assocaition
161 parent.updateFunctionalAssociation(versionId);
162
163 Activation::activation(Activation::Activations::Active);
Lei YUb53425d2019-02-22 11:38:40 +0800164}
165
166} // namespace updater
167} // namespace software
168} // namespace openpower