Skip to content

Commit

Permalink
support cached volumes, fixes topolvm#1003
Browse files Browse the repository at this point in the history
* add `C` to VolumeType and OpenTarget consts
* `lv.IsThin` should check LV attrs for thin (e.g., cached LVs have a
  pool but are not necessarily thin)
* add tests for cached LVs

Signed-off-by: guppy0130 <guppy0130@yahoo.com>
  • Loading branch information
guppy0130 committed Jan 10, 2025
1 parent 3305f75 commit cc0b56d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
3 changes: 2 additions & 1 deletion internal/lvmd/command/lvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,8 @@ func (l *LogicalVolume) Origin(ctx context.Context) (*LogicalVolume, error) {

// IsThin checks if the volume is thin volume or not.
func (l *LogicalVolume) IsThin() bool {
return l.pool != nil
// TODO: maybe use const from lvm_lv_attr.go
return l.attr[0] == 'V'
}

// Pool returns thin pool if this is a thin pool, or nil if not.
Expand Down
34 changes: 34 additions & 0 deletions internal/lvmd/command/lvm_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,39 @@ func Test_lvm_command(t *testing.T) {
t.Fatalf("expected error to be %v, got %v", ErrNoMultipleOfSectorSize, err)
}
})

t.Run("create cached volume and read it", func(t *testing.T) {
// create the cachedevice
cache_vg_name := "CACHEDEVICE"
cache_loop, err := testutils.MakeLoopbackDevice(ctx, cache_vg_name)
if err != nil {
t.Fatal(err)
}
err = testutils.MakeLoopbackVG(ctx, cache_vg_name, cache_loop)
if err != nil {
t.Fatal(err)
}
// ensure cache device cleanup
defer func() { _ = testutils.CleanLoopbackVG(cache_vg_name, []string{cache_loop}, []string{cache_vg_name}) }()
vg, err := FindVolumeGroup(ctx, cache_vg_name)
if err != nil {
t.Fatal(err)
}
// create cached LV
err = vg.CreateVolume(ctx, "test1", uint64(topolvm.MinimumSectorSize), []string{"tag"}, 0, "", []string{"--type", "writecache", "--cachesize", "10M", "--cachedevice", cache_loop})
if err != nil {
t.Fatal(err)
}
vol, err := vg.FindVolume(ctx, "test1")
if err != nil {
t.Fatal(err)
}
if vol.IsThin() {
t.Fatal("Expected test1 to not be thin (eval lv_attr instead of pool)")
}
if !strings.Contains(vol.attr, "C") {
t.Fatal("Created a LV but without writecache?")
}
})
})
}
2 changes: 2 additions & 0 deletions internal/lvmd/command/lvm_lv_attr.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ var (
type VolumeType rune

const (
VolumeTypeCached VolumeType = 'C'
VolumeTypeMirrored VolumeType = 'm'
VolumeTypeMirroredNoInitialSync VolumeType = 'M'
VolumeTypeOrigin VolumeType = 'o'
Expand Down Expand Up @@ -114,6 +115,7 @@ const (
type OpenTarget rune

const (
OpenTargetCache OpenTarget = 'C'
OpenTargetMirror OpenTarget = 'm'
OpenTargetRaid OpenTarget = 'r'
OpenTargetSnapshot OpenTarget = 's'
Expand Down
17 changes: 17 additions & 0 deletions internal/lvmd/command/lvm_lv_attr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,23 @@ func TestParsedLVAttr(t *testing.T) {
},
noError,
},
{
"Cache",
args{raw: "Cwi-aoC---"},
LVAttr{
VolumeType: VolumeTypeCached,
Permissions: PermissionsWriteable,
AllocationPolicy: AllocationPolicyInherited,
Minor: MinorFalse,
State: StateActive,
Open: OpenTrue,
OpenTarget: OpenTargetCache,
Zero: ZeroFalse,
VolumeHealth: VolumeHealthOK,
SkipActivation: SkipActivationFalse,
},
noError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit cc0b56d

Please # to comment.