Skip to content

Commit b314efc

Browse files
tiagolobocastroshubham14bajpaiakhilerm
committed
feat(lvm): add lvm pool and replica support
Add LVM as an experimental alternative backend to Mayastor: 1. it allows us to use a low latency single replica local volume (app pinned to the same node) 2. robust backend for existing LVM users which may prefer it 3. combine local engines into mayastor This differs from the existing lvm localpv as rather than importing the existing VGs we create the LVM PV's and the LVM VG itself. On destruction, if the VG has no non-mayastor LVs then we destroy it, otherwise we leave it behind, untagged. The existing pool/replica services are also refactored to support adding other backends in the future as well. This is achieved by implementing the service interface separately and binding them at a higher level. This way it avoids mixing the backend code, at least as much as possible. Co-authored-by: shubham <shubham.bajpai@mayadata.io> Co-authored-by: Akhil Mohan <akhil.mohan@mayadata.io> Co-authored-by: Tiago Castro <tiagolobocastro@gmail.com> Signed-off-by: Tiago Castro <tiagolobocastro@gmail.com>
1 parent 3a9face commit b314efc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+4482
-703
lines changed

ci.nix

+2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ mkShell {
7272
SPDK_PATH = if nospdk then null else "${spdk}";
7373
FIO_SPDK = if nospdk then null else "${spdk}/fio/spdk_nvme";
7474
ETCD_BIN = "${etcd}/bin/etcd";
75+
LVM_BINS = "${lvm2.bin}/bin";
7576

7677
IO_ENGINE_DIR = if asan then "target/x86_64-unknown-linux-gnu/debug" else "target/debug";
7778

@@ -102,6 +103,7 @@ mkShell {
102103
${pkgs.lib.optionalString (!nospdk) "echo 'SPDK version :' $(echo $SPDK_PATH | sed 's/.*libspdk-//g')"}
103104
${pkgs.lib.optionalString (!nospdk) "echo 'SPDK path :' $SPDK_PATH"}
104105
${pkgs.lib.optionalString (!nospdk) "echo 'SPDK FIO plugin :' $FIO_SPDK"}
106+
echo 'LVM path :' $LVM_BINS
105107
${pkgs.lib.optionalString (!norust) "echo 'Rust version :' $(rustc --version 2> /dev/null || echo '${norustc_msg}')"}
106108
${pkgs.lib.optionalString (!norust) "echo 'Rust path :' $(which rustc 2> /dev/null || echo '${norustc_msg}')"}
107109
echo 'I/O engine dir :' $IO_ENGINE_DIR

doc/lvm.md

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# LVM as an alternative backend to Mayastor (Experimental!)
2+
3+
Mayastor, a cloud-native declarative data plane written in Rust, aims to abstract storage resources
4+
and their differences through the data plane.
5+
6+
In this document, we’ll explore how to integrate Logical Volume Management (LVM) as an alternative
7+
backend for Mayastor pools.
8+
LVM, a mature and widely adopted storage management system in Linux environments, offers robustness
9+
and extensive features that can enhance Mayastor’s storage services.
10+
11+
## Motivation
12+
13+
LVM is a mature and widely adopted storage management system in Linux environments.
14+
While the SPDK Blobstore (LVS) has been a reliable option, integrating LVM as an alternative backend
15+
can captivate a broader audience due to its robustness and maturity, feature set,
16+
and community support make it an attractive choice for Mayastor users.
17+
By integrating LVM, we can also allow users to upgrade existing non-replicated LVM volumes
18+
(eg: lvm-localpv) seamlessly.
19+
20+
## Goals
21+
22+
Alternative Backend: Enable Mayastor to use LVM volume groups as an alternative backend for storage
23+
pools.
24+
Dynamic Volume Management: Leverage LVM’s volume management features (resizing, snapshots,
25+
thin provisioning) within Mayastor.
26+
Simplicity: Abstract LVM complexities from users while providing robust storage services.
27+
28+
### Supporting Changes
29+
1. Pools
30+
31+
Mayastor pools represent devices supplying persistent backing storage.
32+
Introduce a new pool type: LVM Pool.
33+
Users can create new Mayastor pools with the LVM backend type.
34+
35+
2. LVM Integration
36+
37+
Extend Mayastor to integrate with LVM.
38+
Implement LVM-specific logic for pool and replica creation, replica resizing, and snapshot management.
39+
Ensure seamless interaction between Mayastor and LVM.
40+
41+
3. Replication (HA)
42+
43+
Extend Mayastor’s replication mechanisms to work with LVM-backed logical units.
44+
In short, make LVM backed volumes highly available across nodes.
45+
46+
4. Volume Management
47+
48+
Mayastor will expose LVM volume management features through its pool API.
49+
Users can resize volumes online.
50+
Snapshots are managed transparently.
51+
52+
Features
53+
---
54+
55+
- [x] Pool Operations
56+
- [x] Create
57+
- [x] Destroy
58+
- [x] Import
59+
- [x] List
60+
- [x] Replica Operations
61+
- [x] Create
62+
- [x] Destroy
63+
- [x] Share/Unshare
64+
- [x] Resize
65+
- [x] List
66+
- [ ] Thin Provisioning
67+
- [ ] Snapshots
68+
- [ ] Clones
69+
- [ ] RAIDx
70+
71+
### Limitation
72+
- Thin provisioning and snapshot support is not yet integrated
73+
- RAID is not yet integrated
74+
75+
## Conclusion
76+
77+
By integrating LVM with Mayastor, you can leverage the benefits of both technologies. LVM provides dynamic volume management,
78+
while Mayastor abstracts storage complexities, allowing you to focus on your applications.
79+
Happy storage provisioning! 🚀
80+
81+
82+
```mermaid
83+
graph TD;
84+
subgraph Volume Group - VG
85+
VG_1 --> LV_1["replica 1"]
86+
VG_1 --> LV_2["replica 2"]
87+
VG_2 --> LV_3["replica 3"]
88+
end
89+
90+
subgraph Mayastor Volume
91+
LV_1 --> VOL_1["1-replica volume"]
92+
LV_2 --> VOL_2["2-replica volume"]
93+
LV_3 --> VOL_2["2-replica volume"]
94+
end
95+
96+
subgraph Physical Volumes
97+
PV_1 --> VG_1["Volume Group - VG 1"]
98+
PV_2 --> VG_1
99+
PV_3 --> VG_2["Volume Group - VG 2"]
100+
end
101+
102+
subgraph Node1
103+
/dev/sda --> PV_1
104+
/dev/sdb --> PV_2
105+
end
106+
subgraph Node2
107+
/dev/sdc --> PV_3
108+
end
109+
```

io-engine-tests/src/pool.rs

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ impl PoolBuilder {
118118
uuid: None,
119119
pooluuid: self.uuid.clone(),
120120
query: None,
121+
pooltypes: vec![],
121122
})
122123
.await
123124
.map(|r| r.into_inner().replicas)

io-engine-tests/src/replica.rs

+2
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ pub async fn list_replicas(
228228
uuid: None,
229229
pooluuid: None,
230230
query: None,
231+
pooltypes: vec![],
231232
})
232233
.await
233234
.map(|r| r.into_inner().replicas)
@@ -246,6 +247,7 @@ pub async fn find_replica_by_uuid(
246247
uuid: Some(uuid.to_owned()),
247248
pooluuid: None,
248249
query: None,
250+
pooltypes: vec![],
249251
})
250252
.await
251253
.map(|r| r.into_inner().replicas)?

io-engine/src/bdev/lvs.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::{
3131
bdev_api::BdevError,
3232
core::LogicalVolume,
3333
lvs::LvsLvol,
34-
pool_backend::PoolArgs,
34+
pool_backend::{PoolArgs, PoolBackend},
3535
};
3636

3737
/// An lvol specified via URI.
@@ -215,6 +215,7 @@ impl Lvs {
215215
disks: vec![self.disk.to_owned()],
216216
uuid: None,
217217
cluster_size: None,
218+
backend: PoolBackend::Lvs,
218219
};
219220
match &self.mode {
220221
LvsMode::Create => {

io-engine/src/bin/io-engine-client/main.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use byte_unit::Byte;
22
use snafu::{Backtrace, Snafu};
3+
use strum::ParseError;
34
use tonic::transport::Channel;
45

56
use io_engine_api::v0::{
@@ -23,6 +24,11 @@ pub enum ClientError {
2324
source: tonic::Status,
2425
backtrace: Backtrace,
2526
},
27+
#[snafu(display("gRPC status: {}", source))]
28+
GrpcParseStatus {
29+
source: ParseError,
30+
backtrace: Backtrace,
31+
},
2632
#[snafu(display("Context building error: {}", source))]
2733
ContextCreate {
2834
source: context::Error,

0 commit comments

Comments
 (0)