1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <brillo/blkdev_utils/device_mapper_fake.h>
6 
7 #include <memory>
8 #include <string>
9 #include <unordered_map>
10 #include <utility>
11 #include <vector>
12 
13 namespace brillo {
14 namespace fake {
15 
16 namespace {
17 
18 // Stub DmTask runs into a map for easy reference.
StubDmRunTask(DmTask * task,bool udev_sync)19 bool StubDmRunTask(DmTask* task, bool udev_sync) {
20   std::string dev_name = task->name;
21   std::string params;
22   int type = task->type;
23   static auto& dm_target_map_ =
24       *new std::unordered_map<std::string, std::vector<DmTarget>>();
25 
26   switch (type) {
27     case DM_DEVICE_CREATE:
28       CHECK_EQ(udev_sync, true);
29       if (dm_target_map_.find(dev_name) != dm_target_map_.end())
30         return false;
31       dm_target_map_.insert(std::make_pair(dev_name, task->targets));
32       break;
33     case DM_DEVICE_REMOVE:
34       CHECK_EQ(udev_sync, true);
35       if (dm_target_map_.find(dev_name) == dm_target_map_.end())
36         return false;
37       dm_target_map_.erase(dev_name);
38       break;
39     case DM_DEVICE_TABLE:
40       CHECK_EQ(udev_sync, false);
41       if (dm_target_map_.find(dev_name) == dm_target_map_.end())
42         return false;
43       task->targets = dm_target_map_[dev_name];
44       break;
45     case DM_DEVICE_RELOAD:
46       CHECK_EQ(udev_sync, false);
47       if (dm_target_map_.find(dev_name) == dm_target_map_.end())
48         return false;
49       dm_target_map_.erase(dev_name);
50       dm_target_map_.insert(std::make_pair(dev_name, task->targets));
51       break;
52     default:
53       return false;
54   }
55   return true;
56 }
57 
DmTaskCreate(int type)58 std::unique_ptr<DmTask> DmTaskCreate(int type) {
59   auto t = std::make_unique<DmTask>();
60   t->type = type;
61   return t;
62 }
63 
64 }  // namespace
65 
FakeDevmapperTask(int type)66 FakeDevmapperTask::FakeDevmapperTask(int type) : task_(DmTaskCreate(type)) {}
67 
SetName(const std::string & name)68 bool FakeDevmapperTask::SetName(const std::string& name) {
69   task_->name = std::string(name);
70   return true;
71 }
72 
AddTarget(uint64_t start,uint64_t sectors,const std::string & type,const SecureBlob & parameters)73 bool FakeDevmapperTask::AddTarget(uint64_t start,
74                                   uint64_t sectors,
75                                   const std::string& type,
76                                   const SecureBlob& parameters) {
77   DmTarget dmt;
78   dmt.start = start;
79   dmt.size = sectors;
80   dmt.type = type;
81   dmt.parameters = parameters;
82   task_->targets.push_back(dmt);
83   return true;
84 }
85 
GetNextTarget(uint64_t * start,uint64_t * sectors,std::string * type,SecureBlob * parameters)86 bool FakeDevmapperTask::GetNextTarget(uint64_t* start,
87                                       uint64_t* sectors,
88                                       std::string* type,
89                                       SecureBlob* parameters) {
90   if (task_->targets.empty())
91     return false;
92 
93   DmTarget dmt = task_->targets[0];
94   *start = dmt.start;
95   *sectors = dmt.size;
96   *type = dmt.type;
97   *parameters = dmt.parameters;
98   task_->targets.erase(task_->targets.begin());
99 
100   return !task_->targets.empty();
101 }
102 
Run(bool udev_sync)103 bool FakeDevmapperTask::Run(bool udev_sync) {
104   return StubDmRunTask(task_.get(), udev_sync);
105 }
106 
CreateDevmapperTask(int type)107 std::unique_ptr<DevmapperTask> CreateDevmapperTask(int type) {
108   return std::make_unique<FakeDevmapperTask>(type);
109 }
110 
111 }  // namespace fake
112 }  // namespace brillo
113