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_LOOP_DEVICE_H_ 6 #define LIBBRILLO_BRILLO_BLKDEV_UTILS_LOOP_DEVICE_H_ 7 8 #include <linux/loop.h> 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 #include <base/bind.h> 14 #include <base/callback.h> 15 #include <base/files/file_path.h> 16 #include <brillo/secure_blob.h> 17 18 namespace brillo { 19 20 // Forward declaration used by LoopDevice. 21 class LoopDeviceManager; 22 23 using LoopIoctl = 24 base::Callback<int(const base::FilePath&, int, uint64_t, int)>; 25 26 // LoopDevice provides an interface to attached loop devices. 27 // In order to simplify handling of loop devices, there 28 // is no inherent modifiable state associated within objects: 29 // the device number and backing file are consts. 30 // The intent here is for no class to create a LoopDevice 31 // directly; instead use LoopDeviceManager to get devices. 32 class BRILLO_EXPORT LoopDevice { 33 public: 34 // Create a loop device with a ioctl runner. 35 // Parameters 36 // device_number - loop device number. 37 // backing_file - backing file for the device. 38 // ioctl_runner - function to run loop ioctls. 39 LoopDevice(int device_number, 40 const base::FilePath& backing_file, 41 const LoopIoctl& ioctl_runner); 42 ~LoopDevice() = default; 43 44 // Set device status. 45 // Parameters 46 // info - struct containing status. 47 bool SetStatus(struct loop_info64 info); 48 // Get device status. 49 // Parameters 50 // info - struct to populate. 51 bool GetStatus(struct loop_info64* info); 52 // Set device name. 53 // Parameters 54 // name - device name 55 bool SetName(const std::string& name); 56 // Detach device. 57 bool Detach(); 58 // Check if device is valid; 59 bool IsValid(); 60 61 // Getters for device parameters. GetBackingFilePath()62 base::FilePath GetBackingFilePath() { return backing_file_; } 63 base::FilePath GetDevicePath(); 64 65 private: 66 const int device_number_; 67 const base::FilePath backing_file_; 68 // Ioctl runner. 69 LoopIoctl loop_ioctl_; 70 }; 71 72 // Loop Device Manager handles requests for creating or fetching 73 // existing loop devices. If creation/fetch fails, the loop device 74 // manager returns nullptr. 75 class BRILLO_EXPORT LoopDeviceManager { 76 public: 77 LoopDeviceManager(); 78 // Create a loop device manager with a non-default ioctl runner. 79 // Parameters 80 // ioctl_runner - base::Callback to run ioctls. 81 explicit LoopDeviceManager(LoopIoctl ioctl_runner); 82 virtual ~LoopDeviceManager() = default; 83 84 // Allocates a loop device and attaches it to a backing file. 85 // Parameters 86 // backing_file - file to attach device to. 87 virtual std::unique_ptr<LoopDevice> AttachDeviceToFile( 88 const base::FilePath& backing_file); 89 90 // Fetches all attached loop devices. 91 std::vector<std::unique_ptr<LoopDevice>> GetAttachedDevices(); 92 93 // Fetches a loop device by device number. 94 std::unique_ptr<LoopDevice> GetAttachedDeviceByNumber(int device_number); 95 96 // Fetches a device number by name. 97 std::unique_ptr<LoopDevice> GetAttachedDeviceByName(const std::string& name); 98 99 private: 100 // Search for loop devices by device number; if no device number is given, 101 // default to searaching and returning all loop devices. 102 virtual std::vector<std::unique_ptr<LoopDevice>> SearchLoopDevicePaths( 103 int device_number = -1); 104 // Create loop device with current ioctl runner. 105 // Parameters 106 // device_number - device number. 107 // backing_file - path to backing file. 108 std::unique_ptr<LoopDevice> CreateLoopDevice( 109 int device_number, const base::FilePath& backing_file); 110 111 LoopIoctl loop_ioctl_; 112 DISALLOW_COPY_AND_ASSIGN(LoopDeviceManager); 113 }; 114 115 } // namespace brillo 116 117 #endif // LIBBRILLO_BRILLO_BLKDEV_UTILS_LOOP_DEVICE_H_ 118