Skip to content
This repository has been archived by the owner on Jul 6, 2023. It is now read-only.

gluster-block: implement expand feature interface #1702

Merged
merged 3 commits into from Apr 16, 2020

Conversation

pkalever
Copy link
Contributor

@pkalever pkalever commented Mar 24, 2020

What does this PR achieve? Why do we need it?

Implement block volume expand interface in heketi

Notes for the reviewer

Pushing it live with the intention that I will have my code side review comments ready by that time I finish on the TODO list.

The RFE just works fine now but also check for TODO list at the end of this comment which I got from John and Talur in a demo meeting.

Before Expand:
-------------
[root@server1 ~]# heketi-cli blockvolume create --size 1
Name: blockvol_365f428f2bf4b5a37f644c239f148058
Size: 1
Volume Id: 365f428f2bf4b5a37f644c239f148058
Cluster Id: 0b5740b0e3c34e935c1cd73e8bbf3c71
Hosts: [192.168.121.42 192.168.121.68 192.168.121.155]
IQN: iqn.2016-12.org.gluster-block:afcc41a3-1c46-4102-812b-5a0767cfb16a
LUN: 0
Hacount: 3
Username:
Password:
Block Hosting Volume: 7b3e7fceae17a57e0fc9ddedcce75912

[root@server1 ~]# heketi-cli volume info 7b3e7fceae17a57e0fc9ddedcce75912 | grep "Free Size"
Free Size: 8

[root@server1 ~]# targetcli ls | grep vol_7b3e7fceae17a57e0fc9ddedcce75912
 o- blockvol_365f428f2bf4b5a37f644c239f148058 [vol_7b3e7fceae17a57e0fc9ddedcce75912@... (1.0GiB) activated]

After Expand:
------------
[root@server1 ~]# heketi-cli blockvolume expand --block-volume 365f428f2bf4b5a37f644c239f148058 --new-size 2
Name: blockvol_365f428f2bf4b5a37f644c239f148058
Size: 2
Volume Id: 365f428f2bf4b5a37f644c239f148058
Cluster Id: 0b5740b0e3c34e935c1cd73e8bbf3c71
Hosts: [192.168.121.42 192.168.121.68 192.168.121.155]
IQN: iqn.2016-12.org.gluster-block:afcc41a3-1c46-4102-812b-5a0767cfb16a
LUN: 0
Hacount: 3
Username:
Password:
Block Hosting Volume: 7b3e7fceae17a57e0fc9ddedcce75912

[root@server1 ~]# heketi-cli volume info 7b3e7fceae17a57e0fc9ddedcce75912 | grep "Free Size"
Free Size: 7

[root@server1 ~]# targetcli ls | grep vol_7b3e7fceae17a57e0fc9ddedcce75912
 o- blockvol_365f428f2bf4b5a37f644c239f148058 [vol_7b3e7fceae17a57e0fc9ddedcce75912@... (2.0GiB) activated]

TODO:

  1. Implement Clean() and CleanDone() methods --> Done with V2
  2. Add unit tests
  3. defer the block volume delete in the functional test case --> Done with V2

@centos-ci
Copy link
Collaborator

Can one of the admins verify this patch?

@pkalever
Copy link
Contributor Author

@phlogistonjohn @raghavendra-talur can we request the CI for running the Smoke tests? or does it already got triggered automatically?

@phlogistonjohn
Copy link
Contributor

/ok to test

@phlogistonjohn
Copy link
Contributor

Added 'do not merge' label for now, once TODOs are done we will remove the label.

@pkalever
Copy link
Contributor Author

@phlogistonjohn @raghavendra-talur I have added new patches to this series, implementing Rollback, clean and CleanDone methods, also moved BHV delete in functional tests to a defer method. PTAL.

@pkalever pkalever changed the title [RFC] gluster-block: implement expand feature interface gluster-block: implement expand feature interface Mar 30, 2020
@phlogistonjohn
Copy link
Contributor

Travis CI run is failing due to a go vet error. This appears to be a real issue, please investigate.

Centoc-CI run failed in TestBlockVolumeExpand. This will need investigation too.

--- FAIL: TestBlockVolumeExpand (66.95s)
    assert.go:44:
        ^MASSERT:»»»func (github.com/heketi/heketi/tests/functional/TestSmokeTest/tests.TestBlockVolumeExpand) 0x71f629
        ^M»»File /root/go/src/github.com/heketi/heketi/tests/functional/TestSmokeTest/tests/block_volume_test.go:283
        ^M»»Info: [expected volInfo.Size == 146 got: 200]

I will begin reviewing too.

Copy link
Contributor

@phlogistonjohn phlogistonjohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete review, but I feel there is sufficient items that need feedback so far to submit this.

return err
}

if msg.Size == blockvolume.Info.Size {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checks should be moved into the Build function of the operation. Putting the checks outside of the operation could lead to races with the checks passing at the http request level and then starting two simultaneous expand operations for the same volume.
Specifically checks that depend on the state of the volume need to happen inside the same db transaction, such that it all happens atomically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

@@ -320,6 +320,65 @@ func (v *BlockVolumeEntry) destroyFromHost(
return nil
}

func (v *BlockVolumeEntry) InfoBlockVolumeFromHost(executor executors.Executor,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order of words in this function name is strange. Shouldn't it be something like "BlockVolumeInfoFromHost"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

return e
}

func (v *BlockVolumeEntry) expandBlockVolumeExec(executor executors.Executor,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the value-add of this function? Is the additional logging here particularly valuable or can we just call the executor function when needed and do the logging/error-handling in the callers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for now, it only called by Exec(), I will call the executor function directly.

@@ -25,6 +25,7 @@ var (
ErrKeyExists = errors.New("Key already exists in the database")
ErrNoReplacement = errors.New("No Replacement was found for resource requested to be removed")
ErrCloneBlockVol = errors.New("Cloning of block hosting volumes is not supported")
ErrInvalidRequest = errors.New("Invalid request")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please drop this error and use one of the existing errors OR make it much much more specific.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

John, I had looked at the existing errors and none of them looks like a match to give a better hint in this case, if you have any thoughts you can share here, so that I will drop it.

This description I had copied from errno.h

EINVAL          Invalid argument (POSIX.1-2001).

which looked more generic, I can tune it specific to my functionality of code, but the reusability will be compromised.

Let me know what you think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove it and where it is being used generate specific error messages, similar to (or the same as) what you are currently logging. We do not have to precreate the errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

// with the given blockvolume entry, db connection and newsize (in GB) that the
// blockvolume is to be expanded by.
func NewBlockVolumeExpandOperation(
bvol *BlockVolumeEntry, db wdb.DB, newSize int) *BlockVolumeExpandOperation {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Net-new operations should take IDs as arguments rather than *Entry types. The reason is one of db management and being clean across db transactions and avoiding stale state. I realize that a lot of existing operations use the entry types but this has lead to quite a few interesting bugs, and probably should not have been done that way. Regardless, we should not propagate that sub-optimal pattern in new code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

return err
}
bve.bvol = v
if bve.bvol.Pending.Id != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have a similar check for a pending BHV? It might be the case that the BHV is being modified/deleted and so we should probably avoid any changes to the contents (and any changes to the sizes tracked on the bhv) until those changes are complete.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

// to the db.
// This is only noteworthy because it is different from regular
// volumes which determines everything up front. Here certain
// values are determined by gluster-block commands.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're probably copying the code for file volume expand a bit too closely here. This isn't the best pattern, at least as far as mutating the entry objects outside of a transaction and then expecting consistent results afterward.
A better pattern would be to capture the results needed from the system in the expand exec function in an object(s) or attributes specifically created to track what the state of the system is rather than piggyback on db entries.
This also makes it cleaner wrt removing the *Entry as an argument to initialize the operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

John,

I have copied this piece of comments intentionally from the same file, it is part of function:

func (bvc *BlockVolumeCreateOperation) Finalize() error {
    ...
}

I was actually unclear with what we wanted to do to fix completely.

Hence, I would like to let this PR carry as it is, if its not a serious problem, and I will definitely address it in both the places in a separate PR.

@pkalever pkalever force-pushed the expand-bv-rfe branch 3 times, most recently from 466741e to 1814c15 Compare March 31, 2020 13:38
@pkalever
Copy link
Contributor Author

V3:
Addressed:

  • Travis CI run is failing due to a go vet errors and later by go fmt errors
  • Centoc-CI run failed in TestBlockVolumeExpand.
  • The rest of the comments are addressed in a separate patch
    • Moved multiple size checks to Build()
    • Change function name from InfoBlockVolumeFromHost() -> BlockVolumeInfoFromHost()
    • Discarded expandBlockVolumeExec() and called the executor directly from Exec()
    • Used IDs as arguments rather than *Entry types at NewBlockVolumeExpandOperation()
    • Added check for pending BHV along with existing pending BV in Build()

PTAL

Thanks!

@pkalever
Copy link
Contributor Author

pkalever commented Apr 1, 2020

Rebased on the latest master.

@@ -25,6 +25,7 @@ var (
ErrKeyExists = errors.New("Key already exists in the database")
ErrNoReplacement = errors.New("No Replacement was found for resource requested to be removed")
ErrCloneBlockVol = errors.New("Cloning of block hosting volumes is not supported")
ErrInvalidRequest = errors.New("Invalid request")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove it and where it is being used generate specific error messages, similar to (or the same as) what you are currently logging. We do not have to precreate the errors.

apps/glusterfs/app_block_volume.go Show resolved Hide resolved
godbc.Require(hvname != "")
godbc.Require(h != "")

// Request the executor to get the block volume info
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

type ExpandCleanOpType int

const (
OperationChangeInSize ExpandCleanOpType = iota + 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this redundant? Can't we just get back the size and then do a comparison (currSize == dbSize)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with removing

)

type BlockVolExpandReclaim struct {
Op ExpandCleanOpType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore if we end up dropping this variable, but the name Op is very confusing to me. Correct me if I'm wrong but this is really to track if the state change occurred in the underlying volume, it's not what I'd call an "Op" maybe a 'result' or a 'status' something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with removing

@@ -25,6 +25,9 @@ var (
bv_auth bool
bv_clusters string
bv_ha int

bv_newSize int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize the existing names have underscores in them but let us not propagate that non-idiomatic style for the new stuff. Use camelCase like typical Go code please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

EXABYTE
)

func ToGigaBytes(s string) (int, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way gluster-block can return its output in just bytes or GB rather than heketi code having to parse strings like this? I'm specifically concerned about rounding errors, and things like that. If we need to have this function we absolutely need thorough unit tests for just this function. Similarly, it should not be a public function (not capitalized).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gluster-block returns Human redable formats, counting from Bytes, MiB's, GiB's ...EiB's. The block volume size in heketi start with unit GiB, i.e. heketi cannot create Block Volume with Size less than 1GiB. Were as Gluster-block allows creating a blockVolume starting from Size 512Bytes :-)

This is why we cannot make gluster-block return size in GiB's always.

Sure, I will cover the test as part of the next PR.

}
}

func (c *CmdExecutor) InfoBlockVolume(host string, blockhostingvolume string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BlockVolumeInfo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inspired by ListBlockVolume, will take care


// if any of the cases above set err, log it and return
if err != nil {
logger.LogError("%v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least give some context to the person who might grep the code for an error line seen in the logs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copied it from the other places, np will do.

@@ -41,6 +41,8 @@ type Executor interface {
SetLogLevel(level string)
BlockVolumeCreate(host string, blockVolume *BlockVolumeRequest) (*BlockVolumeInfo, error)
BlockVolumeDestroy(host string, blockHostingVolumeName string, blockVolumeName string) error
BlockVolumeExpand(host string, blockHostingVolumeName string, blockVolumeName string, newSize int) error
InfoBlockVolume(host string, blockhostingvolume string, blockVolumeName string) (*BlockVolumeInfo, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BlockVolumeInfo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

@phlogistonjohn
Copy link
Contributor

I just noticed that it is not in the TODO list you have, but we will need a error handling functional test at some point. Let me know if that something you need assistance with and/or want to do in a follow-up pr.

Copy link
Contributor Author

@pkalever pkalever left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed Comments @phlogistonjohn , Will update the patches soon.

godbc.Require(hvname != "")
godbc.Require(h != "")

// Request the executor to get the block volume info
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

@@ -25,6 +25,7 @@ var (
ErrKeyExists = errors.New("Key already exists in the database")
ErrNoReplacement = errors.New("No Replacement was found for resource requested to be removed")
ErrCloneBlockVol = errors.New("Cloning of block hosting volumes is not supported")
ErrInvalidRequest = errors.New("Invalid request")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

type ExpandCleanOpType int

const (
OperationChangeInSize ExpandCleanOpType = iota + 1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with removing

)

type BlockVolExpandReclaim struct {
Op ExpandCleanOpType
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with removing

@@ -41,6 +41,8 @@ type Executor interface {
SetLogLevel(level string)
BlockVolumeCreate(host string, blockVolume *BlockVolumeRequest) (*BlockVolumeInfo, error)
BlockVolumeDestroy(host string, blockHostingVolumeName string, blockVolumeName string) error
BlockVolumeExpand(host string, blockHostingVolumeName string, blockVolumeName string, newSize int) error
InfoBlockVolume(host string, blockhostingvolume string, blockVolumeName string) (*BlockVolumeInfo, error)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

}

if bv.Info.Size != gotSize {
bve.Reclaim.Op = OperationChangeInSize
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


func (bve *BlockVolumeExpandOperation) CleanDone() error {
logger.Info("Clean is done for %v op:%v", bve.Label(), bve.op.Id)
if bve.Reclaim.Op == OperationChangeInSize {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

// NewBlockVolumeExpandOperation creates a new BlockVolumeExpandOperation populated
// with the given blockvolume id, db connection and newsize (in GB) that the
// blockvolume is to be expanded by.
func NewBlockVolumeExpandOperation(bvolId string, db wdb.DB, newSize int) (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 👍

return ErrNoSpace
}

err = bve.bvol.expandBlockVolumeComponents(txdb, bve.newSize)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfectly makesense to me. Will take care.

if e := bve.op.Save(tx); e != nil {
return e
}
if e := bve.bvol.Save(tx); e != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it.

@pkalever
Copy link
Contributor Author

pkalever commented Apr 7, 2020

@phlogistonjohn

Split your latest comments into 3 different patches:

  • V4: split updating the size of the bhv and bv
  • V4: minimize the state carried across function calls
  • V4: addressing comments from John ----> minor code style comments

I hope I had addressed all of them, incase If I had missed anything, please let me know.

TODO for the next PR:

  • Write Unit tests (including one for toGigaBytes() Function)
  • error handling functional test

Thank you! For the best-detailed review.

Copy link
Contributor

@phlogistonjohn phlogistonjohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're getting very close. Just a few smallish things + I do want to see a test for the output parsing function in this PR rather than in a followup because its proper functioning is critical to the clean path behaving correctly.

return blockVolumeInfo, nil
}

func (bv *BlockVolumeEntry) expandBlockVolumeComponents(db wdb.DB, newSize int) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more I look at this function the more I think we should get rid of it. It is only called in one place, the name is misleading (IMO), and it mutates the db state of the parent BHV only not the block volume the method is connected to.
I suggest either moving the valuable logic into a private helper function in the operation or just remove it altogether and merge the logic where needed in the operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@@ -376,6 +376,295 @@ func (bvc *BlockVolumeCreateOperation) CleanDone() error {
})
}

// BlockVolumeExpandOperation implements the operation functions used to
// expand an existing blockvolume.
type BlockVolExpandReclaim struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's lowercase this name to ensure future readers of the code that's it is private to the app logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


// modification values
newSize int
Reclaim BlockVolExpandReclaim // gets set by Clean() call
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowercase "reclaim" too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

return err
}
if bhv.Pending.Id != "" {
logger.LogError("Pending volume %v can not expand block volume %v", bhv.Info.Id, bve.bvolId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wording here is a bit awkward. How about: "Can not expand block volume %v when hosting volume %v is pending"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

if bve.newSize == bv.Info.Size {
logger.LogError("Requested new-size %v is same as current block volume size %v, nothing to be done.",
bve.newSize, bv.Info.Size)
return fmt.Errorf("Invalid Request: Requested new-size %v is same as current "+
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just return the result of logger.LogError [1] here, that text is (a) better/more clearly worded (b) the message the user can see on the CLI will be more easlily matched up with content in the logs.

1 - IIRC, LogError returns an error you can just use. If I'm misremembering create the error, log it, and then return it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

} else if bve.newSize < bv.Info.Size {
logger.LogError("Requested new-size %v is less than current block volume size %v, shrinking is not allowed.",
bve.newSize, bv.Info.Size)
return fmt.Errorf("Invalid Request: Requested new-size %v is less than current "+
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the above block.


func (bve *BlockVolumeExpandOperation) Finalize() error {
return bve.db.Update(func(tx *bolt.Tx) error {
var bv *BlockVolumeEntry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will check

if err != nil {
return err
}
actualSize = bvolInfo.Size
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless you have a reason not to you could just assign to bve.Reclaim.actualSize here and skip the intermediate variable. But it's not a big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how silly! thanks for catching, I think this is a by-product of removing the enum before.

if err != nil {
return err
}
ReclaimHsize := bve.newSize - bve.Reclaim.actualSize
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't capitalize this. Also, what's the "H" mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. I mean reclaimBhvSize, fixed it this way.

executors/cmdexec/block_volume.go Show resolved Hide resolved
@phlogistonjohn
Copy link
Contributor

@raghavendra-talur PTAL

Copy link
Contributor Author

@pkalever pkalever left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phlogistonjohn thanks!

return blockVolumeInfo, nil
}

func (bv *BlockVolumeEntry) expandBlockVolumeComponents(db wdb.DB, newSize int) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@@ -376,6 +376,295 @@ func (bvc *BlockVolumeCreateOperation) CleanDone() error {
})
}

// BlockVolumeExpandOperation implements the operation functions used to
// expand an existing blockvolume.
type BlockVolExpandReclaim struct {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


// modification values
newSize int
Reclaim BlockVolExpandReclaim // gets set by Clean() call
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

return err
}
if bhv.Pending.Id != "" {
logger.LogError("Pending volume %v can not expand block volume %v", bhv.Info.Id, bve.bvolId)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

if bve.newSize == bv.Info.Size {
logger.LogError("Requested new-size %v is same as current block volume size %v, nothing to be done.",
bve.newSize, bv.Info.Size)
return fmt.Errorf("Invalid Request: Requested new-size %v is same as current "+
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


func (bve *BlockVolumeExpandOperation) Finalize() error {
return bve.db.Update(func(tx *bolt.Tx) error {
var bv *BlockVolumeEntry
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will check

if err != nil {
return err
}
actualSize = bvolInfo.Size
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how silly! thanks for catching, I think this is a by-product of removing the enum before.

if err != nil {
return err
}
ReclaimHsize := bve.newSize - bve.Reclaim.actualSize
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. I mean reclaimBhvSize, fixed it this way.

executors/cmdexec/block_volume.go Show resolved Hide resolved
@pkalever
Copy link
Contributor Author

pkalever commented Apr 9, 2020

@phlogistonjohn updated with the patch fixing the latest review comments. I'm yet to add the Unit Test for toGigaBytes(), which is pending for this PR.

I will start working on the Unit Test for toGigaBytes() soon.

Thanks!

@pkalever
Copy link
Contributor Author

pkalever commented Apr 9, 2020

@phlogistonjohn @raghavendra-talur added unit test for toGigaBytes()

Thanks!

@phlogistonjohn
Copy link
Contributor

@phlogistonjohn @raghavendra-talur added unit test for toGigaBytes()

Thanks!

Test looks good with one line uncovered, which is the default case for the switch statement. If you add another section to the test that creates a bogus suffix I think you will trigger that error case and get full coverage of the function. Thanks!

@phlogistonjohn
Copy link
Contributor

Yes please.

@pkalever
Copy link
Contributor Author

@phlogistonjohn squashed them now. Travis CI crashing everytime on s390x/Go-1.1.3 attempting to run "# go get github.com/mattn/goveralls", doesn't look related to this PR anyways.

Thanks!

@phlogistonjohn
Copy link
Contributor

Yeah. I'm thinking about changing the travis config and just disabling s390.

Copy link
Contributor

@phlogistonjohn phlogistonjohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution. I look forward to seeing the follow-up PRs with the functional tests, etc!

@pkalever
Copy link
Contributor Author

pkalever commented Apr 14, 2020

Thank you for the contribution. I look forward to seeing the follow-up PRs with the functional tests, etc!

Well, I should actually thank you for all the quick and detailed reviews.

Yes @phlogistonjohn, as agreed before, I will spend some time this week to work on the pending list and submit them in a fresh PR.

BTW the items in the pending TODO list are:

  • Writing Unit tests
  • Writing error handling functional tests

return err
}

requiredFeeSize := bve.newSize - bv.Info.Size
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small typo but it also gives a new meaning to the statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

return err
}
}
if err := bve.op.Save(tx); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a delete of the operation instead of a save?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. This does look wrong to me now that you point it out. Let's fix this now.
This is another reason why I don't love doing the tests in a seperate PR because we should have a check in the tests that ensures no pending ops after the clean + clean done functions are run. Still not going to insist on that but this is why we do tests and not just reviews. :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

return err
}
}
if err := bve.op.Save(tx); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. This does look wrong to me now that you point it out. Let's fix this now.
This is another reason why I don't love doing the tests in a seperate PR because we should have a check in the tests that ensures no pending ops after the clean + clean done functions are run. Still not going to insist on that but this is why we do tests and not just reviews. :-)

return err
}
} else {
logger.Info("Actual Size match newly requested Size %v", bve.reclaim.actualSize)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed a minor grammar error here. Should be " Actual Size matches newly requested Size "

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Contributor Author

@pkalever pkalever left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will post a patch addressing the review comments soon.

Thanks!

return err
}

requiredFeeSize := bve.newSize - bv.Info.Size
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

return err
}
} else {
logger.Info("Actual Size match newly requested Size %v", bve.reclaim.actualSize)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

return err
}
}
if err := bve.op.Save(tx); err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

@pkalever
Copy link
Contributor Author

@phlogistonjohn @raghavendra-talur updated the patch addressing the review comments. Once the reviewing is done, will squash it and resend.

Thanks!

@phlogistonjohn
Copy link
Contributor

Latest changes look OK to me. Please squash at your earliest convenience.

Prasanna Kumar Kalever added 3 commits April 15, 2020 19:55
Before Expand:
-------------
[root@server1 ~]# heketi-cli blockvolume create --size 1
Name: blockvol_365f428f2bf4b5a37f644c239f148058
Size: 1
Volume Id: 365f428f2bf4b5a37f644c239f148058
Cluster Id: 0b5740b0e3c34e935c1cd73e8bbf3c71
Hosts: [192.168.121.42 192.168.121.68 192.168.121.155]
IQN: iqn.2016-12.org.gluster-block:afcc41a3-1c46-4102-812b-5a0767cfb16a
LUN: 0
Hacount: 3
Username:
Password:
Block Hosting Volume: 7b3e7fceae17a57e0fc9ddedcce75912

[root@server1 ~]# heketi-cli volume info 7b3e7fceae17a57e0fc9ddedcce75912 | grep "Free Size"
Free Size: 8

[root@server1 ~]# targetcli ls | grep vol_7b3e7fceae17a57e0fc9ddedcce75912
 o- blockvol_365f428f2bf4b5a37f644c239f148058 [vol_7b3e7fceae17a57e0fc9ddedcce75912@... (1.0GiB) activated]

After Expand:
------------
[root@server1 ~]# heketi-cli blockvolume expand --block-volume 365f428f2bf4b5a37f644c239f148058 --new-size 2
Name: blockvol_365f428f2bf4b5a37f644c239f148058
Size: 2
Volume Id: 365f428f2bf4b5a37f644c239f148058
Cluster Id: 0b5740b0e3c34e935c1cd73e8bbf3c71
Hosts: [192.168.121.42 192.168.121.68 192.168.121.155]
IQN: iqn.2016-12.org.gluster-block:afcc41a3-1c46-4102-812b-5a0767cfb16a
LUN: 0
Hacount: 3
Username:
Password:
Block Hosting Volume: 7b3e7fceae17a57e0fc9ddedcce75912

[root@server1 ~]# heketi-cli volume info 7b3e7fceae17a57e0fc9ddedcce75912 | grep "Free Size"
Free Size: 7

[root@server1 ~]# targetcli ls | grep vol_7b3e7fceae17a57e0fc9ddedcce75912
 o- blockvol_365f428f2bf4b5a37f644c239f148058 [vol_7b3e7fceae17a57e0fc9ddedcce75912@... (2.0GiB) activated]

Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
@pkalever
Copy link
Contributor Author

Latest changes look OK to me. Please squash at your earliest convenience.

@phlogistonjohn done now. Thanks!

@phlogistonjohn
Copy link
Contributor

retest this please

@phlogistonjohn
Copy link
Contributor

retest this please

@phlogistonjohn phlogistonjohn merged commit 65462a5 into heketi:master Apr 16, 2020
raghavendra-talur added a commit to raghavendra-talur/heketi that referenced this pull request Dec 4, 2020
In PR heketi#1702 we added a new OperationType and ChangeType. However, it
renumbered the consts. In cases where heketi is upgraded when the
db has pending ops, this can lead to undefined behavior.

Signed-off-by: Raghavendra Talur <rtalur@redhat.com>
raghavendra-talur added a commit to raghavendra-talur/heketi that referenced this pull request Dec 7, 2020
In PR heketi#1702 we added a new OperationType and ChangeType. However, it
renumbered the enums. In cases where heketi is upgraded when the
db has pending ops, this can lead to undefined behavior.

Signed-off-by: Raghavendra Talur <rtalur@redhat.com>
raghavendra-talur added a commit to raghavendra-talur/heketi that referenced this pull request Dec 7, 2020
In PR heketi#1702 we added a new OperationType and ChangeType. However, it
renumbered the enums. In cases where heketi is upgraded when the
db has pending ops, this can lead to undefined behavior.

Signed-off-by: Raghavendra Talur <rtalur@redhat.com>
raghavendra-talur added a commit that referenced this pull request Dec 7, 2020
In PR #1702 we added a new OperationType and ChangeType. However, it
renumbered the enums. In cases where heketi is upgraded when the
db has pending ops, this can lead to undefined behavior.

Signed-off-by: Raghavendra Talur <rtalur@redhat.com>
phlogistonjohn pushed a commit that referenced this pull request Dec 15, 2020
In PR #1702 we added a new OperationType and ChangeType. However, it
renumbered the enums. In cases where heketi is upgraded when the
db has pending ops, this can lead to undefined behavior.

Signed-off-by: Raghavendra Talur <rtalur@redhat.com>
(cherry picked from commit 9c9c572)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants