blob: a5a357b43b89ec10c1a09d0dd418f1e2981f46a7 [file] [log] [blame]
Jason Lingc78bfc82020-11-05 18:58:16 -08001#include "version_handler.hpp"
2
William A. Kennington IIIabf17352020-12-22 21:07:11 -08003#include <utility>
4#include <vector>
5
Jason Lingc78bfc82020-11-05 18:58:16 -08006namespace ipmi_flash
7{
William A. Kennington IIIabf17352020-12-22 21:07:11 -08008
9VersionBlobHandler::VersionBlobHandler(
10 std::vector<HandlerConfig<ActionPack>>&& configs)
Jason Lingc78bfc82020-11-05 18:58:16 -080011{
William A. Kennington IIIabf17352020-12-22 21:07:11 -080012 for (auto& config : configs)
Jason Lingc78bfc82020-11-05 18:58:16 -080013 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080014 auto info = std::make_unique<BlobInfo>();
15 info->blobId = std::move(config.blobId);
16 info->actions = std::move(config.actions);
17 info->handler = std::move(config.handler);
18 if (!blobInfoMap.try_emplace(info->blobId, std::move(info)).second)
William A. Kennington IIIabf17352020-12-22 21:07:11 -080019 {
20 fprintf(stderr, "Ignoring duplicate config for %s\n",
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080021 info->blobId.c_str());
William A. Kennington IIIabf17352020-12-22 21:07:11 -080022 }
Jason Lingc78bfc82020-11-05 18:58:16 -080023 }
Jason Lingc78bfc82020-11-05 18:58:16 -080024}
25
26bool VersionBlobHandler::canHandleBlob(const std::string& path)
27{
William A. Kennington IIIabf17352020-12-22 21:07:11 -080028 return blobInfoMap.find(path) != blobInfoMap.end();
Jason Lingc78bfc82020-11-05 18:58:16 -080029}
30
31std::vector<std::string> VersionBlobHandler::getBlobIds()
32{
William A. Kennington IIIabf17352020-12-22 21:07:11 -080033 std::vector<std::string> ret;
34 for (const auto& [key, _] : blobInfoMap)
35 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080036 ret.emplace_back(key);
William A. Kennington IIIabf17352020-12-22 21:07:11 -080037 }
38 return ret;
Jason Lingc78bfc82020-11-05 18:58:16 -080039}
40
41/**
42 * deleteBlob - does nothing, always fails
43 */
44bool VersionBlobHandler::deleteBlob(const std::string& path)
45{
46 return false;
47}
48
49bool VersionBlobHandler::stat(const std::string& path, blobs::BlobMeta* meta)
50{
51 // TODO: stat should return the blob state and in the meta data information
52 // on whether a read is successful should be contained
53 // do things like determine if systemd target is triggered
54 // then check if file can be opened for read
55 return false; /* not yet implemented */
56}
57
58bool VersionBlobHandler::open(uint16_t session, uint16_t flags,
59 const std::string& path)
60{
Jason Lingc78bfc82020-11-05 18:58:16 -080061 /* only reads are supported, check if blob is handled and make sure
62 * the blob isn't already opened
63 */
64 if (flags != blobs::read)
65 {
66 fprintf(stderr, "open %s fail: unsupported flags(0x%04X.)\n",
67 path.c_str(), flags);
Jason Lingc78bfc82020-11-05 18:58:16 -080068 return false;
69 }
Jason Lingc78bfc82020-11-05 18:58:16 -080070
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080071 auto& v = *blobInfoMap.at(path);
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080072 if (v.blobState == blobs::StateFlags::open_read)
Jason Lingc78bfc82020-11-05 18:58:16 -080073 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080074 fprintf(stderr, "open %s fail: blob already opened for read\n",
75 path.c_str());
Jason Lingc78bfc82020-11-05 18:58:16 -080076 return false;
77 }
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080078 if (v.actions->onOpen->trigger() == false)
79 {
80 fprintf(stderr, "open %s fail: onOpen trigger failed\n", path.c_str());
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080081 return false;
82 }
William A. Kennington III007c0162020-12-23 16:36:22 -080083
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080084 v.blobState = blobs::StateFlags::open_read;
William A. Kennington III007c0162020-12-23 16:36:22 -080085 sessionToBlob[session] = &v;
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080086 return true;
Jason Lingc78bfc82020-11-05 18:58:16 -080087}
88
89std::vector<uint8_t> VersionBlobHandler::read(uint16_t session, uint32_t offset,
90 uint32_t requestedSize)
91{
William A. Kennington III12e6e752020-12-23 20:47:29 -080092 auto pack = sessionToBlob.at(session);
93
Jason Lingc78bfc82020-11-05 18:58:16 -080094 /* onOpen trigger must be successful, otherwise potential
95 * for stale data to be read
96 */
William A. Kennington IIIabf17352020-12-22 21:07:11 -080097 if (pack->actions->onOpen->status() != ActionStatus::success)
Jason Lingc78bfc82020-11-05 18:58:16 -080098 {
99 fprintf(stderr, "read failed: onOpen trigger not successful\n");
100 return {};
101 }
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800102 if (!pack->handler->open("don't care", std::ios::in))
Jason Lingc78bfc82020-11-05 18:58:16 -0800103 {
104 fprintf(stderr, "read failed: file open unsuccessful blob=%s\n",
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -0800105 pack->blobId.c_str());
Jason Lingc78bfc82020-11-05 18:58:16 -0800106 return {};
107 }
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800108 auto d = pack->handler->read(offset, requestedSize);
Jason Lingc78bfc82020-11-05 18:58:16 -0800109 if (!d)
110 {
111 fprintf(stderr, "read failed: unable to read file for blob %s\n",
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -0800112 pack->blobId.c_str());
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800113 pack->handler->close();
Jason Lingc78bfc82020-11-05 18:58:16 -0800114 return {};
115 }
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800116 pack->handler->close();
Jason Lingc78bfc82020-11-05 18:58:16 -0800117 return *d;
118}
119
120bool VersionBlobHandler::close(uint16_t session)
121{
Jason Lingc78bfc82020-11-05 18:58:16 -0800122 try
123 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -0800124 auto& pack = *sessionToBlob.at(session);
William A. Kennington III007c0162020-12-23 16:36:22 -0800125 pack.actions->onOpen->abort();
Jason Lingc78bfc82020-11-05 18:58:16 -0800126 pack.blobState = static_cast<blobs::StateFlags>(0);
127 sessionToBlob.erase(session);
128 return true;
129 }
130 catch (const std::out_of_range& e)
131 {
132 return false;
133 }
134}
William A. Kennington IIIc5b901d2020-12-23 17:07:20 -0800135
136bool VersionBlobHandler::stat(uint16_t session, blobs::BlobMeta* meta)
137{
138 return false;
139}
140
141bool VersionBlobHandler::expire(uint16_t session)
142{
143 close(session);
144 return true;
145}
146
Jason Lingc78bfc82020-11-05 18:58:16 -0800147} // namespace ipmi_flash