Skip to content

Commit

Permalink
Merge pull request #607 from joseivanlopez/flash_bcache_keep_abi
Browse files Browse the repository at this point in the history
Add support for flash-only bcache (with ABI compatibility)
  • Loading branch information
joseivanlopez committed Jan 30, 2019
2 parents 8dc5fae + 270047e commit 8f4000c
Show file tree
Hide file tree
Showing 28 changed files with 2,248 additions and 122 deletions.
2 changes: 1 addition & 1 deletion LIBVERSION
@@ -1 +1 @@
1.6.1
1.7.0
4 changes: 4 additions & 0 deletions bindings/storage-catches.i
Expand Up @@ -144,6 +144,8 @@
%catches(storage::Exception) storage::Bcache::attach_bcache_cset(BcacheCset *bcache_cset);
%catches(storage::DeviceNotFound, storage::DeviceHasWrongType) storage::Bcache::find_by_name(Devicegraph *devicegraph, const std::string &name);
%catches(storage::DeviceNotFound, storage::DeviceHasWrongType) storage::Bcache::find_by_name(const Devicegraph *devicegraph, const std::string &name);
%catches(storage::Exception) storage::Bcache::get_backing_device() const;
%catches(storage::Exception) storage::Bcache::get_blk_device() const;
%catches(storage::DeviceNotFound, storage::DeviceHasWrongType) storage::BcacheCset::find_by_uuid(Devicegraph *devicegraph, const std::string &uuid);
%catches(storage::DeviceNotFound, storage::DeviceHasWrongType) storage::BcacheCset::find_by_uuid(const Devicegraph *devicegraph, const std::string &uuid);
%catches(storage::WrongNumberOfChildren) storage::BlkDevice::create_bcache_cset();
Expand All @@ -165,6 +167,8 @@
%catches(storage::Exception) storage::BlkFilesystem::detect_content_info() const;
%catches(storage::BtrfsSubvolumeNotFoundByPath) storage::Btrfs::find_btrfs_subvolume_by_path(const std::string &path);
%catches(storage::BtrfsSubvolumeNotFoundByPath) storage::Btrfs::find_btrfs_subvolume_by_path(const std::string &path) const;
%catches(storage::DeviceNotFound) storage::CompoundAction::find_by_target_device(Actiongraph *actiongraph, const Device *device);
%catches(storage::DeviceNotFound) storage::CompoundAction::find_by_target_device(const Actiongraph *actiongraph, const Device *device);
%catches(storage::DeviceNotFound, storage::DeviceHasWrongType) storage::Dasd::find_by_name(Devicegraph *devicegraph, const std::string &name);
%catches(storage::DeviceNotFound, storage::DeviceHasWrongType) storage::Dasd::find_by_name(const Devicegraph *devicegraph, const std::string &name);
%catches(storage::Exception) storage::Device::compare_by_name(const Device *lhs, const Device *rhs);
Expand Down
3 changes: 2 additions & 1 deletion doc/autodocs/doxygen.conf
Expand Up @@ -13,7 +13,8 @@ TAB_SIZE = 8

INPUT = ../../storage
FILE_PATTERNS = Actiongraph.h Devicegraph.h Environment.h FreeInfo.h Graphviz.h \
SimpleEtcFstab.h SimpleEtcCrypttab.h Storage.h UsedFeatures.h Version.h
SimpleEtcFstab.h SimpleEtcCrypttab.h Storage.h UsedFeatures.h Version.h \
CompoundAction.h

INPUT += ../../storage/Devices
FILE_PATTERNS += BcacheCset.h Bcache.h BlkDevice.h Dasd.h DasdPt.h Device.h \
Expand Down
80 changes: 80 additions & 0 deletions doc/bcache.md
@@ -0,0 +1,80 @@
# Bcache

Bcache technology allows to speed up the access (read and write) for slow devices. The idea
consists on using a fast device (e.g., SSD) as caching device.

Bcache manages three kind of devices: caching set, bcache device and flash-only bcache device.

## Caching Set

A caching set (a.k.a. cset) is used for caching the data from a bcache device. A cset can use several
caching devices at the same time. And a caching device can be any block device (partition, raid, disk,
etc).

Currently, Bcache implementation only supports cset with one caching device. A cset is represented by
`BcacheCset` class in libstorage-ng.

## Bcache device

A Bcache device represents a block device that is using a cset for caching read/write operations. The
Bcache device is created over a backing device, and the backing device can be any block device.

A Bcache device could use none cset at all, so IO is directly performed over the backing device.

A Bcache device supports all operations that can be performed over a block device, so it could be
partitioned, encrypted, formatted, etc. Bcache device is represented by `Bcache` class in libstorage-ng
(with `type` attribute set to `BcacheType::BACKED` value).

## Flash-only Bcache device

A Flash-only Bcache is an special type of bcache. It has no backing device, and it is directly created
over a cset.

Several Flash-only Bcache devices can be created over the same cset. They can be used as a regular block
device. A Flash-only Bcache device is also represented by `Bcache` class in libstorage-ng (but with
`type` attribute set to `BcacheType::FLASH_ONLY` value).


# `bcache` command

Currently, libstorage-ng performs several operations (attach, delete, etc) by directly touching certain
files in `/sys` directory. Moreover, it uses `make-bcache` for creating a cset or a Backed Bcache device.

The `bcache-tools` package is now shipping a new `bcache` command. This command is a little bit more
powerful, and some actions could be delegated to it instead of touching `/sys` files.

## Probing

For probing, libstorage-ng inspects `/dev` and `/sys` directories. The command `bcache show` does not
help in this case, because it is not aware about Flash-only Bcache devices.

## Creating

`bcache make -C` and `bcache make -B` can be use for creating a cset and a Bcache device respectively.
Such commands are simply links to `make-bcache`, but we could stop using `make-bcache` if favor of new
`bcache`.

Currently, `bcache` command has no option to create a Flash-only Bcache device, so this kind of devices
must be still created by touching `/sys`:

```
echo 100M > /sys/fs/bcache/[uuid]/flash_only_create
```

## Attach/Detach

Command `bcache attach` can be used to attach a cset to a Backing Bcache. There is also a `bcache detach`
for detaching the cset.

## Unregister

Command `bcache unregister` allows to delete a cset or bcache device. This command is responsible of flushing
pending data.

## Cache mode

The cache mode of a Backed Bcache can be permanently saved with the command `bcache set-cachemode`.

## Missing options

A way for permanently saving Backed Bcache properties like `sequential_cutoff` and `writeback_percent`.
15 changes: 14 additions & 1 deletion storage/CompoundAction.cc
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 SUSE LLC
* Copyright (c) [2017-2019] SUSE LLC
*
* All Rights Reserved.
*
Expand Down Expand Up @@ -53,5 +53,18 @@ namespace storage
return get_impl().is_delete();
}

CompoundAction*
CompoundAction::find_by_target_device(Actiongraph* actiongraph, const Device* device)
{
return CompoundAction::Impl::find_by_target_device(actiongraph, device);
}


const CompoundAction*
CompoundAction::find_by_target_device(const Actiongraph* actiongraph, const Device* device)
{
return CompoundAction::Impl::find_by_target_device(actiongraph, device);
}

}

18 changes: 17 additions & 1 deletion storage/CompoundAction.h
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 SUSE LLC
* Copyright (c) [2017-2019] SUSE LLC
*
* All Rights Reserved.
*
Expand Down Expand Up @@ -40,6 +40,12 @@ namespace storage
class Actiongraph;
class Device;

/**
* A Compound Action groups several related actions from an actiongraph.
*
* For example, when a partition is created and then formatted and mounted,
* a Compound Action is created with all that individual actions.
*/
class CompoundAction : private boost::noncopyable
{

Expand All @@ -54,6 +60,16 @@ namespace storage

bool is_delete() const;

/**
* @throw DeviceNotFound
*/
static CompoundAction* find_by_target_device(Actiongraph* actiongraph, const Device* device);

/**
* @throw DeviceNotFound
*/
static const CompoundAction* find_by_target_device(const Actiongraph* actiongraph, const Device* device);

public:

class Generator;
Expand Down
31 changes: 27 additions & 4 deletions storage/CompoundAction/Formatter/Bcache.cc
Expand Up @@ -24,18 +24,17 @@

#include "storage/CompoundAction/Formatter/Bcache.h"
#include "storage/Devices/BcacheImpl.h"
#include "storage/Devices/BcacheCsetImpl.h"
#include "storage/Filesystems/Swap.h"
#include "storage/Utils/Format.h"
#include "storage/Utils/ExceptionImpl.h"


namespace storage
{

CompoundAction::Formatter::Bcache::Bcache( const CompoundAction::Impl* compound_action ):
CompoundAction::Formatter( compound_action, "Bcache" ),
bcache( to_bcache( compound_action->get_target_device() ) ),
bcache_cset( bcache->get_bcache_cset() )
bcache( to_bcache( compound_action->get_target_device() ) )
{
// NOP
}
Expand Down Expand Up @@ -119,7 +118,15 @@ namespace storage
Text
CompoundAction::Formatter::Bcache::bcache_cset_text() const
{
Text dev_list_text = format_devices_text( bcache_cset->get_blk_devices() );
// Text related to cset is not shown for Flash-only bcache devices
if(bcache->get_type() == BcacheType::FLASH_ONLY)
return Text();

// A Bcache might not have an associated caching set
if(!bcache->has_bcache_cset())
return Text();

Text dev_list_text = format_devices_text( bcache->get_bcache_cset()->get_blk_devices() );

// TRANSLATORS:
// %1$s is replaced with the the bcache name (e.g. /dev/bcache0),
Expand Down Expand Up @@ -400,4 +407,20 @@ namespace storage
mount_point.c_str() );
}


const BlkDevice*
CompoundAction::Formatter::Bcache::get_blk_device() const {
if(bcache->get_type() == BcacheType::BACKED)
return bcache->get_backing_device();
else
{
vector<const BlkDevice*> caching_devices = bcache->get_bcache_cset()->get_blk_devices();

if(caching_devices.empty())
ST_THROW(Exception("Flash-only Bcache without caching device"));

return caching_devices.front();
}
}

}
12 changes: 8 additions & 4 deletions storage/CompoundAction/Formatter/Bcache.h
Expand Up @@ -26,7 +26,6 @@

#include "storage/CompoundAction/Formatter.h"
#include "storage/Devices/Bcache.h"
#include "storage/Filesystems/BlkFilesystem.h"


namespace storage
Expand Down Expand Up @@ -65,13 +64,18 @@ namespace storage
Text mount_point_text() const;

string get_bcache_name() const { return bcache->get_name(); }
string get_device_name() const { return bcache->get_blk_device()->get_name(); }
string get_size() const { return bcache->get_size_string(); }
string get_device_name() const { return get_blk_device()->get_name(); }

/**
* Block device associated to the Bcache. Normally it is the backing device,
* but for a Flash-only Bcache, it represents its caching device.
*/
const BlkDevice* get_blk_device() const;

private:

const storage::Bcache * bcache;
const storage::BcacheCset * bcache_cset;
const storage::Bcache* bcache;
};

}
Expand Down
25 changes: 23 additions & 2 deletions storage/CompoundActionImpl.cc
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 SUSE LLC
* Copyright (c) [2017-2019] SUSE LLC
*
* All Rights Reserved.
*
Expand Down Expand Up @@ -42,6 +42,7 @@
#include "storage/Filesystems/BlkFilesystem.h"
#include "storage/Filesystems/MountPoint.h"
#include "storage/Utils/Exception.h"
#include "storage/Utils/Format.h"


namespace storage
Expand Down Expand Up @@ -128,7 +129,7 @@ namespace storage
else if (is_nfs(target_device))
return CompoundAction::Formatter::Nfs(this).string_representation();

else if (is_bcache(target_device) || is_bcache_cset(target_device))
else if (is_bcache(target_device))
return CompoundAction::Formatter::Bcache(this).string_representation();

else if (is_md(target_device))
Expand Down Expand Up @@ -271,5 +272,25 @@ namespace storage
return action->get_device(actiongraph->get_impl());
}


CompoundAction*
CompoundAction::Impl::find_by_target_device(Actiongraph* actiongraph, const Device* device)
{
return const_cast<CompoundAction*>(find_by_target_device(static_cast<const Actiongraph*>(actiongraph), device));
}


const CompoundAction*
CompoundAction::Impl::find_by_target_device(const Actiongraph* actiongraph, const Device* device)
{
for (auto action : actiongraph->get_compound_actions())
{
if (action->get_target_device() == device)
return action;
}

ST_THROW(DeviceNotFound(sformat("target device not found, sid:%d", device->get_sid())));
}

}

5 changes: 4 additions & 1 deletion storage/CompoundActionImpl.h
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 SUSE LLC
* Copyright (c) [2017-2019] SUSE LLC
*
* All Rights Reserved.
*
Expand Down Expand Up @@ -79,6 +79,9 @@ namespace storage
static const Device* device(const Actiongraph* actiongraph, const Action::Modify* action);
static const Device* device(const Actiongraph* actiongraph, const Action::Delete* action);

static CompoundAction* find_by_target_device(Actiongraph* actiongraph, const Device* device);
static const CompoundAction* find_by_target_device(const Actiongraph* actiongraph, const Device* device);

private:

const Actiongraph* actiongraph;
Expand Down
29 changes: 25 additions & 4 deletions storage/Devices/Bcache.cc
@@ -1,5 +1,5 @@
/*
* Copyright (c) [2016,2018] SUSE LLC
* Copyright (c) [2016-2019] SUSE LLC
*
* All Rights Reserved.
*
Expand All @@ -21,7 +21,7 @@


#include "storage/Devices/BcacheImpl.h"
#include "storage/Devicegraph.h"
#include "storage/Devices/DeviceImpl.h"


namespace storage
Expand All @@ -33,7 +33,14 @@ namespace storage
Bcache*
Bcache::create(Devicegraph* devicegraph, const string& name)
{
Bcache* ret = new Bcache(new Bcache::Impl(name));
return Bcache::create(devicegraph, name, BcacheType::BACKED);
}


Bcache*
Bcache::create(Devicegraph* devicegraph, const string& name, BcacheType type)
{
Bcache* ret = new Bcache(new Bcache::Impl(name, type));
ret->Device::create(devicegraph);
return ret;
}
Expand Down Expand Up @@ -75,17 +82,31 @@ namespace storage
}


BcacheType
Bcache::get_type() const
{
return get_impl().get_type();
}


unsigned int
Bcache::get_number() const
{
return get_impl().get_number();
}


const BlkDevice*
Bcache::get_backing_device() const
{
return get_impl().get_backing_device();
}


const BlkDevice*
Bcache::get_blk_device() const
{
return get_impl().get_blk_device();
return get_backing_device();
}


Expand Down

0 comments on commit 8f4000c

Please sign in to comment.