-
Notifications
You must be signed in to change notification settings - Fork 24
/
item_updater.hpp
403 lines (347 loc) · 13.6 KB
/
item_updater.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
#pragma once
#include "activation.hpp"
#include "item_updater_helper.hpp"
#include "msl_verify.hpp"
#include "update_manager.hpp"
#include "version.hpp"
#include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
#include <sdbusplus/async.hpp>
#include <sdbusplus/server.hpp>
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
#include <xyz/openbmc_project/Common/FactoryReset/server.hpp>
#include <xyz/openbmc_project/Control/FieldMode/server.hpp>
#include <xyz/openbmc_project/Software/MinimumVersion/server.hpp>
#include <string>
#include <vector>
namespace phosphor
{
namespace software
{
namespace updater
{
using ActivationIntf =
sdbusplus::xyz::openbmc_project::Software::server::Activation;
using ItemUpdaterInherit = sdbusplus::server::object_t<
sdbusplus::server::xyz::openbmc_project::common::FactoryReset,
sdbusplus::server::xyz::openbmc_project::control::FieldMode,
sdbusplus::server::xyz::openbmc_project::association::Definitions,
sdbusplus::server::xyz::openbmc_project::collection::DeleteAll>;
using MinimumVersionInherit = sdbusplus::server::object_t<
sdbusplus::server::xyz::openbmc_project::software::MinimumVersion>;
namespace MatchRules = sdbusplus::bus::match::rules;
using VersionClass = phosphor::software::manager::Version;
using AssociationList =
std::vector<std::tuple<std::string, std::string, std::string>>;
using UpdateManager = phosphor::software::update::Manager;
/** @class MinimumVersion
* @brief OpenBMC MinimumVersion implementation.
* @details A concrete implementation for
* xyz.openbmc_project.Software.MinimumVersion DBus API.
*/
class MinimumVersion : public MinimumVersionInherit
{
public:
/** @brief Constructs MinimumVersion
*
* @param[in] bus - The D-Bus bus object
* @param[in] path - The D-bus object path
*/
MinimumVersion(sdbusplus::bus_t& bus, const std::string& path) :
MinimumVersionInherit(bus, path.c_str(), action::emit_interface_added)
{}
};
/** @class ItemUpdater
* @brief Manages the activation of the BMC version items.
*/
class ItemUpdater : public ItemUpdaterInherit
{
public:
/*
* @brief Types of Activation status for image validation.
*/
enum class ActivationStatus
{
ready,
invalid,
active
};
/** @brief Types of Updater. */
enum class UpdaterType
{
BMC,
BIOS,
ALL
};
/** @brief Constructs ItemUpdater
*
* @param[in] bus - The D-Bus bus object
*/
ItemUpdater(sdbusplus::async::context& ctx, const std::string& path,
UpdaterType type = UpdaterType::ALL,
bool useUpdateDBusInterface = true) :
ItemUpdaterInherit(ctx.get_bus(), path.c_str(),
ItemUpdaterInherit::action::defer_emit),
type(type), useUpdateDBusInterface(useUpdateDBusInterface), ctx(ctx),
bus(ctx.get_bus()), helper(bus)
{
if (!useUpdateDBusInterface)
{
versionMatch = std::make_unique<sdbusplus::bus::match_t>(
bus,
MatchRules::interfacesAdded() +
MatchRules::path("/xyz/openbmc_project/software"),
std::bind(std::mem_fn(&ItemUpdater::createActivation), this,
std::placeholders::_1));
}
getRunningSlot();
setBMCInventoryPath();
if (type == UpdaterType::BMC || type == UpdaterType::ALL)
{
processBMCImage();
}
if (type == UpdaterType::BIOS || type == UpdaterType::ALL)
{
#ifdef HOST_BIOS_UPGRADE
createBIOSObject();
#endif
}
restoreFieldModeStatus();
emit_object_added();
};
/** @brief Save priority value to persistent storage (flash and optionally
* a U-Boot environment variable)
*
* @param[in] versionId - The Id of the version
* @param[in] value - The priority value
* @return None
*/
void savePriority(const std::string& versionId, uint8_t value);
/** @brief Sets the given priority free by incrementing
* any existing priority with the same value by 1
*
* @param[in] value - The priority that needs to be set free.
* @param[in] versionId - The Id of the version for which we
* are trying to free up the priority.
* @return None
*/
void freePriority(uint8_t value, const std::string& versionId);
/**
* @brief Create and populate the active BMC Version.
*/
void processBMCImage();
/**
* @brief Verifies the image at filepath and creates the version and
* activation object. In case activation object already exists for the
* specified id, update the activation status based on image verification.
* @param[in] id - The unique identifier for the update.
* @param[in] path - The object path for the relevant objects.
* @param[in] version - The version of the image.
* @param[in] purpose - The purpose of the image.
* @param[in] extendedVersion The extended version of the image.
* @param[in] filePath - The file path where the image is located.
* @param[in] compatibleNames - The compatible name for the image.
* @param[out] Activations - Whether the image is ready to activate or not.
*/
ActivationIntf::Activations verifyAndCreateObjects(
std::string& id, std::string& path, std::string& version,
VersionClass::VersionPurpose purpose, std::string& extendedVersion,
std ::string& filePath, std::vector<std::string>& compatibleNames);
/**
* @brief Creates the activation object
* @param[in] id - The unique identifier for the update.
* @param[in] path - The object path for the activation object.
* @param[in] applyTime - The apply time for the image
*/
void createActivationWithApplyTime(
std::string& id, std::string& path,
ApplyTimeIntf::RequestedApplyTimes applyTime);
/**
* @brief Request the activation for the specified update.
* @param[in] id - The unique identifier for the update.
* @param[out] bool - status for the action.
*/
bool requestActivation(std::string& id);
/**
* @brief Change the activation status for the specified update.
* @param[in] id - The unique identifier for the update.
* @param[in] status - The activation status to set.
* @param[out] bool - status for the action.
*/
bool updateActivationStatus(std::string& id,
ActivationIntf::Activations status);
/**
* @brief Create the Update object
* @param[in] id - The unique identifier for the update.
* @param[in] path - The object path for the update object.
*/
void createUpdateObject(const std::string& id, const std::string& path);
/**
* @brief Erase specified entry D-Bus object
* if Action property is not set to Active
*
* @param[in] entryId - unique identifier of the entry
*/
void erase(std::string entryId);
/**
* @brief Deletes all versions except for the current one
*/
void deleteAll() override;
/** @brief Creates an active association to the
* newly active software image
*
* @param[in] path - The path to create the association to.
*/
void createActiveAssociation(const std::string& path);
/** @brief Removes the associations from the provided software image path
*
* @param[in] path - The path to remove the associations from.
*/
void removeAssociations(const std::string& path);
/** @brief Determine if the given priority is the lowest
*
* @param[in] value - The priority that needs to be checked.
*
* @return boolean corresponding to whether the given
* priority is lowest.
*/
bool isLowestPriority(uint8_t value);
/**
* @brief Updates the U-Boot variables to point to the requested
* versionId, so that the systems boots from this version on
* the next reboot.
*
* @param[in] versionId - The version to point the system to boot from.
*/
void updateUbootEnvVars(const std::string& versionId);
/**
* @brief Updates the uboot variables to point to BMC version with lowest
* priority, so that the system boots from this version on the
* next boot.
*/
void resetUbootEnvVars();
/** @brief Brings the total number of active BMC versions to
* ACTIVE_BMC_MAX_ALLOWED -1. This function is intended to be
* run before activating a new BMC version. If this function
* needs to delete any BMC version(s) it will delete the
* version(s) with the highest priority, skipping the
* functional BMC version.
*
* @param[in] caller - The Activation object that called this function.
*/
void freeSpace(const Activation& caller);
/** @brief Creates a updateable association to the
* "running" BMC software image
*
* @param[in] path - The path to create the association.
*/
void createUpdateableAssociation(const std::string& path);
/** @brief Persistent map of Version D-Bus objects and their
* version id */
std::map<std::string, std::unique_ptr<VersionClass>> versions;
/** @brief Vector of needed BMC images in the tarball*/
std::vector<std::string> imageUpdateList;
/** @brief The slot of running BMC image */
uint32_t runningImageSlot = 0;
/** @brief The type of updater. */
UpdaterType type;
/** @brief Flag to indicate if the update interface is used or not */
bool useUpdateDBusInterface;
private:
/** @brief Callback function for Software.Version match.
* @details Creates an Activation D-Bus object.
*
* @param[in] msg - Data associated with subscribed signal
*/
void createActivation(sdbusplus::message_t& msg);
/**
* @brief Validates the presence of SquashFS image in the image dir.
*
* @param[in] filePath - The path to the image dir.
* @param[out] result - ActivationStatus Enum.
* ready if validation was successful.
* invalid if validation fail.
* active if image is the current version.
*
*/
ActivationStatus validateSquashFSImage(const std::string& filePath);
/** @brief BMC factory reset - marks the read-write partition for
* recreation upon reboot. */
void reset() override;
/**
* @brief Enables field mode, if value=true.
*
* @param[in] value - If true, enables field mode.
* @param[out] result - Returns the current state of field mode.
*
*/
bool fieldModeEnabled(bool value) override;
/** @brief Sets the BMC inventory item path under
* /xyz/openbmc_project/inventory/system/chassis/. */
void setBMCInventoryPath();
/** @brief The path to the BMC inventory item. */
std::string bmcInventoryPath;
/** @brief Restores field mode status on reboot. */
void restoreFieldModeStatus();
/** @brief Creates a functional association to the
* "running" BMC software image
*
* @param[in] path - The path to create the association to.
*/
void createFunctionalAssociation(const std::string& path);
/** @brief D-Bus context */
sdbusplus::async::context& ctx;
/** @brief Persistent sdbusplus D-Bus bus connection. */
sdbusplus::bus_t& bus;
/** @brief The helper of image updater. */
Helper helper;
/** @brief Persistent map of Activation D-Bus objects and their
* version id */
std::map<std::string, std::unique_ptr<Activation>> activations;
/** @brief sdbusplus signal match for Software.Version */
std::unique_ptr<sdbusplus::bus::match_t> versionMatch;
/** @brief This entry's associations */
AssociationList assocs;
/** @brief Clears read only partition for
* given Activation D-Bus object.
*
* @param[in] versionId - The version id.
*/
void removeReadOnlyPartition(const std::string& versionId);
/** @brief Copies U-Boot from the currently booted BMC chip to the
* alternate chip.
*/
void mirrorUbootToAlt();
/** @brief Check the required image files
*
* @param[in] filePath - BMC tarball file path
* @param[in] imageList - Image filenames included in the BMC tarball
* @param[out] result - Boolean
* true if all image files are found in BMC tarball
* false if one of image files is missing
*/
static bool checkImage(const std::string& filePath,
const std::vector<std::string>& imageList);
/** @brief Persistent MinimumVersion D-Bus object */
std::unique_ptr<MinimumVersion> minimumVersionObject;
/** @brief Persistent map of Update D-Bus objects and their SwIds */
std::map<std::string, std::unique_ptr<UpdateManager>> updateManagers;
#ifdef HOST_BIOS_UPGRADE
/** @brief Create the BIOS object without knowing the version.
*
* The object is created only to provide the DBus access so that an
* external service could set the correct BIOS version.
* On BIOS code update, the version is updated accordingly.
*/
void createBIOSObject();
/** @brief Persistent Activation D-Bus object for BIOS */
std::unique_ptr<Activation> biosActivation;
public:
/** @brief Persistent Version D-Bus object for BIOS */
std::unique_ptr<VersionClass> biosVersion;
#endif
/** @brief Get the slot number of running image */
void getRunningSlot();
};
} // namespace updater
} // namespace software
} // namespace phosphor