blob: 44b9dc43276c5d202061e47ca15ce284e59657da [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CROS_DISKS_DISK_MANAGER_H_
#define CROS_DISKS_DISK_MANAGER_H_
#include <libudev.h>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include <base/callback.h>
#include <base/macros.h>
#include <gtest/gtest_prod.h>
#include "cros-disks/disk.h"
#include "cros-disks/mount_manager.h"
namespace cros_disks {
class DeviceEjector;
class DiskMonitor;
class MounterCompat;
class Platform;
struct Filesystem;
// The DiskManager is responsible for mounting removable media.
//
// This class is designed to run within a single-threaded GMainLoop application
// and should not be considered thread safe.
class DiskManager : public MountManager {
public:
DiskManager(const std::string& mount_root,
Platform* platform,
Metrics* metrics,
brillo::ProcessReaper* process_reaper,
DiskMonitor* disk_monitor,
DeviceEjector* device_ejector);
~DiskManager() override;
// Initializes the disk manager and registers default filesystems.
// Returns true on success.
bool Initialize() override;
// Returns true if mounting |source_path| is supported.
bool CanMount(const std::string& source_path) const override;
// Returns the type of mount sources supported by the manager.
MountSourceType GetMountSourceType() const override {
return MOUNT_SOURCE_REMOVABLE_DEVICE;
}
// Unmounts all mounted paths.
bool UnmountAll() override;
// Registers a set of default filesystems to the disk manager.
void RegisterDefaultFilesystems();
// Registers a filesystem to the disk manager.
// Subsequent registrations of the same filesystem type are ignored.
void RegisterFilesystem(const Filesystem& filesystem);
protected:
// Mounts |source_path| to |mount_path| as |filesystem_type| with |options|.
std::unique_ptr<MountPoint> DoMount(const std::string& source_path,
const std::string& filesystem_type,
const std::vector<std::string>& options,
const base::FilePath& mount_path,
MountOptions* applied_options,
MountErrorType* error) override;
// Returns a suggested mount path for a source path.
std::string SuggestMountPath(const std::string& source_path) const override;
// Returns true to reserve a mount path on errors due to unknown or
// unsupported filesystems.
bool ShouldReserveMountPathOnError(MountErrorType error_type) const override;
private:
// MountPoint implementation that ejects the device on unmount.
class EjectingMountPoint;
// Creates an appropriate mounter object for a given filesystem.
std::unique_ptr<MounterCompat> CreateMounter(
const Disk& disk,
const Filesystem& filesystem,
const std::string& target_path,
const std::vector<std::string>& options) const;
// Returns a Filesystem object if a given filesystem type is supported.
// Otherwise, it returns NULL. This pointer is owned by the DiskManager.
const Filesystem* GetFilesystem(const std::string& filesystem_type) const;
// Ejects media for the device |device_file|. Return true if the eject process
// has started or |eject_device_on_unmount_| is false, or false if the eject
// process failed.
bool EjectDevice(const std::string& device_file);
// If |disk| is an optical disk, wrap |mount_point| in a wrapper that ejects
// the disk on a successful unmount. If |disk| is not an optical disk, returns
// |mount_point|. This is exposed as a function to allow ejecting behaviour to
// be tested.
std::unique_ptr<MountPoint> MaybeWrapMountPointForEject(
std::unique_ptr<MountPoint> mount_point, const Disk& disk);
DiskMonitor* const disk_monitor_;
DeviceEjector* const device_ejector_;
// Set to true if devices should be ejected upon unmount.
bool eject_device_on_unmount_;
// A mapping from a mount path to the corresponding device that should
// be ejected on unmount.
std::map<std::string, Disk> devices_to_eject_on_unmount_;
// A set of supported filesystems indexed by filesystem type.
std::map<std::string, Filesystem> filesystems_;
FRIEND_TEST(DiskManagerTest, CreateExFATMounter);
FRIEND_TEST(DiskManagerTest, CreateNTFSMounter);
FRIEND_TEST(DiskManagerTest, CreateVFATSystemMounter);
FRIEND_TEST(DiskManagerTest, CreateExt4SystemMounter);
FRIEND_TEST(DiskManagerTest, GetFilesystem);
FRIEND_TEST(DiskManagerTest, RegisterFilesystem);
FRIEND_TEST(DiskManagerTest, DoMountDiskWithNonexistentSourcePath);
FRIEND_TEST(DiskManagerTest, EjectDevice);
FRIEND_TEST(DiskManagerTest, EjectDeviceWhenUnmountFailed);
FRIEND_TEST(DiskManagerTest, EjectDeviceWhenExplicitlyDisabled);
FRIEND_TEST(DiskManagerTest, EjectDeviceWhenReleased);
DISALLOW_COPY_AND_ASSIGN(DiskManager);
};
} // namespace cros_disks
#endif // CROS_DISKS_DISK_MANAGER_H_