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 #ifndef LIBBRILLO_BRILLO_BLKDEV_UTILS_DEVICE_MAPPER_TASK_H_
6 #define LIBBRILLO_BRILLO_BLKDEV_UTILS_DEVICE_MAPPER_TASK_H_
7 
8 #include <libdevmapper.h>
9 #include <memory>
10 #include <string>
11 
12 #include <brillo/secure_blob.h>
13 
14 namespace brillo {
15 
16 using DmTaskPtr = std::unique_ptr<dm_task, void (*)(dm_task*)>;
17 
18 // Abstract class to manage DM devices.
19 // This class implements the bare minimum set of functions
20 // required to create/remove DM devices. DevmapperTask is the equivalent
21 // of a command to the device mapper to set/get targets associated with a
22 // logical DM device, but omits, for now, finer-grained commands.
23 // A target represents a segment of a DM device.
24 //
25 // The abstract class is strictly based on the dm_task_* functions
26 // from libdevmapper, but the interface provides sufficient flexibility
27 // for other implementations (eg. invoking dmsetup) or testing facades.
28 //
29 // The task type enum is defined in libdevmapper.h: for simplicity, the same
30 // enum types are reused in fake implementations of DevmapperTask.
31 // The following task types have been tested with DeviceMapper functions:
32 // - DM_DEVICE_CREATE: used in DeviceMapper::Setup.
33 // - DM_DEVICE_REMOVE: used in DeviceMapper::Remove.
34 // - DM_DEVICE_TABLE: used in DeviceMapper::GetTable and
35 //                    DeviceMapper::WipeTable.
36 // - DM_DEVICE_RELOAD: used in DeviceMapper::WipeTable.
37 class DevmapperTask {
38  public:
39   virtual ~DevmapperTask() = default;
40   // Sets device name for the command.
41   virtual bool SetName(const std::string& name) = 0;
42 
43   // Adds a target to the command. Should be followed by a Run();
44   // Parameters:
45   //   start: start of target in device.
46   //   sectors: number of sectors in the target.
47   //   type: type of the target.
48   //   parameters: target parameters.
49   virtual bool AddTarget(uint64_t start,
50                          uint64_t sectors,
51                          const std::string& type,
52                          const SecureBlob& parameters) = 0;
53   // Gets the next target from the command.
54   // Returns true while another target exists.
55   // If no target exist for the device, GetNextTarget sets all
56   // parameters to 0 and returns false.
57   //
58   // Parameters:
59   //   start: start of target in device.
60   //   sectors: number of sectors in the target.
61   //   type: type of the target.
62   //   parameters: target parameters.
63   virtual bool GetNextTarget(uint64_t* start,
64                              uint64_t* sectors,
65                              std::string* type,
66                              SecureBlob* parameters) = 0;
67   // Run the task.
68   // Returns true if the task succeeded.
69   //
70   // Parameters:
71   //   udev_sync: Enable/Disable udev_synchronization. Defaults to false.
72   //              Enable only for tasks that create/remove/rename files to
73   //              prevent both udevd and libdevmapper from attempting to
74   //              add or remove files.
75   virtual bool Run(bool udev_sync = false) = 0;
76 };
77 
78 // Libdevmapper implementation for DevmapperTask.
79 class DevmapperTaskImpl : public DevmapperTask {
80  public:
81   explicit DevmapperTaskImpl(int type);
82   ~DevmapperTaskImpl() override = default;
83   bool SetName(const std::string& name) override;
84   bool AddTarget(uint64_t start,
85                  uint64_t sectors,
86                  const std::string& target,
87                  const SecureBlob& parameters) override;
88   bool GetNextTarget(uint64_t* start,
89                      uint64_t* sectors,
90                      std::string* target,
91                      SecureBlob* parameters) override;
92   bool Run(bool udev_sync = true) override;
93 
94  private:
95   DmTaskPtr task_;
96   void* next_target_ = nullptr;
97 };
98 
99 }  // namespace brillo
100 
101 #endif  // LIBBRILLO_BRILLO_BLKDEV_UTILS_DEVICE_MAPPER_TASK_H_
102