blob: fee62d9f3ecac42abd0596db09233a6aa2bf838a [file] [log] [blame]
Jason Lingc78bfc82020-11-05 18:58:16 -08001#include "version_handler.hpp"
2
3#include <stdexcept>
William A. Kennington IIIabf17352020-12-22 21:07:11 -08004#include <utility>
5#include <vector>
6
Jason Lingc78bfc82020-11-05 18:58:16 -08007namespace ipmi_flash
8{
William A. Kennington IIIabf17352020-12-22 21:07:11 -08009
10VersionBlobHandler::VersionBlobHandler(
11 std::vector<HandlerConfig<ActionPack>>&& configs)
Jason Lingc78bfc82020-11-05 18:58:16 -080012{
William A. Kennington IIIabf17352020-12-22 21:07:11 -080013 for (auto& config : configs)
Jason Lingc78bfc82020-11-05 18:58:16 -080014 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080015 auto info = std::make_unique<BlobInfo>();
16 info->blobId = std::move(config.blobId);
17 info->actions = std::move(config.actions);
18 info->handler = std::move(config.handler);
19 if (!blobInfoMap.try_emplace(info->blobId, std::move(info)).second)
William A. Kennington IIIabf17352020-12-22 21:07:11 -080020 {
21 fprintf(stderr, "Ignoring duplicate config for %s\n",
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080022 info->blobId.c_str());
William A. Kennington IIIabf17352020-12-22 21:07:11 -080023 }
Jason Lingc78bfc82020-11-05 18:58:16 -080024 }
Jason Lingc78bfc82020-11-05 18:58:16 -080025}
26
27bool VersionBlobHandler::canHandleBlob(const std::string& path)
28{
William A. Kennington IIIabf17352020-12-22 21:07:11 -080029 return blobInfoMap.find(path) != blobInfoMap.end();
Jason Lingc78bfc82020-11-05 18:58:16 -080030}
31
32std::vector<std::string> VersionBlobHandler::getBlobIds()
33{
William A. Kennington IIIabf17352020-12-22 21:07:11 -080034 std::vector<std::string> ret;
35 for (const auto& [key, _] : blobInfoMap)
36 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080037 ret.emplace_back(key);
William A. Kennington IIIabf17352020-12-22 21:07:11 -080038 }
39 return ret;
Jason Lingc78bfc82020-11-05 18:58:16 -080040}
41
42/**
43 * deleteBlob - does nothing, always fails
44 */
45bool VersionBlobHandler::deleteBlob(const std::string& path)
46{
47 return false;
48}
49
50bool VersionBlobHandler::stat(const std::string& path, blobs::BlobMeta* meta)
51{
52 // TODO: stat should return the blob state and in the meta data information
53 // on whether a read is successful should be contained
54 // do things like determine if systemd target is triggered
55 // then check if file can be opened for read
56 return false; /* not yet implemented */
57}
58
59bool VersionBlobHandler::open(uint16_t session, uint16_t flags,
60 const std::string& path)
61{
Jason Lingc78bfc82020-11-05 18:58:16 -080062 /* only reads are supported, check if blob is handled and make sure
63 * the blob isn't already opened
64 */
65 if (flags != blobs::read)
66 {
67 fprintf(stderr, "open %s fail: unsupported flags(0x%04X.)\n",
68 path.c_str(), flags);
Jason Lingc78bfc82020-11-05 18:58:16 -080069 return false;
70 }
Jason Lingc78bfc82020-11-05 18:58:16 -080071
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080072 auto& v = *blobInfoMap.at(path);
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080073 if (v.blobState == blobs::StateFlags::open_read)
Jason Lingc78bfc82020-11-05 18:58:16 -080074 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080075 fprintf(stderr, "open %s fail: blob already opened for read\n",
76 path.c_str());
Jason Lingc78bfc82020-11-05 18:58:16 -080077 return false;
78 }
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080079 if (v.actions->onOpen->trigger() == false)
80 {
81 fprintf(stderr, "open %s fail: onOpen trigger failed\n", path.c_str());
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080082 return false;
83 }
William A. Kennington III007c0162020-12-23 16:36:22 -080084
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080085 v.blobState = blobs::StateFlags::open_read;
William A. Kennington III007c0162020-12-23 16:36:22 -080086 sessionToBlob[session] = &v;
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080087 return true;
Jason Lingc78bfc82020-11-05 18:58:16 -080088}
89
90std::vector<uint8_t> VersionBlobHandler::read(uint16_t session, uint32_t offset,
91 uint32_t requestedSize)
92{
William A. Kennington IIIabf17352020-12-22 21:07:11 -080093 BlobInfo* pack;
Jason Lingc78bfc82020-11-05 18:58:16 -080094 try
95 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -080096 pack = sessionToBlob.at(session);
Jason Lingc78bfc82020-11-05 18:58:16 -080097 }
98 catch (const std::out_of_range& e)
99 {
100 return {};
101 }
102 /* onOpen trigger must be successful, otherwise potential
103 * for stale data to be read
104 */
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800105 if (pack->actions->onOpen->status() != ActionStatus::success)
Jason Lingc78bfc82020-11-05 18:58:16 -0800106 {
107 fprintf(stderr, "read failed: onOpen trigger not successful\n");
108 return {};
109 }
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800110 if (!pack->handler->open("don't care", std::ios::in))
Jason Lingc78bfc82020-11-05 18:58:16 -0800111 {
112 fprintf(stderr, "read failed: file open unsuccessful blob=%s\n",
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -0800113 pack->blobId.c_str());
Jason Lingc78bfc82020-11-05 18:58:16 -0800114 return {};
115 }
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800116 auto d = pack->handler->read(offset, requestedSize);
Jason Lingc78bfc82020-11-05 18:58:16 -0800117 if (!d)
118 {
119 fprintf(stderr, "read failed: unable to read file for blob %s\n",
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -0800120 pack->blobId.c_str());
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800121 pack->handler->close();
Jason Lingc78bfc82020-11-05 18:58:16 -0800122 return {};
123 }
William A. Kennington IIIabf17352020-12-22 21:07:11 -0800124 pack->handler->close();
Jason Lingc78bfc82020-11-05 18:58:16 -0800125 return *d;
126}
127
128bool VersionBlobHandler::close(uint16_t session)
129{
Jason Lingc78bfc82020-11-05 18:58:16 -0800130 try
131 {
William A. Kennington IIIb45eb5e2020-12-23 11:47:05 -0800132 auto& pack = *sessionToBlob.at(session);
William A. Kennington III007c0162020-12-23 16:36:22 -0800133 pack.actions->onOpen->abort();
Jason Lingc78bfc82020-11-05 18:58:16 -0800134 pack.blobState = static_cast<blobs::StateFlags>(0);
135 sessionToBlob.erase(session);
136 return true;
137 }
138 catch (const std::out_of_range& e)
139 {
140 return false;
141 }
142}
William A. Kennington IIIc5b901d2020-12-23 17:07:20 -0800143
144bool VersionBlobHandler::stat(uint16_t session, blobs::BlobMeta* meta)
145{
146 return false;
147}
148
149bool VersionBlobHandler::expire(uint16_t session)
150{
151 close(session);
152 return true;
153}
154
Jason Lingc78bfc82020-11-05 18:58:16 -0800155} // namespace ipmi_flash