Skip to content
This repository was archived by the owner on Mar 26, 2020. It is now read-only.

Commit bb1ba6b

Browse files
author
Atin Mukherjee
authored
Merge branch 'master' into vol-stop-socket-connect
2 parents 6b2e269 + c896a94 commit bb1ba6b

9 files changed

Lines changed: 153 additions & 33 deletions

File tree

e2e/smartvol_ops_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,69 @@ func testSmartVolumeAutoDistributeDisperse(t *testing.T) {
510510
checkZeroLvs(r)
511511
}
512512

513+
func testSmartVolumeWhenCloneExists(t *testing.T) {
514+
r := require.New(t)
515+
516+
smartvolname := "svol1"
517+
518+
createReq := api.VolCreateReq{
519+
Name: smartvolname,
520+
Size: 20 * gutils.MiB,
521+
ReplicaCount: 3,
522+
}
523+
volinfo, err := client.VolumeCreate(createReq)
524+
r.Nil(err)
525+
526+
r.Len(volinfo.Subvols, 1)
527+
r.Equal("Replicate", volinfo.Type.String())
528+
r.Len(volinfo.Subvols[0].Bricks, 3)
529+
530+
err = client.VolumeStart(smartvolname, false)
531+
r.Nil(err)
532+
533+
// Snapshot Create, Activate, Clone and delete Snapshot
534+
snapshotCreateReq := api.SnapCreateReq{
535+
VolName: smartvolname,
536+
SnapName: smartvolname + "-s1",
537+
}
538+
_, err = client.SnapshotCreate(snapshotCreateReq)
539+
r.Nil(err, "snapshot create failed")
540+
541+
var snapshotActivateReq api.SnapActivateReq
542+
543+
err = client.SnapshotActivate(snapshotActivateReq, smartvolname+"-s1")
544+
r.Nil(err)
545+
546+
snapshotCloneReq := api.SnapCloneReq{
547+
CloneName: smartvolname + "-c1",
548+
}
549+
_, err = client.SnapshotClone(smartvolname+"-s1", snapshotCloneReq)
550+
r.Nil(err, "snapshot clone failed")
551+
552+
err = client.SnapshotDelete(smartvolname + "-s1")
553+
r.Nil(err)
554+
555+
// Check number of Lvs
556+
nlv, err := numberOfLvs("gluster-dev-gluster_loop1")
557+
r.Nil(err)
558+
// Thinpool + brick + Clone volume's brick
559+
r.Equal(3, nlv)
560+
561+
r.Nil(client.VolumeStop(smartvolname))
562+
563+
r.Nil(client.VolumeDelete(smartvolname))
564+
565+
nlv, err = numberOfLvs("gluster-dev-gluster_loop1")
566+
r.Nil(err)
567+
// Thinpool + brick + Clone volume's brick
568+
r.Equal(2, nlv)
569+
570+
// Delete Clone Volume
571+
r.Nil(client.VolumeDelete(smartvolname + "-c1"))
572+
573+
checkZeroLvs(r)
574+
}
575+
513576
func editDevice(t *testing.T) {
514577
r := require.New(t)
515578
peerList, err := client.Peers()
@@ -632,6 +695,8 @@ func TestSmartVolume(t *testing.T) {
632695
t.Run("Smartvol Distributed-Disperse Volume", testSmartVolumeDistributeDisperse)
633696
t.Run("Smartvol Auto Distributed-Replicate Volume", testSmartVolumeAutoDistributeReplicate)
634697
t.Run("Smartvol Auto Distributed-Disperse Volume", testSmartVolumeAutoDistributeDisperse)
698+
// Test dependent lvs in thinpool cases
699+
t.Run("Smartvol delete when clone exists", testSmartVolumeWhenCloneExists)
635700
t.Run("Replace Brick", testReplaceBrick)
636701
t.Run("Edit device", editDevice)
637702

glusterd2/brick/types.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ type MountInfo struct {
3232
MntOpts string
3333
}
3434

35+
// DeviceInfo is used to store brick device information
36+
type DeviceInfo struct {
37+
TpName string
38+
LvName string
39+
VgName string
40+
RootDevice string
41+
}
42+
3543
// Brickinfo is the static information about the brick
3644
type Brickinfo struct {
3745
ID uuid.UUID
@@ -44,9 +52,8 @@ type Brickinfo struct {
4452
Type Type
4553
Decommissioned bool
4654
PType ProvisionType
47-
VgName string
48-
RootDevice string
4955
MountInfo
56+
DeviceInfo
5057
}
5158

5259
// SizeInfo represents sizing information.

glusterd2/commands/snapshot/snapshot-create.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,9 @@ func createSnapSubvols(newVolinfo, origVolinfo *volume.Volinfo, nodeData map[str
500500
DevicePath: mountData.DevicePath,
501501
FsType: mountData.FsType,
502502
MntOpts: mountData.MntOpts,
503+
VgName: brickinfo.DeviceInfo.VgName,
504+
RootDevice: brickinfo.DeviceInfo.RootDevice,
505+
TpName: brickinfo.DeviceInfo.TpName,
503506
}
504507

505508
bricks = append(bricks, brick)

glusterd2/commands/snapshot/snapshot-restore.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func createVolumeBrickFromSnap(bricks []brick.Brickinfo, vol *volume.Volinfo) []
181181
Hostname: b.Hostname,
182182
ID: b.ID,
183183
MountInfo: b.MountInfo,
184+
DeviceInfo: b.DeviceInfo,
184185
Path: b.Path,
185186
PeerID: b.PeerID,
186187
Type: b.Type,

glusterd2/commands/volumes/volume-smartvol-txn.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func txnUndoPrepareBricks(c transaction.TxnCtx) error {
136136
}
137137

138138
// Remove LV
139-
err = lvmutils.RemoveLV(b.VgName, b.LvName)
139+
err = lvmutils.RemoveLV(b.VgName, b.LvName, true)
140140
if err != nil {
141141
c.Logger().WithError(err).WithFields(log.Fields{
142142
"vg-name": b.VgName,
@@ -145,7 +145,7 @@ func txnUndoPrepareBricks(c transaction.TxnCtx) error {
145145
}
146146

147147
// Remove Thin Pool
148-
err = lvmutils.RemoveLV(b.VgName, b.TpName)
148+
err = lvmutils.RemoveLV(b.VgName, b.TpName, true)
149149
if err != nil {
150150
c.Logger().WithError(err).WithFields(log.Fields{
151151
"vg-name": b.VgName,

glusterd2/volume/struct.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,13 @@ func NewBrickEntries(bricks []api.BrickReq, volName, volfileID string, volID uui
175175
binfo.VolfileID = volfileID
176176
binfo.VolumeID = volID
177177
binfo.ID = uuid.NewRandom()
178-
binfo.VgName = b.VgName
179-
binfo.RootDevice = b.RootDevice
178+
179+
binfo.DeviceInfo = brick.DeviceInfo{
180+
LvName: b.LvName,
181+
TpName: b.TpName,
182+
VgName: b.VgName,
183+
RootDevice: b.RootDevice,
184+
}
180185

181186
binfo.PType = ptype
182187
if ptype.IsAutoProvisioned() || ptype.IsSnapshotProvisioned() {

glusterd2/volume/volume-utils.go

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -286,18 +286,11 @@ func CleanBricks(volinfo *Volinfo) error {
286286
}
287287
vgname := parts[2]
288288
lvname := parts[3]
289-
tpname, err := lvmutils.GetThinpoolName(vgname, lvname)
290-
if err != nil {
291-
log.WithError(err).WithFields(log.Fields{
292-
"vg-name": vgname,
293-
"lv-name": lvname,
294-
}).Error("failed to get thinpool name")
295-
return err
296-
}
297289

298290
// Remove LV
299-
err = lvmutils.RemoveLV(vgname, lvname)
300-
if err != nil {
291+
err = lvmutils.RemoveLV(vgname, lvname, true)
292+
// Ignore error if LV not exists
293+
if err != nil && !lvmutils.IsLvNotFoundError(err) {
301294
log.WithError(err).WithFields(log.Fields{
302295
"vg-name": vgname,
303296
"lv-name": lvname,
@@ -309,26 +302,42 @@ func CleanBricks(volinfo *Volinfo) error {
309302
continue
310303
}
311304

312-
// Remove Thin Pool if LV count is zero, Thinpool will
313-
// have more LVs in case of snapshots and clones
314-
numLvs, err := lvmutils.NumberOfLvs(vgname, tpname)
315-
if err != nil {
316-
log.WithError(err).WithFields(log.Fields{
317-
"vg-name": vgname,
318-
"tp-name": tpname,
319-
}).Error("failed to get number of lvs")
320-
return err
321-
}
322-
323-
if numLvs == 0 {
324-
err = lvmutils.RemoveLV(vgname, tpname)
305+
// Thinpool info will not be available if Volume is manually provisioned
306+
// or a volume is cloned from a manually provisioned volume
307+
if b.DeviceInfo.TpName != "" {
308+
err = lvmutils.DeactivateLV(vgname, b.DeviceInfo.TpName)
325309
if err != nil {
326310
log.WithError(err).WithFields(log.Fields{
327311
"vg-name": vgname,
328-
"tp-name": tpname,
312+
"tp-name": b.DeviceInfo.TpName,
313+
}).Error("thinpool deactivate failed")
314+
return err
315+
}
316+
317+
err = lvmutils.RemoveLV(vgname, b.DeviceInfo.TpName, false)
318+
// Do not remove Thinpool if the dependent Lvs exists
319+
// Ignore the lvremove command failure if the reason is
320+
// dependent Lvs exists
321+
if err != nil && !lvmutils.IsDependentLvsError(err) && !lvmutils.IsLvNotFoundError(err) {
322+
log.WithError(err).WithFields(log.Fields{
323+
"vg-name": vgname,
324+
"tp-name": b.DeviceInfo.TpName,
329325
}).Error("thinpool remove failed")
330326
return err
331327
}
328+
329+
// Thinpool is not removed if dependent Lvs exists,
330+
// activate the thinpool again
331+
if err != nil && lvmutils.IsDependentLvsError(err) {
332+
err = lvmutils.ActivateLV(vgname, b.DeviceInfo.TpName)
333+
if err != nil {
334+
log.WithError(err).WithFields(log.Fields{
335+
"vg-name": vgname,
336+
"tp-name": b.DeviceInfo.TpName,
337+
}).Error("thinpool activate failed")
338+
return err
339+
}
340+
}
332341
}
333342

334343
// Update current Vg free size

pkg/lvmutils/utils.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,39 @@ func UnmountLV(mountdir string) error {
149149
return syscall.Unmount(mountdir, syscall.MNT_FORCE)
150150
}
151151

152+
// IsDependentLvsError returns true if the error related to dependent Lvs exists
153+
func IsDependentLvsError(err error) bool {
154+
if err == nil {
155+
return false
156+
}
157+
return strings.Contains(err.Error(), "dependent volume(s). Proceed? [y/n]")
158+
}
159+
160+
// IsLvNotFoundError returns true if the error is related to non existent LV error
161+
func IsLvNotFoundError(err error) bool {
162+
if err == nil {
163+
return false
164+
}
165+
return strings.Contains(err.Error(), "Failed to find logical volume")
166+
}
167+
168+
// DeactivateLV deactivates a Logical Volume
169+
func DeactivateLV(vgName, lvName string) error {
170+
return utils.ExecuteCommandRun("lvchange", "-a", "n", vgName+"/"+lvName)
171+
}
172+
173+
// ActivateLV activates a Logical Volume
174+
func ActivateLV(vgName, lvName string) error {
175+
return utils.ExecuteCommandRun("lvchange", "-a", "y", vgName+"/"+lvName)
176+
}
177+
152178
// RemoveLV removes Logical Volume
153-
func RemoveLV(vgName, lvName string) error {
154-
return utils.ExecuteCommandRun("lvremove", "-f", vgName+"/"+lvName)
179+
func RemoveLV(vgName, lvName string, force bool) error {
180+
args := []string{"--autobackup", "y", vgName + "/" + lvName}
181+
if force {
182+
args = append(args, "-f")
183+
}
184+
return utils.ExecuteCommandRun("lvremove", args...)
155185
}
156186

157187
// NumberOfLvs returns number of Lvs present in thinpool

plugins/device/deviceutils/store-utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func CheckForAvailableVgSize(expansionSize uint64, bricksInfo []brick.Brickinfo)
190190
if requiredDeviceSizeMap[b.MountInfo.DevicePath] > deviceSize {
191191
return map[string]string{}, false, nil
192192
}
193-
brickVgMapping[b.Path] = b.VgName
193+
brickVgMapping[b.Path] = b.DeviceInfo.VgName
194194
}
195195

196196
return brickVgMapping, true, nil

0 commit comments

Comments
 (0)