Discussion:
[Libstoragemgmt-devel] Replication, volume relationship & API
Tony Asleson
2014-04-09 19:22:55 UTC
Permalink
Gris has crafted a [proposal for
review](https://sourceforge.net/p/libstoragemgmt/wiki/Python_API_Usage/#118-volume-replication-lsmvolumereplication)

We had a good discussion on IRC today with some possible modifications
to it. These are some notes that pertaining to this discussion. I
started out creating a wiki page, but email seems like a better way to
keep track of the discussion.


* Relationships between volumes and their change in relationship
shouldn't cause one or more volumes to be deleted. This is a principle
of least astonishment. Users should have to make a call to
volume_delete to destroy a volume. We should also note that the source
and destination volume may be mapped to initiators while relationships
are changed.

* Ideally users shouldn't be able to call a method that clearly won't
work for all arrays for a specific relationship type, because it just
doesn't make sense for any (eg. two existing volumes and create a delta
relationship, although this might be possible with some arrays and
de-dupe). How can we achieve this and be language agnostic (C & Python)?

* When a user wants a volume deleted, should they have to transverse a
dependency chain splitting&removing dependencies which may or may not
exist or should we do this internally in the library for them? Some
arrays will have nothing to do, some will have a ton of things to do.

* Should we even list relationships between full separate copies of
volumes if an array supports that when some will not? Perhaps a better
statement would be lets only list relationships that cause the client to
do something to act upon for some operations?

* Creating & maintaining mirrors is an obvious need in the API and needs
to be exposed. Do the differences in delta copies and full copies need
this too?

I was going to throw a proposal for modifications to Gris's design, but
I thought I would step back and have this discussion first.

Thoughts/comments?

Regards,
Tony
Gris Ge
2014-04-10 11:49:47 UTC
Permalink
Post by Tony Asleson
We had a good discussion on IRC today with some possible modifications
to it. These are some notes that pertaining to this discussion. I
started out creating a wiki page, but email seems like a better way to
keep track of the discussion.
* Relationships between volumes and their change in relationship
shouldn't cause one or more volumes to be deleted. This is a principle
of least astonishment. Users should have to make a call to
volume_delete to destroy a volume. We should also note that the source
and destination volume may be mapped to initiators while relationships
are changed.
Current wiki page already state: no volume deletion will be issued by
any volume_replication_xxx() methods.
Post by Tony Asleson
* Ideally users shouldn't be able to call a method that clearly won't
work for all arrays for a specific relationship type, because it just
doesn't make sense for any (eg. two existing volumes and create a delta
relationship, although this might be possible with some arrays and
de-dupe). How can we achieve this and be language agnostic (C & Python)?
I think capacity and raise error on incorrect call would be enough.
Already documented.
Post by Tony Asleson
* When a user wants a volume deleted, should they have to transverse a
dependency chain splitting&removing dependencies which may or may not
exist or should we do this internally in the library for them? Some
arrays will have nothing to do, some will have a ton of things to do.
We can use LsmError to indicate user how to clear dependency:
LsmError
ErrorNumber.VOLUME_DELETE_BUSY_MASK
# User can use lsm.Client.mask_infos(volume_id=<vol_id>)
# or lsm.Client.access_groups(volume_id=<vol_id>)
# to find out mask dependency.
ErrorNumber.VOLUME_DELETE_BUSY_REPLICATION
# User can use lsm.Client.volume_replications(
# source_volume_id=<vol_id>)
# to find out the replication dependency.
# Since target volume is already deletable, only source volume
# will be blocked by replication.
ErrorNumber.VOLUME_DELETE_BUSY_POOL_MEMBER
# User can use lsm.Client.pools(with_opt_data=True) [1]
# to find out which pool is using this volume.

[1] Maybe we need a better way to find out that. Since volume pool is rare,
we can add better method for such query later.

The current volume_child_dependency_rm() method will remove whatever blocking
the deletion. That might cause unexpected data lose if user has no predict
knowledge of what will be deleted. I would suggest we remove that method.

To let user have predict knowledge of volume dependency, this class might help:

class VolumeDependency
.type
# VOLUME_DEP_MASK, VOLUME_DEP_REPLICATION, VOLUME_DEP_POOL_MEMBER
.resouce_id
# AccessGroup.id for VOLUME_DEP_MASK
# Target Volume.id for VOLUME_DEP_REPLICATION
# Pool.id for VOLUME_DEP_POOL_MEMBER
Post by Tony Asleson
* Should we even list relationships between full separate copies of
volumes if an array supports that when some will not? Perhaps a better
statement would be lets only list relationships that cause the client to
do something to act upon for some operations?
I see no issue on current design for this.

If any array remove the relationship after full copy done.
Then volume_replications() only list them during the copy progress, once done
they are just ordinary volume.

If they want to resync, they can use use volume_replication_create()(check
below).

If any array keep the relationship after full copy done, they can use
volume_replication_create() with existing settings.

For mirror(SYNC_LOCAL, etc), the relationship will always be there.
Post by Tony Asleson
* Creating & maintaining mirrors is an obvious need in the API and needs
to be exposed. Do the differences in delta copies and full copies need
this too?
I was going to throw a proposal for modifications to Gris's design, but
I thought I would step back and have this discussion first.
Thoughts/comments?
I updated the wiki page with this changes:

lsm.Client.volume_replication_create(name, volume_replication_type,
source_volume, target_volume,
flags=0)

Quote:
Create a volume replication. Use cases:
1. To let plugin create new target volume.
Set target_volume.id = None and target_volume.pool_id to target
pool.
2. Resync a existing replication.
Just invoke volume_replication_create() with existing settings.
3. Change replicaiton type:
Invoke volume_replication_create() with new
volume_replication_type.
Only these type changes is allowed:
1. UNSYNC_DELTA_RO <--> UNSYNC_DELTA_RW
2. SYNC_LOCAL <--> ASYNC_LOCAL
3. SYNC_REMOTE <--> ASYNC_REMOTE
Post by Tony Asleson
Regards,
Tony
--
Gris Ge
Gris Ge
2014-04-10 12:11:59 UTC
Permalink
Post by Gris Ge
lsm.Client.volume_replication_create(name, volume_replication_type,
source_volume, target_volume,
flags=0)
1. To let plugin create new target volume.
Set target_volume.id = None and target_volume.pool_id to target
pool.
2. Resync a existing replication.
Just invoke volume_replication_create() with existing settings.
Invoke volume_replication_create() with new
volume_replication_type.
1. UNSYNC_DELTA_RO <--> UNSYNC_DELTA_RW
2. SYNC_LOCAL <--> ASYNC_LOCAL
3. SYNC_REMOTE <--> ASYNC_REMOTE
Forgot to mention. I purged lsm.Client.volume_replication_resync()
method as lsm.Client.volume_replication_create() take over its job.
Post by Gris Ge
--
Gris Ge
--
Gris Ge
Continue reading on narkive:
Loading...