blob: 3c54ed86a41a97389e16b773d8c1dd2a1369cecc [file] [log] [blame]
Sergei Datsenko16821892019-04-05 11:26:38 +11001// Copyright 2019 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 CROS_DISKS_DISK_MONITOR_H_
6#define CROS_DISKS_DISK_MONITOR_H_
7
Sergei Datsenko16821892019-04-05 11:26:38 +11008#include <map>
9#include <memory>
10#include <set>
11#include <string>
12#include <vector>
13
14#include <base/callback.h>
15#include <base/files/file_path.h>
Sergei Datsenko16821892019-04-05 11:26:38 +110016#include <gtest/gtest_prod.h>
17
18#include "cros-disks/device_event.h"
19#include "cros-disks/device_event_source_interface.h"
20#include "cros-disks/disk.h"
21#include "cros-disks/mount_manager.h"
22
Anand K Mistry5757f632019-09-11 13:29:41 +100023namespace brillo {
24class Udev;
25class UdevDevice;
26class UdevMonitor;
27} // namespace brillo
28
Sergei Datsenko16821892019-04-05 11:26:38 +110029namespace cros_disks {
30
31// The DiskMonitor is responsible for reading device state from udev.
32// Said changes could be the result of a udev notification or a synchronous
33// call to enumerate the relevant storage devices attached to the system.
34//
35// This class is designed to run within a single-threaded GMainLoop application
36// and should not be considered thread safe.
37class DiskMonitor : public DeviceEventSourceInterface {
38 public:
39 DiskMonitor();
Qijiang Fan6bc59e12020-11-11 02:51:06 +090040 DiskMonitor(const DiskMonitor&) = delete;
41 DiskMonitor& operator=(const DiskMonitor&) = delete;
42
Sergei Datsenko16821892019-04-05 11:26:38 +110043 ~DiskMonitor() override;
44
45 // Initializes the disk monitor.
46 // Returns true on success.
47 virtual bool Initialize();
48
49 // Lists the current block devices attached to the system.
50 virtual std::vector<Disk> EnumerateDisks() const;
51
52 // Gets a Disk object that corresponds to a given device file.
53 virtual bool GetDiskByDevicePath(const base::FilePath& device_path,
54 Disk* disk) const;
55
Sergei Datsenko16821892019-04-05 11:26:38 +110056 // A file descriptor that can be select()ed or poll()ed for system changes.
Anand K Mistry5757f632019-09-11 13:29:41 +100057 int udev_monitor_fd() const;
Sergei Datsenko16821892019-04-05 11:26:38 +110058
59 // Implements the DeviceEventSourceInterface interface to read the changes
60 // from udev and converts the changes into device events. Returns false on
61 // error or if not device event is available. Must be called to clear the fd.
62 bool GetDeviceEvents(DeviceEventList* events) override;
63
Sergei Datsenkoad8b5042020-09-21 22:39:04 +100064 // Adds the specified device to a list allowing it to be used despite
65 // not having certain properties. Used by tests to perform operations on
66 // loopback devices.
67 void AddDeviceToAllowlist(const base::FilePath& device);
68 void RemoveDeviceFromAllowlist(const base::FilePath& device);
69
Sergei Datsenko16821892019-04-05 11:26:38 +110070 private:
François Degros16ad1ae2019-07-17 16:02:39 +100071 // An EnumerateBlockDevices callback that emulates an 'add' action on
72 // |device|. Always returns true to continue enumeration in
73 // EnumerateBlockDevices.
Anand K Mistry5757f632019-09-11 13:29:41 +100074 bool EmulateAddBlockDeviceEvent(std::unique_ptr<brillo::UdevDevice> device);
Sergei Datsenko16821892019-04-05 11:26:38 +110075
76 // Enumerates the block devices on the system and invokes |callback| for each
Anand K Mistry5757f632019-09-11 13:29:41 +100077 // device found during the enumeration. The enumeration stops if |callback|
78 // returns false.
Sergei Datsenko16821892019-04-05 11:26:38 +110079 void EnumerateBlockDevices(
Anand K Mistryc0ece3d2020-01-28 15:55:29 +110080 base::RepeatingCallback<bool(std::unique_ptr<brillo::UdevDevice> dev)>
Anand K Mistry5757f632019-09-11 13:29:41 +100081 callback) const;
Sergei Datsenko16821892019-04-05 11:26:38 +110082
83 // Determines one or more device/disk events from a udev block device change.
Anand K Mistry5757f632019-09-11 13:29:41 +100084 void ProcessBlockDeviceEvents(std::unique_ptr<brillo::UdevDevice> device,
Sergei Datsenko16821892019-04-05 11:26:38 +110085 const char* action,
86 DeviceEventList* events);
87
88 // Determines one or more device/disk events from a udev MMC or SCSI device
89 // change.
Anand K Mistry5757f632019-09-11 13:29:41 +100090 void ProcessMmcOrScsiDeviceEvents(std::unique_ptr<brillo::UdevDevice> device,
Sergei Datsenko16821892019-04-05 11:26:38 +110091 const char* action,
92 DeviceEventList* events);
93
94 // The root udev object.
Anand K Mistry5757f632019-09-11 13:29:41 +100095 std::unique_ptr<brillo::Udev> udev_;
Sergei Datsenko16821892019-04-05 11:26:38 +110096
97 // Provides access to udev changes as they occur.
Anand K Mistry5757f632019-09-11 13:29:41 +100098 std::unique_ptr<brillo::UdevMonitor> udev_monitor_;
Sergei Datsenko16821892019-04-05 11:26:38 +110099
100 // A set of device sysfs paths detected by the udev monitor.
101 std::set<std::string> devices_detected_;
102
103 // A mapping from a sysfs path of a disk, detected by the udev monitor,
104 // to a set of sysfs paths of the immediate children of the disk.
105 std::map<std::string, std::set<std::string>> disks_detected_;
106
Sergei Datsenkoad8b5042020-09-21 22:39:04 +1000107 std::set<std::string> allowlist_;
Sergei Datsenko16821892019-04-05 11:26:38 +1100108};
109
110} // namespace cros_disks
111
Ben Chana9181d62019-04-10 16:29:10 -0700112#endif // CROS_DISKS_DISK_MONITOR_H_