mirror of
https://github.com/ceph/ceph
synced 2025-04-21 14:58:03 +00:00
rbd-mirror: allow mirroring to a different namespace
Allows a namespace in a pool to be mirrored to a differently named namespace in the secondary cluster. Signed-off-by: N Balachandran <nibalach@redhat.com>
This commit is contained in:
parent
a71318b738
commit
3fdbc160bb
@ -543,8 +543,9 @@ Commands
|
|||||||
|
|
||||||
:command:`mirror pool info` [*pool-name*]
|
:command:`mirror pool info` [*pool-name*]
|
||||||
Show information about the pool or namespace mirroring configuration.
|
Show information about the pool or namespace mirroring configuration.
|
||||||
For a pool, it includes mirroring mode, peer UUID, remote cluster name,
|
For both pools and namespaces, it includes the mirroring mode
|
||||||
and remote client name. For a namespace, it includes only mirroring mode.
|
and remote namespace. For pools, it additionally includes the site name,
|
||||||
|
peer UUID, mirror UUID, remote cluster name, and remote client name.
|
||||||
|
|
||||||
:command:`mirror pool peer add` [*pool-name*] *remote-cluster-spec*
|
:command:`mirror pool peer add` [*pool-name*] *remote-cluster-spec*
|
||||||
Add a mirroring peer to a pool.
|
Add a mirroring peer to a pool.
|
||||||
@ -555,7 +556,7 @@ Commands
|
|||||||
This requires mirroring to be enabled on the pool.
|
This requires mirroring to be enabled on the pool.
|
||||||
|
|
||||||
:command:`mirror pool peer remove` [*pool-name*] *uuid*
|
:command:`mirror pool peer remove` [*pool-name*] *uuid*
|
||||||
Remove a mirroring peer from a pool. The peer uuid is available
|
Remove a mirroring peer from a pool. The peer UUID is available
|
||||||
from ``mirror pool info`` command.
|
from ``mirror pool info`` command.
|
||||||
|
|
||||||
:command:`mirror pool peer set` [*pool-name*] *uuid* *key* *value*
|
:command:`mirror pool peer set` [*pool-name*] *uuid* *key* *value*
|
||||||
|
@ -37,12 +37,12 @@ set_image_meta ${CLUSTER2} ${POOL} ${image} "key1" "value1"
|
|||||||
set_image_meta ${CLUSTER2} ${POOL} ${image} "key2" "value2"
|
set_image_meta ${CLUSTER2} ${POOL} ${image} "key2" "value2"
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
write_image ${CLUSTER2} ${POOL} ${image} 100
|
write_image ${CLUSTER2} ${POOL} ${image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
||||||
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'down+unknown'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'down+unknown'
|
||||||
fi
|
fi
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
compare_image_meta ${CLUSTER1} ${POOL} ${image} "key1" "value1"
|
compare_image_meta ${CLUSTER1} ${POOL} ${image} "key1" "value1"
|
||||||
compare_image_meta ${CLUSTER1} ${POOL} ${image} "key2" "value2"
|
compare_image_meta ${CLUSTER1} ${POOL} ${image} "key2" "value2"
|
||||||
|
|
||||||
@ -53,19 +53,19 @@ create_image_and_enable_mirror ${CLUSTER2} ${POOL} ${image1} ${RBD_MIRROR_MODE}
|
|||||||
write_image ${CLUSTER2} ${POOL} ${image1} 100
|
write_image ${CLUSTER2} ${POOL} ${image1} 100
|
||||||
start_mirrors ${CLUSTER1}
|
start_mirrors ${CLUSTER1}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image1}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image1}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image1}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image1}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image1}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image1}
|
||||||
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image1} 'down+unknown'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image1} 'down+unknown'
|
||||||
fi
|
fi
|
||||||
compare_images ${POOL} ${image1}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image1}
|
||||||
|
|
||||||
testlog "TEST: test the first image is replaying after restart"
|
testlog "TEST: test the first image is replaying after restart"
|
||||||
write_image ${CLUSTER2} ${POOL} ${image} 100
|
write_image ${CLUSTER2} ${POOL} ${image} 100
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
|
|
||||||
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
||||||
testlog "TEST: stop/start/restart mirror via admin socket"
|
testlog "TEST: stop/start/restart mirror via admin socket"
|
||||||
@ -173,7 +173,7 @@ wait_for_image_in_omap ${CLUSTER2} ${POOL}
|
|||||||
create_image_and_enable_mirror ${CLUSTER2} ${POOL} ${image} ${RBD_MIRROR_MODE}
|
create_image_and_enable_mirror ${CLUSTER2} ${POOL} ${image} ${RBD_MIRROR_MODE}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
write_image ${CLUSTER2} ${POOL} ${image} 100
|
write_image ${CLUSTER2} ${POOL} ${image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying'
|
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying'
|
||||||
|
|
||||||
testlog "TEST: failover and failback"
|
testlog "TEST: failover and failback"
|
||||||
@ -187,10 +187,10 @@ wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
|||||||
promote_image ${CLUSTER2} ${POOL} ${image}
|
promote_image ${CLUSTER2} ${POOL} ${image}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
write_image ${CLUSTER2} ${POOL} ${image} 100
|
write_image ${CLUSTER2} ${POOL} ${image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
|
|
||||||
# failover (unmodified)
|
# failover (unmodified)
|
||||||
demote_image ${CLUSTER2} ${POOL} ${image}
|
demote_image ${CLUSTER2} ${POOL} ${image}
|
||||||
@ -207,10 +207,10 @@ wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+unknown'
|
|||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
||||||
promote_image ${CLUSTER2} ${POOL} ${image}
|
promote_image ${CLUSTER2} ${POOL} ${image}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
|
|
||||||
# failover
|
# failover
|
||||||
demote_image ${CLUSTER2} ${POOL} ${image}
|
demote_image ${CLUSTER2} ${POOL} ${image}
|
||||||
@ -220,10 +220,10 @@ wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
|||||||
promote_image ${CLUSTER1} ${POOL} ${image}
|
promote_image ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_image_replay_started ${CLUSTER2} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER2} ${POOL} ${image}
|
||||||
write_image ${CLUSTER1} ${POOL} ${image} 100
|
write_image ${CLUSTER1} ${POOL} ${image} 100
|
||||||
wait_for_replay_complete ${CLUSTER2} ${CLUSTER1} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER2} ${CLUSTER1} ${POOL} ${POOL} ${image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+stopped'
|
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+stopped'
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER2} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER2} ${POOL} ${image}
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
|
|
||||||
# failback
|
# failback
|
||||||
demote_image ${CLUSTER1} ${POOL} ${image}
|
demote_image ${CLUSTER1} ${POOL} ${image}
|
||||||
@ -233,10 +233,10 @@ wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
|||||||
promote_image ${CLUSTER2} ${POOL} ${image}
|
promote_image ${CLUSTER2} ${POOL} ${image}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
write_image ${CLUSTER2} ${POOL} ${image} 100
|
write_image ${CLUSTER2} ${POOL} ${image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
|
|
||||||
testlog "TEST: failover / failback loop"
|
testlog "TEST: failover / failback loop"
|
||||||
for i in `seq 1 20`; do
|
for i in `seq 1 20`; do
|
||||||
@ -246,7 +246,7 @@ for i in `seq 1 20`; do
|
|||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
||||||
promote_image ${CLUSTER1} ${POOL} ${image}
|
promote_image ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_image_replay_started ${CLUSTER2} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER2} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER2} ${CLUSTER1} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER2} ${CLUSTER1} ${POOL} ${POOL} ${image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+stopped'
|
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+stopped'
|
||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+replaying'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+replaying'
|
||||||
demote_image ${CLUSTER1} ${POOL} ${image}
|
demote_image ${CLUSTER1} ${POOL} ${image}
|
||||||
@ -255,7 +255,7 @@ for i in `seq 1 20`; do
|
|||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+unknown'
|
||||||
promote_image ${CLUSTER2} ${POOL} ${image}
|
promote_image ${CLUSTER2} ${POOL} ${image}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
|
||||||
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying'
|
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying'
|
||||||
done
|
done
|
||||||
@ -271,7 +271,7 @@ create_image_and_enable_mirror ${CLUSTER2} ${POOL} ${force_promote_image} ${RBD_
|
|||||||
write_image ${CLUSTER2} ${POOL} ${force_promote_image} 100
|
write_image ${CLUSTER2} ${POOL} ${force_promote_image} 100
|
||||||
wait_for_image_replay_stopped ${CLUSTER2} ${POOL} ${force_promote_image}
|
wait_for_image_replay_stopped ${CLUSTER2} ${POOL} ${force_promote_image}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${force_promote_image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${force_promote_image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${force_promote_image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${force_promote_image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${force_promote_image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${force_promote_image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${force_promote_image} 'up+stopped'
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${force_promote_image} 'up+stopped'
|
||||||
promote_image ${CLUSTER1} ${POOL} ${force_promote_image} '--force'
|
promote_image ${CLUSTER1} ${POOL} ${force_promote_image} '--force'
|
||||||
@ -302,14 +302,14 @@ else
|
|||||||
enable_mirror ${CLUSTER2} ${PARENT_POOL} ${parent_image} ${RBD_MIRROR_MODE}
|
enable_mirror ${CLUSTER2} ${PARENT_POOL} ${parent_image} ${RBD_MIRROR_MODE}
|
||||||
fi
|
fi
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${PARENT_POOL} ${parent_image}
|
wait_for_image_replay_started ${CLUSTER1} ${PARENT_POOL} ${parent_image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${PARENT_POOL} ${parent_image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${PARENT_POOL} ${PARENT_POOL} ${parent_image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${PARENT_POOL} ${parent_image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${PARENT_POOL} ${parent_image}
|
||||||
compare_images ${PARENT_POOL} ${parent_image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${PARENT_POOL} ${PARENT_POOL} ${parent_image}
|
||||||
|
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${clone_image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${clone_image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${clone_image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${clone_image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${clone_image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${clone_image}
|
||||||
compare_images ${POOL} ${clone_image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${clone_image}
|
||||||
remove_image_retry ${CLUSTER2} ${POOL} ${clone_image}
|
remove_image_retry ${CLUSTER2} ${POOL} ${clone_image}
|
||||||
|
|
||||||
testlog " - clone v1"
|
testlog " - clone v1"
|
||||||
@ -383,11 +383,11 @@ create_snapshot ${CLUSTER2} ${POOL} ${dp_image} 'snap1'
|
|||||||
write_image ${CLUSTER2} ${POOL} ${dp_image} 100
|
write_image ${CLUSTER2} ${POOL} ${dp_image} 100
|
||||||
create_snapshot ${CLUSTER2} ${POOL} ${dp_image} 'snap2'
|
create_snapshot ${CLUSTER2} ${POOL} ${dp_image} 'snap2'
|
||||||
write_image ${CLUSTER2} ${POOL} ${dp_image} 100
|
write_image ${CLUSTER2} ${POOL} ${dp_image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${dp_image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${dp_image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${dp_image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${dp_image}
|
||||||
compare_images ${POOL} ${dp_image}@snap1
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${dp_image}@snap1
|
||||||
compare_images ${POOL} ${dp_image}@snap2
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${dp_image}@snap2
|
||||||
compare_images ${POOL} ${dp_image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${dp_image}
|
||||||
remove_image_retry ${CLUSTER2} ${POOL} ${dp_image}
|
remove_image_retry ${CLUSTER2} ${POOL} ${dp_image}
|
||||||
|
|
||||||
testlog "TEST: disable mirroring / delete non-primary image"
|
testlog "TEST: disable mirroring / delete non-primary image"
|
||||||
@ -436,8 +436,8 @@ if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
|||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${i} 'present'
|
wait_for_image_present ${CLUSTER1} ${POOL} ${i} 'present'
|
||||||
wait_for_snap_present ${CLUSTER1} ${POOL} ${i} 'snap2'
|
wait_for_snap_present ${CLUSTER1} ${POOL} ${i} 'snap2'
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${i}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${i}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${i}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${i}
|
||||||
compare_images ${POOL} ${i}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${i}
|
||||||
done
|
done
|
||||||
|
|
||||||
testlog "TEST: remove mirroring pool"
|
testlog "TEST: remove mirroring pool"
|
||||||
@ -454,9 +454,9 @@ if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
|||||||
create_image ${CLUSTER2} ${POOL} ${rdp_image} 128 --data-pool ${pool}
|
create_image ${CLUSTER2} ${POOL} ${rdp_image} 128 --data-pool ${pool}
|
||||||
write_image ${CLUSTER2} ${pool} ${image} 100
|
write_image ${CLUSTER2} ${pool} ${image} 100
|
||||||
write_image ${CLUSTER2} ${POOL} ${rdp_image} 100
|
write_image ${CLUSTER2} ${POOL} ${rdp_image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${pool} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${pool} ${pool} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${pool} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${pool} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${rdp_image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${rdp_image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${rdp_image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${rdp_image}
|
||||||
for cluster in ${CLUSTER1} ${CLUSTER2}; do
|
for cluster in ${CLUSTER1} ${CLUSTER2}; do
|
||||||
CEPH_ARGS='' ceph --cluster ${cluster} osd pool rm ${pool} ${pool} --yes-i-really-really-mean-it
|
CEPH_ARGS='' ceph --cluster ${cluster} osd pool rm ${pool} ${pool} --yes-i-really-really-mean-it
|
||||||
@ -519,12 +519,12 @@ wait_for_image_replay_started ${CLUSTER1} ${POOL}/${NS1} ${image}
|
|||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL}/${NS2} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL}/${NS2} ${image}
|
||||||
write_image ${CLUSTER2} ${POOL}/${NS1} ${image} 100
|
write_image ${CLUSTER2} ${POOL}/${NS1} ${image} 100
|
||||||
write_image ${CLUSTER2} ${POOL}/${NS2} ${image} 100
|
write_image ${CLUSTER2} ${POOL}/${NS2} ${image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS1} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS1} ${POOL}/${NS1} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS2} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS2} ${POOL}/${NS2} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL}/${NS1} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL}/${NS1} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL}/${NS2} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL}/${NS2} ${image}
|
||||||
compare_images ${POOL}/${NS1} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS1} ${POOL}/${NS1} ${image}
|
||||||
compare_images ${POOL}/${NS2} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS2} ${POOL}/${NS2} ${image}
|
||||||
|
|
||||||
testlog " - disable mirroring / delete image"
|
testlog " - disable mirroring / delete image"
|
||||||
remove_image_retry ${CLUSTER2} ${POOL}/${NS1} ${image}
|
remove_image_retry ${CLUSTER2} ${POOL}/${NS1} ${image}
|
||||||
@ -533,6 +533,40 @@ wait_for_image_present ${CLUSTER1} ${POOL}/${NS1} ${image} 'deleted'
|
|||||||
wait_for_image_present ${CLUSTER1} ${POOL}/${NS2} ${image} 'deleted'
|
wait_for_image_present ${CLUSTER1} ${POOL}/${NS2} ${image} 'deleted'
|
||||||
remove_image_retry ${CLUSTER2} ${POOL}/${NS2} ${image}
|
remove_image_retry ${CLUSTER2} ${POOL}/${NS2} ${image}
|
||||||
|
|
||||||
|
testlog "TEST: mirror to a different remote namespace"
|
||||||
|
testlog " - replay"
|
||||||
|
NS3=ns3
|
||||||
|
NS4=ns4
|
||||||
|
rbd --cluster ${CLUSTER1} namespace create ${POOL}/${NS3}
|
||||||
|
rbd --cluster ${CLUSTER2} namespace create ${POOL}/${NS4}
|
||||||
|
rbd --cluster ${CLUSTER1} mirror pool enable ${POOL}/${NS3} ${MIRROR_POOL_MODE} --remote-namespace ${NS4}
|
||||||
|
rbd --cluster ${CLUSTER2} mirror pool enable ${POOL}/${NS4} ${MIRROR_POOL_MODE} --remote-namespace ${NS3}
|
||||||
|
create_image_and_enable_mirror ${CLUSTER2} ${POOL}/${NS4} ${image} ${RBD_MIRROR_MODE}
|
||||||
|
wait_for_image_replay_started ${CLUSTER1} ${POOL}/${NS3} ${image}
|
||||||
|
write_image ${CLUSTER2} ${POOL}/${NS4} ${image} 100
|
||||||
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS3} ${POOL}/${NS4} ${image}
|
||||||
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL}/${NS3} ${image}
|
||||||
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS3} ${POOL}/${NS4} ${image}
|
||||||
|
|
||||||
|
testlog " - disable mirroring and re-enable without remote-namespace"
|
||||||
|
remove_image_retry ${CLUSTER2} ${POOL}/${NS4} ${image}
|
||||||
|
wait_for_image_present ${CLUSTER1} ${POOL}/${NS3} ${image} 'deleted'
|
||||||
|
rbd --cluster ${CLUSTER1} mirror pool disable ${POOL}/${NS3}
|
||||||
|
rbd --cluster ${CLUSTER2} mirror pool disable ${POOL}/${NS4}
|
||||||
|
rbd --cluster ${CLUSTER2} namespace create ${POOL}/${NS3}
|
||||||
|
rbd --cluster ${CLUSTER2} mirror pool enable ${POOL}/${NS3} ${MIRROR_POOL_MODE}
|
||||||
|
rbd --cluster ${CLUSTER1} mirror pool enable ${POOL}/${NS3} ${MIRROR_POOL_MODE}
|
||||||
|
create_image_and_enable_mirror ${CLUSTER2} ${POOL}/${NS3} ${image} ${RBD_MIRROR_MODE}
|
||||||
|
wait_for_image_replay_started ${CLUSTER1} ${POOL}/${NS3} ${image}
|
||||||
|
write_image ${CLUSTER2} ${POOL}/${NS3} ${image} 100
|
||||||
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS3} ${POOL}/${NS3} ${image}
|
||||||
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL}/${NS3} ${image}
|
||||||
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS3} ${POOL}/${NS3} ${image}
|
||||||
|
remove_image_retry ${CLUSTER2} ${POOL}/${NS3} ${image}
|
||||||
|
wait_for_image_present ${CLUSTER1} ${POOL}/${NS3} ${image} 'deleted'
|
||||||
|
rbd --cluster ${CLUSTER1} mirror pool disable ${POOL}/${NS3}
|
||||||
|
rbd --cluster ${CLUSTER2} mirror pool disable ${POOL}/${NS3}
|
||||||
|
|
||||||
testlog " - data pool"
|
testlog " - data pool"
|
||||||
dp_image=test_data_pool
|
dp_image=test_data_pool
|
||||||
create_image_and_enable_mirror ${CLUSTER2} ${POOL}/${NS1} ${dp_image} ${RBD_MIRROR_MODE} 128 --data-pool ${PARENT_POOL}
|
create_image_and_enable_mirror ${CLUSTER2} ${POOL}/${NS1} ${dp_image} ${RBD_MIRROR_MODE} 128 --data-pool ${PARENT_POOL}
|
||||||
@ -542,9 +576,9 @@ wait_for_image_replay_started ${CLUSTER1} ${POOL}/${NS1} ${dp_image}
|
|||||||
data_pool=$(get_image_data_pool ${CLUSTER1} ${POOL}/${NS1} ${dp_image})
|
data_pool=$(get_image_data_pool ${CLUSTER1} ${POOL}/${NS1} ${dp_image})
|
||||||
test "${data_pool}" = "${PARENT_POOL}"
|
test "${data_pool}" = "${PARENT_POOL}"
|
||||||
write_image ${CLUSTER2} ${POOL}/${NS1} ${dp_image} 100
|
write_image ${CLUSTER2} ${POOL}/${NS1} ${dp_image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS1} ${dp_image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS1} ${POOL}/${NS1} ${dp_image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL}/${NS1} ${dp_image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL}/${NS1} ${dp_image}
|
||||||
compare_images ${POOL}/${NS1} ${dp_image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL}/${NS1} ${POOL}/${NS1} ${dp_image}
|
||||||
remove_image_retry ${CLUSTER2} ${POOL}/${NS1} ${dp_image}
|
remove_image_retry ${CLUSTER2} ${POOL}/${NS1} ${dp_image}
|
||||||
|
|
||||||
testlog "TEST: simple image resync"
|
testlog "TEST: simple image resync"
|
||||||
@ -553,7 +587,7 @@ wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted' ${image_id}
|
|||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
|
|
||||||
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
||||||
testlog "TEST: image resync while replayer is stopped"
|
testlog "TEST: image resync while replayer is stopped"
|
||||||
@ -566,7 +600,7 @@ if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
|||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
testlog "TEST: request image resync while daemon is offline"
|
testlog "TEST: request image resync while daemon is offline"
|
||||||
@ -577,7 +611,7 @@ wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted' ${image_id}
|
|||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${POOL} ${image}
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
remove_image_retry ${CLUSTER2} ${POOL} ${image}
|
remove_image_retry ${CLUSTER2} ${POOL} ${image}
|
||||||
|
|
||||||
if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
||||||
@ -588,7 +622,7 @@ if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
|||||||
|
|
||||||
testlog " - replay stopped after disconnect"
|
testlog " - replay stopped after disconnect"
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
test -n "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
test -n "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
||||||
disconnect_image ${CLUSTER2} ${POOL} ${image}
|
disconnect_image ${CLUSTER2} ${POOL} ${image}
|
||||||
test -z "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
test -z "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
||||||
@ -600,9 +634,9 @@ if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
|||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted' ${image_id}
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted' ${image_id}
|
||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
test -n "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
test -n "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
|
|
||||||
testlog " - disconnected after max_concurrent_object_sets reached"
|
testlog " - disconnected after max_concurrent_object_sets reached"
|
||||||
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
if [ -z "${RBD_MIRROR_USE_RBD_MIRROR}" ]; then
|
||||||
@ -628,25 +662,25 @@ if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
|||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted' ${image_id}
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted' ${image_id}
|
||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
test -n "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
test -n "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
|
|
||||||
testlog " - rbd_mirroring_resync_after_disconnect config option"
|
testlog " - rbd_mirroring_resync_after_disconnect config option"
|
||||||
set_image_meta ${CLUSTER2} ${POOL} ${image} \
|
set_image_meta ${CLUSTER2} ${POOL} ${image} \
|
||||||
conf_rbd_mirroring_resync_after_disconnect true
|
conf_rbd_mirroring_resync_after_disconnect true
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
image_id=$(get_image_id ${CLUSTER1} ${POOL} ${image})
|
image_id=$(get_image_id ${CLUSTER1} ${POOL} ${image})
|
||||||
disconnect_image ${CLUSTER2} ${POOL} ${image}
|
disconnect_image ${CLUSTER2} ${POOL} ${image}
|
||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted' ${image_id}
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted' ${image_id}
|
||||||
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'present'
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
test -n "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
test -n "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
set_image_meta ${CLUSTER2} ${POOL} ${image} \
|
set_image_meta ${CLUSTER2} ${POOL} ${image} \
|
||||||
conf_rbd_mirroring_resync_after_disconnect false
|
conf_rbd_mirroring_resync_after_disconnect false
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
disconnect_image ${CLUSTER2} ${POOL} ${image}
|
disconnect_image ${CLUSTER2} ${POOL} ${image}
|
||||||
test -z "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
test -z "$(get_mirror_journal_position ${CLUSTER2} ${POOL} ${image})"
|
||||||
wait_for_image_replay_stopped ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_stopped ${CLUSTER1} ${POOL} ${image}
|
||||||
|
@ -38,7 +38,7 @@ create_image_and_enable_mirror ${CLUSTER1} ${POOL} image1
|
|||||||
|
|
||||||
wait_for_image_replay_started ${CLUSTER2} ${POOL} image1
|
wait_for_image_replay_started ${CLUSTER2} ${POOL} image1
|
||||||
write_image ${CLUSTER1} ${POOL} image1 100
|
write_image ${CLUSTER1} ${POOL} image1 100
|
||||||
wait_for_replay_complete ${CLUSTER2} ${CLUSTER1} ${POOL} image1
|
wait_for_replay_complete ${CLUSTER2} ${CLUSTER1} ${POOL} ${POOL} image1
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER2} ${POOL} image1
|
wait_for_replaying_status_in_pool_dir ${CLUSTER2} ${POOL} image1
|
||||||
|
|
||||||
testlog "TEST: verify rx-tx direction"
|
testlog "TEST: verify rx-tx direction"
|
||||||
@ -54,12 +54,12 @@ enable_mirror ${CLUSTER2} ${PARENT_POOL} image2
|
|||||||
|
|
||||||
wait_for_image_replay_started ${CLUSTER2} ${PARENT_POOL} image1
|
wait_for_image_replay_started ${CLUSTER2} ${PARENT_POOL} image1
|
||||||
write_image ${CLUSTER1} ${PARENT_POOL} image1 100
|
write_image ${CLUSTER1} ${PARENT_POOL} image1 100
|
||||||
wait_for_replay_complete ${CLUSTER2} ${CLUSTER1} ${PARENT_POOL} image1
|
wait_for_replay_complete ${CLUSTER2} ${CLUSTER1} ${PARENT_POOL} ${PARENT_POOL} image1
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER2} ${PARENT_POOL} image1
|
wait_for_replaying_status_in_pool_dir ${CLUSTER2} ${PARENT_POOL} image1
|
||||||
|
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${PARENT_POOL} image2
|
wait_for_image_replay_started ${CLUSTER1} ${PARENT_POOL} image2
|
||||||
write_image ${CLUSTER2} ${PARENT_POOL} image2 100
|
write_image ${CLUSTER2} ${PARENT_POOL} image2 100
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${PARENT_POOL} image2
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${PARENT_POOL} ${PARENT_POOL} image2
|
||||||
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${PARENT_POOL} image2
|
wait_for_replaying_status_in_pool_dir ${CLUSTER1} ${PARENT_POOL} image2
|
||||||
|
|
||||||
testlog "TEST: pool replayer and callout cleanup when peer is updated"
|
testlog "TEST: pool replayer and callout cleanup when peer is updated"
|
||||||
|
@ -71,7 +71,7 @@ test_replay()
|
|||||||
wait_for_image_replay_started ${CLUSTER1}:${LEADER} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1}:${LEADER} ${POOL} ${image}
|
||||||
write_image ${CLUSTER2} ${POOL} ${image} 100
|
write_image ${CLUSTER2} ${POOL} ${image} 100
|
||||||
wait_for_replay_complete ${CLUSTER1}:${LEADER} ${CLUSTER2} ${POOL} \
|
wait_for_replay_complete ${CLUSTER1}:${LEADER} ${CLUSTER2} ${POOL} \
|
||||||
${image}
|
${POOL} ${image}
|
||||||
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying' \
|
wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying' \
|
||||||
'primary_position' \
|
'primary_position' \
|
||||||
"${MIRROR_USER_ID_PREFIX}${LEADER} on $(hostname -s)"
|
"${MIRROR_USER_ID_PREFIX}${LEADER} on $(hostname -s)"
|
||||||
@ -79,7 +79,7 @@ test_replay()
|
|||||||
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} \
|
wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} \
|
||||||
'down+unknown'
|
'down+unknown'
|
||||||
fi
|
fi
|
||||||
compare_images ${POOL} ${image}
|
compare_images ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,17 +743,18 @@ wait_for_journal_replay_complete()
|
|||||||
{
|
{
|
||||||
local local_cluster=$1
|
local local_cluster=$1
|
||||||
local cluster=$2
|
local cluster=$2
|
||||||
local pool=$3
|
local local_pool=$3
|
||||||
local image=$4
|
local remote_pool=$4
|
||||||
|
local image=$5
|
||||||
local s master_pos mirror_pos last_mirror_pos
|
local s master_pos mirror_pos last_mirror_pos
|
||||||
local master_tag master_entry mirror_tag mirror_entry
|
local master_tag master_entry mirror_tag mirror_entry
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
for s in 0.2 0.4 0.8 1.6 2 2 4 4 8 8 16 16 32 32; do
|
for s in 0.2 0.4 0.8 1.6 2 2 4 4 8 8 16 16 32 32; do
|
||||||
sleep ${s}
|
sleep ${s}
|
||||||
flush "${local_cluster}" "${pool}" "${image}"
|
flush "${local_cluster}" "${local_pool}" "${image}"
|
||||||
master_pos=$(get_master_journal_position "${cluster}" "${pool}" "${image}")
|
master_pos=$(get_master_journal_position "${cluster}" "${remote_pool}" "${image}")
|
||||||
mirror_pos=$(get_mirror_journal_position "${cluster}" "${pool}" "${image}")
|
mirror_pos=$(get_mirror_journal_position "${cluster}" "${remote_pool}" "${image}")
|
||||||
test -n "${master_pos}" -a "${master_pos}" = "${mirror_pos}" && return 0
|
test -n "${master_pos}" -a "${master_pos}" = "${mirror_pos}" && return 0
|
||||||
test "${mirror_pos}" != "${last_mirror_pos}" && break
|
test "${mirror_pos}" != "${last_mirror_pos}" && break
|
||||||
done
|
done
|
||||||
@ -796,21 +797,22 @@ wait_for_snapshot_sync_complete()
|
|||||||
{
|
{
|
||||||
local local_cluster=$1
|
local local_cluster=$1
|
||||||
local cluster=$2
|
local cluster=$2
|
||||||
local pool=$3
|
local local_pool=$3
|
||||||
local image=$4
|
local remote_pool=$4
|
||||||
|
local image=$5
|
||||||
|
|
||||||
local status_log=${TEMPDIR}/$(mkfname ${cluster}-${pool}-${image}.status)
|
local status_log=${TEMPDIR}/$(mkfname ${cluster}-${remote_pool}-${image}.status)
|
||||||
local local_status_log=${TEMPDIR}/$(mkfname ${local_cluster}-${pool}-${image}.status)
|
local local_status_log=${TEMPDIR}/$(mkfname ${local_cluster}-${local_pool}-${image}.status)
|
||||||
|
|
||||||
mirror_image_snapshot "${cluster}" "${pool}" "${image}"
|
mirror_image_snapshot "${cluster}" "${remote_pool}" "${image}"
|
||||||
get_newest_mirror_snapshot "${cluster}" "${pool}" "${image}" "${status_log}"
|
get_newest_mirror_snapshot "${cluster}" "${remote_pool}" "${image}" "${status_log}"
|
||||||
local snapshot_id=$(xmlstarlet sel -t -v "//snapshot/id" < ${status_log})
|
local snapshot_id=$(xmlstarlet sel -t -v "//snapshot/id" < ${status_log})
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
for s in 0.2 0.4 0.8 1.6 2 2 4 4 8 8 16 16 32 32; do
|
for s in 0.2 0.4 0.8 1.6 2 2 4 4 8 8 16 16 32 32; do
|
||||||
sleep ${s}
|
sleep ${s}
|
||||||
|
|
||||||
get_newest_mirror_snapshot "${local_cluster}" "${pool}" "${image}" "${local_status_log}"
|
get_newest_mirror_snapshot "${local_cluster}" "${local_pool}" "${image}" "${local_status_log}"
|
||||||
local primary_snapshot_id=$(xmlstarlet sel -t -v "//snapshot/namespace/primary_snap_id" < ${local_status_log})
|
local primary_snapshot_id=$(xmlstarlet sel -t -v "//snapshot/namespace/primary_snap_id" < ${local_status_log})
|
||||||
|
|
||||||
test "${snapshot_id}" = "${primary_snapshot_id}" && return 0
|
test "${snapshot_id}" = "${primary_snapshot_id}" && return 0
|
||||||
@ -825,13 +827,14 @@ wait_for_replay_complete()
|
|||||||
{
|
{
|
||||||
local local_cluster=$1
|
local local_cluster=$1
|
||||||
local cluster=$2
|
local cluster=$2
|
||||||
local pool=$3
|
local local_pool=$3
|
||||||
local image=$4
|
local remote_pool=$4
|
||||||
|
local image=$5
|
||||||
|
|
||||||
if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
if [ "${RBD_MIRROR_MODE}" = "journal" ]; then
|
||||||
wait_for_journal_replay_complete ${local_cluster} ${cluster} ${pool} ${image}
|
wait_for_journal_replay_complete ${local_cluster} ${cluster} ${local_pool} ${remote_pool} ${image}
|
||||||
elif [ "${RBD_MIRROR_MODE}" = "snapshot" ]; then
|
elif [ "${RBD_MIRROR_MODE}" = "snapshot" ]; then
|
||||||
wait_for_snapshot_sync_complete ${local_cluster} ${cluster} ${pool} ${image}
|
wait_for_snapshot_sync_complete ${local_cluster} ${cluster} ${local_pool} ${remote_pool} ${image}
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -1298,16 +1301,19 @@ show_diff()
|
|||||||
|
|
||||||
compare_images()
|
compare_images()
|
||||||
{
|
{
|
||||||
local pool=$1
|
|
||||||
local image=$2
|
|
||||||
local ret=0
|
local ret=0
|
||||||
|
local local_cluster=$1
|
||||||
|
local cluster=$2
|
||||||
|
local local_pool=$3
|
||||||
|
local remote_pool=$4
|
||||||
|
local image=$5
|
||||||
|
|
||||||
local rmt_export=${TEMPDIR}/$(mkfname ${CLUSTER2}-${pool}-${image}.export)
|
local rmt_export=${TEMPDIR}/$(mkfname ${cluster}-${remote_pool}-${image}.export)
|
||||||
local loc_export=${TEMPDIR}/$(mkfname ${CLUSTER1}-${pool}-${image}.export)
|
local loc_export=${TEMPDIR}/$(mkfname ${local_cluster}-${local_pool}-${image}.export)
|
||||||
|
|
||||||
rm -f ${rmt_export} ${loc_export}
|
rm -f ${rmt_export} ${loc_export}
|
||||||
rbd --cluster ${CLUSTER2} export ${pool}/${image} ${rmt_export}
|
rbd --cluster ${cluster} export ${remote_pool}/${image} ${rmt_export}
|
||||||
rbd --cluster ${CLUSTER1} export ${pool}/${image} ${loc_export}
|
rbd --cluster ${local_cluster} export ${local_pool}/${image} ${loc_export}
|
||||||
if ! cmp ${rmt_export} ${loc_export}
|
if ! cmp ${rmt_export} ${loc_export}
|
||||||
then
|
then
|
||||||
show_diff ${rmt_export} ${loc_export}
|
show_diff ${rmt_export} ${loc_export}
|
||||||
|
@ -111,7 +111,7 @@ do
|
|||||||
snap_name="snap${i}"
|
snap_name="snap${i}"
|
||||||
create_snap ${CLUSTER2} ${POOL} ${image} ${snap_name}
|
create_snap ${CLUSTER2} ${POOL} ${image} ${snap_name}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_snap_present ${CLUSTER1} ${POOL} ${image} ${snap_name}
|
wait_for_snap_present ${CLUSTER1} ${POOL} ${image} ${snap_name}
|
||||||
|
|
||||||
if [ -n "${clean_snap_name}" ]; then
|
if [ -n "${clean_snap_name}" ]; then
|
||||||
@ -124,7 +124,7 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_snap_present ${CLUSTER1} ${POOL} ${image} ${clean_snap_name}
|
wait_for_snap_present ${CLUSTER1} ${POOL} ${image} ${clean_snap_name}
|
||||||
|
|
||||||
for i in `seq 1 10`
|
for i in `seq 1 10`
|
||||||
@ -173,7 +173,7 @@ do
|
|||||||
image="image_${i}"
|
image="image_${i}"
|
||||||
create_snap ${CLUSTER2} ${POOL} ${image} ${snap_name}
|
create_snap ${CLUSTER2} ${POOL} ${image} ${snap_name}
|
||||||
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
|
||||||
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
|
wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${POOL} ${image}
|
||||||
wait_for_snap_present ${CLUSTER1} ${POOL} ${image} ${snap_name}
|
wait_for_snap_present ${CLUSTER1} ${POOL} ${image} ${snap_name}
|
||||||
compare_image_snaps ${POOL} ${image} ${snap_name}
|
compare_image_snaps ${POOL} ${image} ${snap_name}
|
||||||
done
|
done
|
||||||
|
@ -4624,6 +4624,7 @@ static const std::string STATUS_GLOBAL_KEY_PREFIX("status_global_");
|
|||||||
static const std::string REMOTE_STATUS_GLOBAL_KEY_PREFIX("remote_status_global_");
|
static const std::string REMOTE_STATUS_GLOBAL_KEY_PREFIX("remote_status_global_");
|
||||||
static const std::string INSTANCE_KEY_PREFIX("instance_");
|
static const std::string INSTANCE_KEY_PREFIX("instance_");
|
||||||
static const std::string MIRROR_IMAGE_MAP_KEY_PREFIX("image_map_");
|
static const std::string MIRROR_IMAGE_MAP_KEY_PREFIX("image_map_");
|
||||||
|
static const std::string REMOTE_NAMESPACE("remote_namespace");
|
||||||
|
|
||||||
std::string peer_key(const std::string &uuid) {
|
std::string peer_key(const std::string &uuid) {
|
||||||
return PEER_KEY_PREFIX + uuid;
|
return PEER_KEY_PREFIX + uuid;
|
||||||
@ -5920,6 +5921,56 @@ int mirror_mode_set(cls_method_context_t hctx, bufferlist *in,
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = remove_key(hctx, mirror::REMOTE_NAMESPACE);
|
||||||
|
if (r < 0) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mirror_remote_namespace_get(cls_method_context_t hctx, bufferlist *in,
|
||||||
|
bufferlist *out) {
|
||||||
|
std::string mirror_ns_decode;
|
||||||
|
int r = read_key(hctx, mirror::REMOTE_NAMESPACE, &mirror_ns_decode);
|
||||||
|
if (r < 0) {
|
||||||
|
CLS_ERR("error getting mirror remote namespace: %s",
|
||||||
|
cpp_strerror(r).c_str());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
encode(mirror_ns_decode, *out);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mirror_remote_namespace_set(cls_method_context_t hctx, bufferlist *in,
|
||||||
|
bufferlist *out) {
|
||||||
|
std::string mirror_namespace;
|
||||||
|
try {
|
||||||
|
auto bl_it = in->cbegin();
|
||||||
|
decode(mirror_namespace, bl_it);
|
||||||
|
} catch (const ceph::buffer::error &err) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mirror_mode;
|
||||||
|
int r = read_key(hctx, mirror::MODE, &mirror_mode);
|
||||||
|
if (r < 0 && r != -ENOENT) {
|
||||||
|
return r;
|
||||||
|
} else if (r == 0 && mirror_mode != cls::rbd::MIRROR_MODE_DISABLED) {
|
||||||
|
CLS_ERR("cannot set mirror remote namespace while mirroring enabled");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferlist bl;
|
||||||
|
encode(mirror_namespace, bl);
|
||||||
|
|
||||||
|
r = cls_cxx_map_set_val(hctx, mirror::REMOTE_NAMESPACE, &bl);
|
||||||
|
if (r < 0) {
|
||||||
|
CLS_ERR("error setting mirror remote namespace: %s",
|
||||||
|
cpp_strerror(r).c_str());
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8278,6 +8329,8 @@ CLS_INIT(rbd)
|
|||||||
cls_method_handle_t h_mirror_uuid_set;
|
cls_method_handle_t h_mirror_uuid_set;
|
||||||
cls_method_handle_t h_mirror_mode_get;
|
cls_method_handle_t h_mirror_mode_get;
|
||||||
cls_method_handle_t h_mirror_mode_set;
|
cls_method_handle_t h_mirror_mode_set;
|
||||||
|
cls_method_handle_t h_mirror_remote_namespace_get;
|
||||||
|
cls_method_handle_t h_mirror_remote_namespace_set;
|
||||||
cls_method_handle_t h_mirror_peer_ping;
|
cls_method_handle_t h_mirror_peer_ping;
|
||||||
cls_method_handle_t h_mirror_peer_list;
|
cls_method_handle_t h_mirror_peer_list;
|
||||||
cls_method_handle_t h_mirror_peer_add;
|
cls_method_handle_t h_mirror_peer_add;
|
||||||
@ -8575,6 +8628,13 @@ CLS_INIT(rbd)
|
|||||||
cls_register_cxx_method(h_class, "mirror_mode_set",
|
cls_register_cxx_method(h_class, "mirror_mode_set",
|
||||||
CLS_METHOD_RD | CLS_METHOD_WR,
|
CLS_METHOD_RD | CLS_METHOD_WR,
|
||||||
mirror_mode_set, &h_mirror_mode_set);
|
mirror_mode_set, &h_mirror_mode_set);
|
||||||
|
cls_register_cxx_method(h_class, "mirror_remote_namespace_get",
|
||||||
|
CLS_METHOD_RD, mirror_remote_namespace_get,
|
||||||
|
&h_mirror_remote_namespace_get);
|
||||||
|
cls_register_cxx_method(h_class, "mirror_remote_namespace_set",
|
||||||
|
CLS_METHOD_RD | CLS_METHOD_WR,
|
||||||
|
mirror_remote_namespace_set,
|
||||||
|
&h_mirror_remote_namespace_set);
|
||||||
cls_register_cxx_method(h_class, "mirror_peer_ping",
|
cls_register_cxx_method(h_class, "mirror_peer_ping",
|
||||||
CLS_METHOD_RD | CLS_METHOD_WR,
|
CLS_METHOD_RD | CLS_METHOD_WR,
|
||||||
mirror_peer_ping, &h_mirror_peer_ping);
|
mirror_peer_ping, &h_mirror_peer_ping);
|
||||||
|
@ -1882,6 +1882,40 @@ int mirror_mode_set(librados::IoCtx *ioctx,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mirror_remote_namespace_get(librados::IoCtx *ioctx,
|
||||||
|
std::string *mirror_namespace) {
|
||||||
|
bufferlist in_bl;
|
||||||
|
bufferlist out_bl;
|
||||||
|
|
||||||
|
int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_remote_namespace_get",
|
||||||
|
in_bl, out_bl);
|
||||||
|
if (r < 0) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = out_bl.cbegin();
|
||||||
|
try {
|
||||||
|
decode(*mirror_namespace, it);
|
||||||
|
} catch (const ceph::buffer::error &err) {
|
||||||
|
return -EBADMSG;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mirror_remote_namespace_set(librados::IoCtx *ioctx,
|
||||||
|
const std::string &mirror_namespace) {
|
||||||
|
bufferlist in_bl;
|
||||||
|
encode(mirror_namespace, in_bl);
|
||||||
|
|
||||||
|
bufferlist out_bl;
|
||||||
|
int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_remote_namespace_set",
|
||||||
|
in_bl, out_bl);
|
||||||
|
if (r < 0) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void mirror_peer_list_start(librados::ObjectReadOperation *op) {
|
void mirror_peer_list_start(librados::ObjectReadOperation *op) {
|
||||||
bufferlist bl;
|
bufferlist bl;
|
||||||
op->exec("rbd", "mirror_peer_list", bl);
|
op->exec("rbd", "mirror_peer_list", bl);
|
||||||
|
@ -389,6 +389,11 @@ int mirror_mode_get(librados::IoCtx *ioctx,
|
|||||||
int mirror_mode_set(librados::IoCtx *ioctx,
|
int mirror_mode_set(librados::IoCtx *ioctx,
|
||||||
cls::rbd::MirrorMode mirror_mode);
|
cls::rbd::MirrorMode mirror_mode);
|
||||||
|
|
||||||
|
int mirror_remote_namespace_get(librados::IoCtx *ioctx,
|
||||||
|
std::string *mirror_namespace);
|
||||||
|
int mirror_remote_namespace_set(librados::IoCtx *ioctx,
|
||||||
|
const std::string &mirror_namespace);
|
||||||
|
|
||||||
int mirror_peer_ping(librados::IoCtx *ioctx,
|
int mirror_peer_ping(librados::IoCtx *ioctx,
|
||||||
const std::string& site_name,
|
const std::string& site_name,
|
||||||
const std::string& fsid);
|
const std::string& fsid);
|
||||||
|
@ -577,6 +577,16 @@ CEPH_RBD_API int rbd_mirror_mode_get(rados_ioctx_t io_ctx,
|
|||||||
rbd_mirror_mode_t *mirror_mode);
|
rbd_mirror_mode_t *mirror_mode);
|
||||||
CEPH_RBD_API int rbd_mirror_mode_set(rados_ioctx_t io_ctx,
|
CEPH_RBD_API int rbd_mirror_mode_set(rados_ioctx_t io_ctx,
|
||||||
rbd_mirror_mode_t mirror_mode);
|
rbd_mirror_mode_t mirror_mode);
|
||||||
|
CEPH_RBD_API int rbd_mirror_remote_namespace_get(rados_ioctx_t io_ctx,
|
||||||
|
char *remote_namespace,
|
||||||
|
size_t *max_len);
|
||||||
|
/**
|
||||||
|
* The value can be set only if mirroring on io_ctx is disabled. The previously
|
||||||
|
* set value will be automatically reset to io_ctx's namespace when mirroring on
|
||||||
|
* io_ctx is disabled.
|
||||||
|
*/
|
||||||
|
CEPH_RBD_API int rbd_mirror_remote_namespace_set(rados_ioctx_t io_ctx,
|
||||||
|
const char *remote_namespace);
|
||||||
|
|
||||||
CEPH_RBD_API int rbd_mirror_uuid_get(rados_ioctx_t io_ctx,
|
CEPH_RBD_API int rbd_mirror_uuid_get(rados_ioctx_t io_ctx,
|
||||||
char *uuid, size_t *max_len);
|
char *uuid, size_t *max_len);
|
||||||
|
@ -357,6 +357,16 @@ public:
|
|||||||
int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
|
int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
|
||||||
int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
|
int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
|
||||||
|
|
||||||
|
int mirror_remote_namespace_get(IoCtx& io_ctx,
|
||||||
|
std::string* remote_namespace);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value can be set only if mirroring on io_ctx is disabled. The
|
||||||
|
* previously set value will be automatically reset to io_ctx's namespace when
|
||||||
|
* mirroring on io_ctx is disabled.
|
||||||
|
*/
|
||||||
|
int mirror_remote_namespace_set(IoCtx& io_ctx,
|
||||||
|
const std::string& remote_namespace);
|
||||||
int mirror_uuid_get(IoCtx& io_ctx, std::string* mirror_uuid);
|
int mirror_uuid_get(IoCtx& io_ctx, std::string* mirror_uuid);
|
||||||
|
|
||||||
int mirror_peer_bootstrap_create(IoCtx& io_ctx, std::string* token);
|
int mirror_peer_bootstrap_create(IoCtx& io_ctx, std::string* token);
|
||||||
|
@ -1115,9 +1115,8 @@ int Mirror<I>::mode_set(librados::IoCtx& io_ctx,
|
|||||||
<< dendl;
|
<< dendl;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_mirror_mode == next_mirror_mode) {
|
if (current_mirror_mode == next_mirror_mode) {
|
||||||
return 0;
|
return 0; // Nothing more to be done
|
||||||
} else if (current_mirror_mode == cls::rbd::MIRROR_MODE_DISABLED) {
|
} else if (current_mirror_mode == cls::rbd::MIRROR_MODE_DISABLED) {
|
||||||
uuid_d uuid_gen;
|
uuid_d uuid_gen;
|
||||||
uuid_gen.generate_random();
|
uuid_gen.generate_random();
|
||||||
@ -1271,6 +1270,55 @@ int Mirror<I>::mode_set(librados::IoCtx& io_ctx,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
int Mirror<I>::remote_namespace_get(librados::IoCtx& io_ctx,
|
||||||
|
std::string* remote_namespace) {
|
||||||
|
|
||||||
|
CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
|
||||||
|
ldout(cct, 20) << dendl;
|
||||||
|
|
||||||
|
int r = cls_client::mirror_remote_namespace_get(&io_ctx, remote_namespace);
|
||||||
|
if (r < 0) {
|
||||||
|
if (r != -ENOENT && r != -EOPNOTSUPP) {
|
||||||
|
lderr(cct) << "failed to retrieve remote mirror namespace: "
|
||||||
|
<< cpp_strerror(r) << dendl;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
*remote_namespace = io_ctx.get_namespace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
int Mirror<I>::remote_namespace_set(librados::IoCtx& io_ctx,
|
||||||
|
const std::string& remote_namespace) {
|
||||||
|
CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
|
||||||
|
ldout(cct, 20) << dendl;
|
||||||
|
|
||||||
|
std::string local_namespace = io_ctx.get_namespace();
|
||||||
|
|
||||||
|
if (local_namespace.empty() && !remote_namespace.empty()) {
|
||||||
|
lderr(cct) << "cannot mirror the default namespace to a "
|
||||||
|
<< "non-default namespace." << dendl;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!local_namespace.empty() && remote_namespace.empty()) {
|
||||||
|
lderr(cct) << "cannot mirror a non-default namespace to the default "
|
||||||
|
<< "namespace." << dendl;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int r = cls_client::mirror_remote_namespace_set(&io_ctx, remote_namespace);
|
||||||
|
if (r < 0) {
|
||||||
|
lderr(cct) << "failed to set remote mirror namespace: "
|
||||||
|
<< cpp_strerror(r) << dendl;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
int Mirror<I>::uuid_get(librados::IoCtx& io_ctx, std::string* mirror_uuid) {
|
int Mirror<I>::uuid_get(librados::IoCtx& io_ctx, std::string* mirror_uuid) {
|
||||||
CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
|
CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
|
||||||
|
@ -31,6 +31,11 @@ struct Mirror {
|
|||||||
static int mode_get(librados::IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
|
static int mode_get(librados::IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
|
||||||
static int mode_set(librados::IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
|
static int mode_set(librados::IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
|
||||||
|
|
||||||
|
static int remote_namespace_get(librados::IoCtx& io_ctx,
|
||||||
|
std::string* remote_namespace);
|
||||||
|
static int remote_namespace_set(librados::IoCtx& io_ctx,
|
||||||
|
const std::string& remote_namespace);
|
||||||
|
|
||||||
static int uuid_get(librados::IoCtx& io_ctx, std::string* mirror_uuid);
|
static int uuid_get(librados::IoCtx& io_ctx, std::string* mirror_uuid);
|
||||||
static void uuid_get(librados::IoCtx& io_ctx, std::string* mirror_uuid,
|
static void uuid_get(librados::IoCtx& io_ctx, std::string* mirror_uuid,
|
||||||
Context* on_finish);
|
Context* on_finish);
|
||||||
|
@ -1101,6 +1101,18 @@ namespace librbd {
|
|||||||
return librbd::api::Mirror<>::mode_set(io_ctx, mirror_mode);
|
return librbd::api::Mirror<>::mode_set(io_ctx, mirror_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RBD::mirror_remote_namespace_get(IoCtx& io_ctx,
|
||||||
|
std::string* remote_namespace) {
|
||||||
|
return librbd::api::Mirror<>::remote_namespace_get(io_ctx,
|
||||||
|
remote_namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
int RBD::mirror_remote_namespace_set(IoCtx& io_ctx,
|
||||||
|
const std::string& remote_namespace) {
|
||||||
|
return librbd::api::Mirror<>::remote_namespace_set(io_ctx,
|
||||||
|
remote_namespace);
|
||||||
|
}
|
||||||
|
|
||||||
int RBD::mirror_uuid_get(IoCtx& io_ctx, std::string* mirror_uuid) {
|
int RBD::mirror_uuid_get(IoCtx& io_ctx, std::string* mirror_uuid) {
|
||||||
return librbd::api::Mirror<>::uuid_get(io_ctx, mirror_uuid);
|
return librbd::api::Mirror<>::uuid_get(io_ctx, mirror_uuid);
|
||||||
}
|
}
|
||||||
@ -3395,6 +3407,37 @@ extern "C" int rbd_mirror_mode_set(rados_ioctx_t p,
|
|||||||
return librbd::api::Mirror<>::mode_set(io_ctx, mirror_mode);
|
return librbd::api::Mirror<>::mode_set(io_ctx, mirror_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" int rbd_mirror_remote_namespace_get(rados_ioctx_t p,
|
||||||
|
char *remote_namespace,
|
||||||
|
size_t *max_len) {
|
||||||
|
librados::IoCtx io_ctx;
|
||||||
|
librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
|
||||||
|
|
||||||
|
std::string remote_namespace_str;
|
||||||
|
int r = librbd::api::Mirror<>::remote_namespace_get(io_ctx,
|
||||||
|
&remote_namespace_str);
|
||||||
|
if (r < 0) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto total_len = remote_namespace_str.size() + 1;
|
||||||
|
if (*max_len < total_len) {
|
||||||
|
*max_len = total_len;
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
*max_len = total_len;
|
||||||
|
|
||||||
|
strcpy(remote_namespace, remote_namespace_str.c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int rbd_mirror_remote_namespace_set(rados_ioctx_t p,
|
||||||
|
const char *remote_namespace) {
|
||||||
|
librados::IoCtx io_ctx;
|
||||||
|
librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
|
||||||
|
return librbd::api::Mirror<>::remote_namespace_set(io_ctx, remote_namespace);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" int rbd_mirror_uuid_get(rados_ioctx_t p,
|
extern "C" int rbd_mirror_uuid_get(rados_ioctx_t p,
|
||||||
char *mirror_uuid, size_t *max_len) {
|
char *mirror_uuid, size_t *max_len) {
|
||||||
librados::IoCtx io_ctx;
|
librados::IoCtx io_ctx;
|
||||||
|
@ -394,6 +394,12 @@ cdef extern from "rbd/librbd.h" nogil:
|
|||||||
int rbd_mirror_mode_get(rados_ioctx_t io, rbd_mirror_mode_t *mirror_mode)
|
int rbd_mirror_mode_get(rados_ioctx_t io, rbd_mirror_mode_t *mirror_mode)
|
||||||
int rbd_mirror_mode_set(rados_ioctx_t io, rbd_mirror_mode_t mirror_mode)
|
int rbd_mirror_mode_set(rados_ioctx_t io, rbd_mirror_mode_t mirror_mode)
|
||||||
|
|
||||||
|
int rbd_mirror_remote_namespace_get(rados_ioctx_t io_ctx,
|
||||||
|
char *remote_namespace,
|
||||||
|
size_t *max_len)
|
||||||
|
int rbd_mirror_remote_namespace_set(rados_ioctx_t io_ctx,
|
||||||
|
const char *remote_namespace)
|
||||||
|
|
||||||
int rbd_mirror_uuid_get(rados_ioctx_t io_ctx, char *mirror_uuid,
|
int rbd_mirror_uuid_get(rados_ioctx_t io_ctx, char *mirror_uuid,
|
||||||
size_t *max_len)
|
size_t *max_len)
|
||||||
|
|
||||||
|
@ -437,6 +437,14 @@ cdef nogil:
|
|||||||
int rbd_mirror_mode_set(rados_ioctx_t io, rbd_mirror_mode_t mirror_mode):
|
int rbd_mirror_mode_set(rados_ioctx_t io, rbd_mirror_mode_t mirror_mode):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
int rbd_mirror_remote_namespace_get(rados_ioctx_t io_ctx,
|
||||||
|
char *remote_namespace,
|
||||||
|
size_t *max_len):
|
||||||
|
pass
|
||||||
|
int rbd_mirror_remote_namespace_set(rados_ioctx_t io_ctx,
|
||||||
|
const char *remote_namespace):
|
||||||
|
pass
|
||||||
|
|
||||||
int rbd_mirror_uuid_get(rados_ioctx_t io_ctx, char *mirror_uuid,
|
int rbd_mirror_uuid_get(rados_ioctx_t io_ctx, char *mirror_uuid,
|
||||||
size_t *max_len):
|
size_t *max_len):
|
||||||
pass
|
pass
|
||||||
|
@ -1330,6 +1330,52 @@ class RBD(object):
|
|||||||
if ret != 0:
|
if ret != 0:
|
||||||
raise make_ex(ret, 'error setting mirror mode')
|
raise make_ex(ret, 'error setting mirror mode')
|
||||||
|
|
||||||
|
def mirror_remote_namespace_get(self, ioctx):
|
||||||
|
"""
|
||||||
|
Get mirror remote namespace
|
||||||
|
|
||||||
|
:param ioctx: determines which RADOS pool is read
|
||||||
|
:type ioctx: :class:`rados.Ioctx`
|
||||||
|
:returns: str - mirror remote namespace
|
||||||
|
"""
|
||||||
|
cdef:
|
||||||
|
rados_ioctx_t _ioctx = convert_ioctx(ioctx)
|
||||||
|
char *_remote_namespace = NULL
|
||||||
|
size_t _max_size = 512
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
_remote_namespace = <char *>realloc_chk(_remote_namespace,
|
||||||
|
_max_size)
|
||||||
|
with nogil:
|
||||||
|
ret = rbd_mirror_remote_namespace_get(_ioctx,
|
||||||
|
_remote_namespace,
|
||||||
|
&_max_size)
|
||||||
|
if ret >= 0:
|
||||||
|
break
|
||||||
|
elif ret != -errno.ERANGE:
|
||||||
|
raise make_ex(ret, 'error retrieving remote namespace')
|
||||||
|
return decode_cstr(_remote_namespace)
|
||||||
|
finally:
|
||||||
|
free(_remote_namespace)
|
||||||
|
|
||||||
|
def mirror_remote_namespace_set(self, ioctx, remote_namespace):
|
||||||
|
"""
|
||||||
|
Set mirror remote namespace
|
||||||
|
|
||||||
|
:param ioctx: determines which RADOS pool is written
|
||||||
|
:type ioctx: :class:`rados.Ioctx`
|
||||||
|
:param remote_namespace: the remote cluster namespace to mirror to
|
||||||
|
:type str:
|
||||||
|
"""
|
||||||
|
remote_namespace = cstr(remote_namespace, 'remote_namespace')
|
||||||
|
cdef:
|
||||||
|
rados_ioctx_t _ioctx = convert_ioctx(ioctx)
|
||||||
|
char *_remote_namespace = remote_namespace
|
||||||
|
with nogil:
|
||||||
|
ret = rbd_mirror_remote_namespace_set(_ioctx, _remote_namespace)
|
||||||
|
if ret != 0:
|
||||||
|
raise make_ex(ret, 'error setting remote namespace')
|
||||||
|
|
||||||
def mirror_uuid_get(self, ioctx):
|
def mirror_uuid_get(self, ioctx):
|
||||||
"""
|
"""
|
||||||
Get pool mirror uuid
|
Get pool mirror uuid
|
||||||
|
@ -1832,19 +1832,21 @@
|
|||||||
rbd help mirror pool enable
|
rbd help mirror pool enable
|
||||||
usage: rbd mirror pool enable [--pool <pool>] [--namespace <namespace>]
|
usage: rbd mirror pool enable [--pool <pool>] [--namespace <namespace>]
|
||||||
[--site-name <site-name>]
|
[--site-name <site-name>]
|
||||||
|
[--remote-namespace <remote-namespace>]
|
||||||
<pool-spec> <mode>
|
<pool-spec> <mode>
|
||||||
|
|
||||||
Enable RBD mirroring in a pool or namespace.
|
Enable RBD mirroring in a pool or namespace.
|
||||||
|
|
||||||
Positional arguments
|
Positional arguments
|
||||||
<pool-spec> pool specification
|
<pool-spec> pool specification
|
||||||
(example: <pool-name>[/<namespace>]
|
(example: <pool-name>[/<namespace>]
|
||||||
<mode> mirror mode [image or pool]
|
<mode> mirror mode [image or pool]
|
||||||
|
|
||||||
Optional arguments
|
Optional arguments
|
||||||
-p [ --pool ] arg pool name
|
-p [ --pool ] arg pool name
|
||||||
--namespace arg namespace name
|
--namespace arg namespace name
|
||||||
--site-name arg local site name
|
--site-name arg local site name
|
||||||
|
--remote-namespace arg remote namespace name
|
||||||
|
|
||||||
rbd help mirror pool info
|
rbd help mirror pool info
|
||||||
usage: rbd mirror pool info [--pool <pool>] [--namespace <namespace>]
|
usage: rbd mirror pool info [--pool <pool>] [--namespace <namespace>]
|
||||||
@ -2712,3 +2714,4 @@
|
|||||||
--image arg image name
|
--image arg image name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1606,7 +1606,9 @@ TEST_F(TestClsRbd, mirror) {
|
|||||||
ASSERT_EQ(-ENOENT, mirror_peer_list(&ioctx, &peers));
|
ASSERT_EQ(-ENOENT, mirror_peer_list(&ioctx, &peers));
|
||||||
|
|
||||||
std::string uuid;
|
std::string uuid;
|
||||||
|
std::string remote_ns;
|
||||||
ASSERT_EQ(-ENOENT, mirror_uuid_get(&ioctx, &uuid));
|
ASSERT_EQ(-ENOENT, mirror_uuid_get(&ioctx, &uuid));
|
||||||
|
ASSERT_EQ(-ENOENT, mirror_remote_namespace_get(&ioctx, &remote_ns));
|
||||||
ASSERT_EQ(-EINVAL, mirror_peer_add(&ioctx, {"uuid1", MIRROR_PEER_DIRECTION_RX,
|
ASSERT_EQ(-EINVAL, mirror_peer_add(&ioctx, {"uuid1", MIRROR_PEER_DIRECTION_RX,
|
||||||
"siteA", "client",
|
"siteA", "client",
|
||||||
"mirror uuid"}));
|
"mirror uuid"}));
|
||||||
@ -1622,11 +1624,16 @@ TEST_F(TestClsRbd, mirror) {
|
|||||||
ASSERT_EQ(0, mirror_uuid_get(&ioctx, &uuid));
|
ASSERT_EQ(0, mirror_uuid_get(&ioctx, &uuid));
|
||||||
ASSERT_EQ("mirror-uuid", uuid);
|
ASSERT_EQ("mirror-uuid", uuid);
|
||||||
|
|
||||||
|
ASSERT_EQ(0, mirror_remote_namespace_set(&ioctx, "remote-ns"));
|
||||||
|
ASSERT_EQ(0, mirror_remote_namespace_get(&ioctx, &remote_ns));
|
||||||
|
ASSERT_EQ("remote-ns", remote_ns);
|
||||||
|
|
||||||
ASSERT_EQ(0, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_IMAGE));
|
ASSERT_EQ(0, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_IMAGE));
|
||||||
ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
|
ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
|
||||||
ASSERT_EQ(cls::rbd::MIRROR_MODE_IMAGE, mirror_mode);
|
ASSERT_EQ(cls::rbd::MIRROR_MODE_IMAGE, mirror_mode);
|
||||||
|
|
||||||
ASSERT_EQ(-EINVAL, mirror_uuid_set(&ioctx, "new-mirror-uuid"));
|
ASSERT_EQ(-EINVAL, mirror_uuid_set(&ioctx, "new-mirror-uuid"));
|
||||||
|
ASSERT_EQ(-EINVAL, mirror_remote_namespace_set(&ioctx, "new-remote-ns"));
|
||||||
|
|
||||||
ASSERT_EQ(0, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_POOL));
|
ASSERT_EQ(0, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_POOL));
|
||||||
ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
|
ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
|
||||||
@ -1726,6 +1733,7 @@ TEST_F(TestClsRbd, mirror) {
|
|||||||
ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
|
ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
|
||||||
ASSERT_EQ(cls::rbd::MIRROR_MODE_DISABLED, mirror_mode);
|
ASSERT_EQ(cls::rbd::MIRROR_MODE_DISABLED, mirror_mode);
|
||||||
ASSERT_EQ(-ENOENT, mirror_uuid_get(&ioctx, &uuid));
|
ASSERT_EQ(-ENOENT, mirror_uuid_get(&ioctx, &uuid));
|
||||||
|
ASSERT_EQ(-ENOENT, mirror_remote_namespace_get(&ioctx, &remote_ns));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestClsRbd, mirror_image) {
|
TEST_F(TestClsRbd, mirror_image) {
|
||||||
|
@ -2391,6 +2391,27 @@ class TestMirroring(object):
|
|||||||
self.rbd.mirror_site_name_set(rados, "")
|
self.rbd.mirror_site_name_set(rados, "")
|
||||||
eq(rados.get_fsid(), self.rbd.mirror_site_name_get(rados))
|
eq(rados.get_fsid(), self.rbd.mirror_site_name_get(rados))
|
||||||
|
|
||||||
|
def test_mirror_remote_namespace(self):
|
||||||
|
remote_namespace = "remote-ns"
|
||||||
|
# cannot set remote namespace for the default namespace
|
||||||
|
assert_raises(InvalidArgument, self.rbd.mirror_remote_namespace_set,
|
||||||
|
ioctx, remote_namespace)
|
||||||
|
eq("", self.rbd.mirror_remote_namespace_get(ioctx))
|
||||||
|
self.rbd.namespace_create(ioctx, "ns1")
|
||||||
|
ioctx.set_namespace("ns1")
|
||||||
|
self.rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_IMAGE)
|
||||||
|
# cannot set remote namespace while mirroring enabled
|
||||||
|
assert_raises(InvalidArgument, self.rbd.mirror_remote_namespace_set,
|
||||||
|
ioctx, remote_namespace)
|
||||||
|
self.rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_DISABLED)
|
||||||
|
# cannot set remote namespace to the default namespace
|
||||||
|
assert_raises(InvalidArgument, self.rbd.mirror_remote_namespace_set,
|
||||||
|
ioctx, "")
|
||||||
|
self.rbd.mirror_remote_namespace_set(ioctx, remote_namespace)
|
||||||
|
eq(remote_namespace, self.rbd.mirror_remote_namespace_get(ioctx))
|
||||||
|
ioctx.set_namespace("")
|
||||||
|
self.rbd.namespace_remove(ioctx, "ns1")
|
||||||
|
|
||||||
def test_mirror_peer_bootstrap(self):
|
def test_mirror_peer_bootstrap(self):
|
||||||
eq([], list(self.rbd.mirror_peer_list(ioctx)))
|
eq([], list(self.rbd.mirror_peer_list(ioctx)))
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ TEST_F(TestMockNamespaceReplayer, Init_LocalMirrorStatusUpdaterError) {
|
|||||||
expect_mirror_status_updater_init(*mock_local_mirror_status_updater, -EINVAL);
|
expect_mirror_status_updater_init(*mock_local_mirror_status_updater, -EINVAL);
|
||||||
|
|
||||||
MockNamespaceReplayer namespace_replayer(
|
MockNamespaceReplayer namespace_replayer(
|
||||||
{}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
{}, {}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
||||||
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
@ -432,7 +432,7 @@ TEST_F(TestMockNamespaceReplayer, Init_RemoteMirrorStatusUpdaterError) {
|
|||||||
expect_mirror_status_updater_shut_down(*mock_local_mirror_status_updater);
|
expect_mirror_status_updater_shut_down(*mock_local_mirror_status_updater);
|
||||||
|
|
||||||
MockNamespaceReplayer namespace_replayer(
|
MockNamespaceReplayer namespace_replayer(
|
||||||
{}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
{}, {}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
||||||
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
@ -458,7 +458,7 @@ TEST_F(TestMockNamespaceReplayer, Init_InstanceReplayerError) {
|
|||||||
expect_mirror_status_updater_shut_down(*mock_local_mirror_status_updater);
|
expect_mirror_status_updater_shut_down(*mock_local_mirror_status_updater);
|
||||||
|
|
||||||
MockNamespaceReplayer namespace_replayer(
|
MockNamespaceReplayer namespace_replayer(
|
||||||
{}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
{}, {}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
||||||
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
@ -489,7 +489,7 @@ TEST_F(TestMockNamespaceReplayer, Init_InstanceWatcherError) {
|
|||||||
expect_mirror_status_updater_shut_down(*mock_local_mirror_status_updater);
|
expect_mirror_status_updater_shut_down(*mock_local_mirror_status_updater);
|
||||||
|
|
||||||
MockNamespaceReplayer namespace_replayer(
|
MockNamespaceReplayer namespace_replayer(
|
||||||
{}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
{}, {}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
||||||
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
@ -517,7 +517,7 @@ TEST_F(TestMockNamespaceReplayer, Init) {
|
|||||||
|
|
||||||
MockServiceDaemon mock_service_daemon;
|
MockServiceDaemon mock_service_daemon;
|
||||||
MockNamespaceReplayer namespace_replayer(
|
MockNamespaceReplayer namespace_replayer(
|
||||||
{}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
{}, {}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
||||||
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
||||||
nullptr, nullptr, &mock_service_daemon, nullptr, nullptr);
|
nullptr, nullptr, &mock_service_daemon, nullptr, nullptr);
|
||||||
|
|
||||||
@ -557,7 +557,7 @@ TEST_F(TestMockNamespaceReplayer, AcquireLeader) {
|
|||||||
|
|
||||||
MockServiceDaemon mock_service_daemon;
|
MockServiceDaemon mock_service_daemon;
|
||||||
MockNamespaceReplayer namespace_replayer(
|
MockNamespaceReplayer namespace_replayer(
|
||||||
{}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
{}, {}, m_local_io_ctx, m_remote_io_ctx, "local mirror uuid",
|
||||||
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
"local peer uuid", {"remote mirror uuid", ""}, m_mock_threads,
|
||||||
nullptr, nullptr, &mock_service_daemon, nullptr, nullptr);
|
nullptr, nullptr, &mock_service_daemon, nullptr, nullptr);
|
||||||
|
|
||||||
|
@ -129,7 +129,8 @@ struct NamespaceReplayer<librbd::MockTestImageCtx> {
|
|||||||
static std::map<std::string, NamespaceReplayer *> s_instances;
|
static std::map<std::string, NamespaceReplayer *> s_instances;
|
||||||
|
|
||||||
static NamespaceReplayer *create(
|
static NamespaceReplayer *create(
|
||||||
const std::string &name,
|
const std::string &local_name,
|
||||||
|
const std::string &remote_name,
|
||||||
librados::IoCtx &local_ioctx,
|
librados::IoCtx &local_ioctx,
|
||||||
librados::IoCtx &remote_ioctx,
|
librados::IoCtx &remote_ioctx,
|
||||||
const std::string &local_mirror_uuid,
|
const std::string &local_mirror_uuid,
|
||||||
@ -141,14 +142,15 @@ struct NamespaceReplayer<librbd::MockTestImageCtx> {
|
|||||||
ServiceDaemon<librbd::MockTestImageCtx> *service_daemon,
|
ServiceDaemon<librbd::MockTestImageCtx> *service_daemon,
|
||||||
journal::CacheManagerHandler *cache_manager_handler,
|
journal::CacheManagerHandler *cache_manager_handler,
|
||||||
PoolMetaCache* pool_meta_cache) {
|
PoolMetaCache* pool_meta_cache) {
|
||||||
ceph_assert(s_instances.count(name));
|
ceph_assert(s_instances.count(local_name));
|
||||||
auto namespace_replayer = s_instances[name];
|
auto namespace_replayer = s_instances[local_name];
|
||||||
s_instances.erase(name);
|
s_instances.erase(local_name);
|
||||||
return namespace_replayer;
|
return namespace_replayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_METHOD0(is_blocklisted, bool());
|
MOCK_METHOD0(is_blocklisted, bool());
|
||||||
MOCK_METHOD0(get_instance_id, std::string());
|
MOCK_METHOD0(get_instance_id, std::string());
|
||||||
|
MOCK_METHOD0(get_remote_namespace, std::string());
|
||||||
|
|
||||||
MOCK_METHOD1(init, void(Context*));
|
MOCK_METHOD1(init, void(Context*));
|
||||||
MOCK_METHOD1(shut_down, void(Context*));
|
MOCK_METHOD1(shut_down, void(Context*));
|
||||||
@ -363,6 +365,18 @@ public:
|
|||||||
Return(0)));
|
Return(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void expect_mirror_remote_namespace_get(
|
||||||
|
librados::MockTestMemIoCtxImpl *io_ctx_impl,
|
||||||
|
const std::string &remote_namespace, int r) {
|
||||||
|
EXPECT_CALL(*io_ctx_impl,
|
||||||
|
exec(RBD_MIRRORING, _, StrEq("rbd"),
|
||||||
|
StrEq("mirror_remote_namespace_get"), _, _, _, _))
|
||||||
|
.WillRepeatedly(DoAll(WithArg<5>(Invoke([remote_namespace](bufferlist *bl) {
|
||||||
|
encode(remote_namespace, *bl);
|
||||||
|
})),
|
||||||
|
Return(r)));
|
||||||
|
}
|
||||||
|
|
||||||
void expect_clone(librados::MockTestMemIoCtxImpl* mock_io_ctx) {
|
void expect_clone(librados::MockTestMemIoCtxImpl* mock_io_ctx) {
|
||||||
EXPECT_CALL(*mock_io_ctx, clone())
|
EXPECT_CALL(*mock_io_ctx, clone())
|
||||||
.WillRepeatedly(Invoke([mock_io_ctx]() {
|
.WillRepeatedly(Invoke([mock_io_ctx]() {
|
||||||
@ -510,6 +524,13 @@ public:
|
|||||||
EXPECT_CALL(mock_namespace_replayer, handle_instances_removed(_));
|
EXPECT_CALL(mock_namespace_replayer, handle_instances_removed(_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void expect_namespace_replayer_get_remote_namespace(
|
||||||
|
MockNamespaceReplayer &mock_namespace_replayer,
|
||||||
|
const std::string& remote_namespace) {
|
||||||
|
EXPECT_CALL(mock_namespace_replayer, get_remote_namespace())
|
||||||
|
.WillRepeatedly(Return(remote_namespace));
|
||||||
|
}
|
||||||
|
|
||||||
void expect_service_daemon_add_namespace(
|
void expect_service_daemon_add_namespace(
|
||||||
MockServiceDaemon &mock_service_daemon,
|
MockServiceDaemon &mock_service_daemon,
|
||||||
const std::string& namespace_name) {
|
const std::string& namespace_name) {
|
||||||
@ -714,10 +735,14 @@ TEST_F(TestMockPoolReplayer, Namespaces) {
|
|||||||
auto mock_ns1_namespace_replayer = new MockNamespaceReplayer("ns1");
|
auto mock_ns1_namespace_replayer = new MockNamespaceReplayer("ns1");
|
||||||
expect_namespace_replayer_is_blocklisted(*mock_ns1_namespace_replayer,
|
expect_namespace_replayer_is_blocklisted(*mock_ns1_namespace_replayer,
|
||||||
false);
|
false);
|
||||||
|
expect_namespace_replayer_get_remote_namespace(*mock_ns1_namespace_replayer,
|
||||||
|
"ns1");
|
||||||
|
|
||||||
auto mock_ns2_namespace_replayer = new MockNamespaceReplayer("ns2");
|
auto mock_ns2_namespace_replayer = new MockNamespaceReplayer("ns2");
|
||||||
expect_namespace_replayer_is_blocklisted(*mock_ns2_namespace_replayer,
|
expect_namespace_replayer_is_blocklisted(*mock_ns2_namespace_replayer,
|
||||||
false);
|
false);
|
||||||
|
expect_namespace_replayer_get_remote_namespace(*mock_ns2_namespace_replayer,
|
||||||
|
"ns2");
|
||||||
|
|
||||||
MockThreads mock_threads(m_threads);
|
MockThreads mock_threads(m_threads);
|
||||||
expect_work_queue(mock_threads);
|
expect_work_queue(mock_threads);
|
||||||
@ -737,6 +762,7 @@ TEST_F(TestMockPoolReplayer, Namespaces) {
|
|||||||
|
|
||||||
expect_clone(mock_local_io_ctx);
|
expect_clone(mock_local_io_ctx);
|
||||||
expect_mirror_mode_get(mock_local_io_ctx);
|
expect_mirror_mode_get(mock_local_io_ctx);
|
||||||
|
expect_mirror_remote_namespace_get(mock_local_io_ctx, "", -ENOENT);
|
||||||
|
|
||||||
InSequence seq;
|
InSequence seq;
|
||||||
|
|
||||||
@ -856,6 +882,7 @@ TEST_F(TestMockPoolReplayer, NamespacesError) {
|
|||||||
|
|
||||||
expect_clone(mock_local_io_ctx);
|
expect_clone(mock_local_io_ctx);
|
||||||
expect_mirror_mode_get(mock_local_io_ctx);
|
expect_mirror_mode_get(mock_local_io_ctx);
|
||||||
|
expect_mirror_remote_namespace_get(mock_local_io_ctx, "", -ENOENT);
|
||||||
|
|
||||||
InSequence seq;
|
InSequence seq;
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ namespace po = boost::program_options;
|
|||||||
|
|
||||||
static const std::string ALL_NAME("all");
|
static const std::string ALL_NAME("all");
|
||||||
static const std::string SITE_NAME("site-name");
|
static const std::string SITE_NAME("site-name");
|
||||||
|
static const std::string REMOTE_NAMESPACE_NAME("remote-namespace");
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -1242,6 +1243,10 @@ void get_enable_arguments(po::options_description *positional,
|
|||||||
positional->add_options()
|
positional->add_options()
|
||||||
("mode", "mirror mode [image or pool]");
|
("mode", "mirror mode [image or pool]");
|
||||||
add_site_name_optional(options);
|
add_site_name_optional(options);
|
||||||
|
|
||||||
|
options->add_options()
|
||||||
|
(REMOTE_NAMESPACE_NAME.c_str(), po::value<std::string>(),
|
||||||
|
"remote namespace name");
|
||||||
}
|
}
|
||||||
|
|
||||||
int execute_enable_disable(librados::IoCtx& io_ctx,
|
int execute_enable_disable(librados::IoCtx& io_ctx,
|
||||||
@ -1310,6 +1315,7 @@ int execute_enable(const po::variables_map &vm,
|
|||||||
const std::vector<std::string> &ceph_global_init_args) {
|
const std::vector<std::string> &ceph_global_init_args) {
|
||||||
std::string pool_name;
|
std::string pool_name;
|
||||||
std::string namespace_name;
|
std::string namespace_name;
|
||||||
|
std::string remote_namespace;
|
||||||
size_t arg_index = 0;
|
size_t arg_index = 0;
|
||||||
int r = utils::get_pool_and_namespace_names(vm, true, &pool_name,
|
int r = utils::get_pool_and_namespace_names(vm, true, &pool_name,
|
||||||
&namespace_name, &arg_index);
|
&namespace_name, &arg_index);
|
||||||
@ -1336,15 +1342,36 @@ int execute_enable(const po::variables_map &vm,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vm.count(REMOTE_NAMESPACE_NAME)) {
|
||||||
|
remote_namespace = vm[REMOTE_NAMESPACE_NAME].as<std::string>();
|
||||||
|
} else {
|
||||||
|
remote_namespace = namespace_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string original_remote_namespace;
|
||||||
|
librbd::RBD rbd;
|
||||||
|
r = rbd.mirror_remote_namespace_get(io_ctx, &original_remote_namespace);
|
||||||
|
if (r < 0) {
|
||||||
|
std::cerr << "rbd: failed to get the current remote namespace."
|
||||||
|
<< std::endl;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (original_remote_namespace != remote_namespace) {
|
||||||
|
r = rbd.mirror_remote_namespace_set(io_ctx, remote_namespace);
|
||||||
|
if (r < 0) {
|
||||||
|
std::cerr << "rbd: failed to set the remote namespace."
|
||||||
|
<< std::endl;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
if (vm.count(SITE_NAME)) {
|
if (vm.count(SITE_NAME)) {
|
||||||
librbd::RBD rbd;
|
|
||||||
|
|
||||||
auto site_name = vm[SITE_NAME].as<std::string>();
|
auto site_name = vm[SITE_NAME].as<std::string>();
|
||||||
std::string original_site_name;
|
std::string original_site_name;
|
||||||
r = rbd.mirror_site_name_get(rados, &original_site_name);
|
r = rbd.mirror_site_name_get(rados, &original_site_name);
|
||||||
updated = (r >= 0 && site_name != original_site_name);
|
updated = (r >= 0 && site_name != original_site_name);
|
||||||
|
|
||||||
r = set_site_name(rados, site_name);
|
r = set_site_name(rados, site_name);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
@ -1366,6 +1393,8 @@ int execute_info(const po::variables_map &vm,
|
|||||||
const std::vector<std::string> &ceph_global_init_args) {
|
const std::vector<std::string> &ceph_global_init_args) {
|
||||||
std::string pool_name;
|
std::string pool_name;
|
||||||
std::string namespace_name;
|
std::string namespace_name;
|
||||||
|
std::string remote_namespace;
|
||||||
|
std::string mirror_uuid;
|
||||||
size_t arg_index = 0;
|
size_t arg_index = 0;
|
||||||
int r = utils::get_pool_and_namespace_names(vm, false, &pool_name,
|
int r = utils::get_pool_and_namespace_names(vm, false, &pool_name,
|
||||||
&namespace_name, &arg_index);
|
&namespace_name, &arg_index);
|
||||||
@ -1407,6 +1436,13 @@ int execute_info(const po::variables_map &vm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mirror_mode != RBD_MIRROR_MODE_DISABLED) {
|
||||||
|
r = rbd.mirror_remote_namespace_get(io_ctx, &remote_namespace);
|
||||||
|
if (r < 0) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string mirror_mode_desc;
|
std::string mirror_mode_desc;
|
||||||
switch (mirror_mode) {
|
switch (mirror_mode) {
|
||||||
case RBD_MIRROR_MODE_DISABLED:
|
case RBD_MIRROR_MODE_DISABLED:
|
||||||
@ -1430,18 +1466,26 @@ int execute_info(const po::variables_map &vm,
|
|||||||
std::cout << "Mode: " << mirror_mode_desc << std::endl;
|
std::cout << "Mode: " << mirror_mode_desc << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mirror_mode != RBD_MIRROR_MODE_DISABLED && namespace_name.empty()) {
|
if (mirror_mode != RBD_MIRROR_MODE_DISABLED) {
|
||||||
if (formatter != nullptr) {
|
if (namespace_name.empty()) {
|
||||||
formatter->dump_string("site_name", site_name);
|
if (formatter != nullptr) {
|
||||||
} else {
|
formatter->dump_string("site_name", site_name);
|
||||||
std::cout << "Site Name: " << site_name << std::endl
|
} else {
|
||||||
<< std::endl;
|
std::cout << "Site Name: " << site_name << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (formatter != nullptr) {
|
||||||
r = format_mirror_peers(io_ctx, formatter, mirror_peers,
|
formatter->dump_string("remote_namespace", remote_namespace);
|
||||||
vm[ALL_NAME].as<bool>());
|
} else {
|
||||||
if (r < 0) {
|
std::cout << "Remote Namespace: " << remote_namespace << std::endl
|
||||||
return r;
|
<< std::endl;
|
||||||
|
}
|
||||||
|
if (namespace_name.empty()) {
|
||||||
|
r = format_mirror_peers(io_ctx, formatter, mirror_peers,
|
||||||
|
vm[ALL_NAME].as<bool>());
|
||||||
|
if (r < 0) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (formatter != nullptr) {
|
if (formatter != nullptr) {
|
||||||
|
@ -36,7 +36,8 @@ const std::string SERVICE_DAEMON_REMOTE_COUNT_KEY("image_remote_count");
|
|||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
NamespaceReplayer<I>::NamespaceReplayer(
|
NamespaceReplayer<I>::NamespaceReplayer(
|
||||||
const std::string &name,
|
const std::string &local_name,
|
||||||
|
const std::string &remote_name,
|
||||||
librados::IoCtx &local_io_ctx, librados::IoCtx &remote_io_ctx,
|
librados::IoCtx &local_io_ctx, librados::IoCtx &remote_io_ctx,
|
||||||
const std::string &local_mirror_uuid,
|
const std::string &local_mirror_uuid,
|
||||||
const std::string& local_mirror_peer_uuid,
|
const std::string& local_mirror_peer_uuid,
|
||||||
@ -47,7 +48,8 @@ NamespaceReplayer<I>::NamespaceReplayer(
|
|||||||
ServiceDaemon<I> *service_daemon,
|
ServiceDaemon<I> *service_daemon,
|
||||||
journal::CacheManagerHandler *cache_manager_handler,
|
journal::CacheManagerHandler *cache_manager_handler,
|
||||||
PoolMetaCache* pool_meta_cache) :
|
PoolMetaCache* pool_meta_cache) :
|
||||||
m_namespace_name(name),
|
m_local_namespace_name(local_name),
|
||||||
|
m_remote_namespace_name(remote_name),
|
||||||
m_local_mirror_uuid(local_mirror_uuid),
|
m_local_mirror_uuid(local_mirror_uuid),
|
||||||
m_local_mirror_peer_uuid(local_mirror_peer_uuid),
|
m_local_mirror_peer_uuid(local_mirror_peer_uuid),
|
||||||
m_remote_pool_meta(remote_pool_meta),
|
m_remote_pool_meta(remote_pool_meta),
|
||||||
@ -57,16 +59,19 @@ NamespaceReplayer<I>::NamespaceReplayer(
|
|||||||
m_cache_manager_handler(cache_manager_handler),
|
m_cache_manager_handler(cache_manager_handler),
|
||||||
m_pool_meta_cache(pool_meta_cache),
|
m_pool_meta_cache(pool_meta_cache),
|
||||||
m_lock(ceph::make_mutex(librbd::util::unique_lock_name(
|
m_lock(ceph::make_mutex(librbd::util::unique_lock_name(
|
||||||
"rbd::mirror::NamespaceReplayer " + name, this))),
|
"rbd::mirror::NamespaceReplayer " + local_name, this))),
|
||||||
m_local_pool_watcher_listener(this, true),
|
m_local_pool_watcher_listener(this, true),
|
||||||
m_remote_pool_watcher_listener(this, false),
|
m_remote_pool_watcher_listener(this, false),
|
||||||
m_image_map_listener(this) {
|
m_image_map_listener(this) {
|
||||||
dout(10) << name << dendl;
|
dout(10) << "local_name=" << local_name
|
||||||
|
<< ", remote_name=" << remote_name
|
||||||
|
<< ", local_mirror_uuid=" << m_local_mirror_uuid
|
||||||
|
<< dendl;
|
||||||
|
|
||||||
m_local_io_ctx.dup(local_io_ctx);
|
m_local_io_ctx.dup(local_io_ctx);
|
||||||
m_local_io_ctx.set_namespace(name);
|
m_local_io_ctx.set_namespace(local_name);
|
||||||
m_remote_io_ctx.dup(remote_io_ctx);
|
m_remote_io_ctx.dup(remote_io_ctx);
|
||||||
m_remote_io_ctx.set_namespace(name);
|
m_remote_io_ctx.set_namespace(remote_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
@ -856,6 +861,16 @@ void NamespaceReplayer<I>::handle_remove_image(const std::string &mirror_uuid,
|
|||||||
mirror_uuid, on_finish);
|
mirror_uuid, on_finish);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
std::string NamespaceReplayer<I>::get_local_namespace() {
|
||||||
|
return m_local_namespace_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
std::string NamespaceReplayer<I>::get_remote_namespace() {
|
||||||
|
return m_remote_namespace_name;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mirror
|
} // namespace mirror
|
||||||
} // namespace rbd
|
} // namespace rbd
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@ template <typename ImageCtxT = librbd::ImageCtx>
|
|||||||
class NamespaceReplayer {
|
class NamespaceReplayer {
|
||||||
public:
|
public:
|
||||||
static NamespaceReplayer *create(
|
static NamespaceReplayer *create(
|
||||||
const std::string &name,
|
const std::string &local_name,
|
||||||
|
const std::string &remote_name,
|
||||||
librados::IoCtx &local_ioctx,
|
librados::IoCtx &local_ioctx,
|
||||||
librados::IoCtx &remote_ioctx,
|
librados::IoCtx &remote_ioctx,
|
||||||
const std::string &local_mirror_uuid,
|
const std::string &local_mirror_uuid,
|
||||||
@ -55,7 +56,7 @@ public:
|
|||||||
ServiceDaemon<ImageCtxT> *service_daemon,
|
ServiceDaemon<ImageCtxT> *service_daemon,
|
||||||
journal::CacheManagerHandler *cache_manager_handler,
|
journal::CacheManagerHandler *cache_manager_handler,
|
||||||
PoolMetaCache* pool_meta_cache) {
|
PoolMetaCache* pool_meta_cache) {
|
||||||
return new NamespaceReplayer(name, local_ioctx, remote_ioctx,
|
return new NamespaceReplayer(local_name, remote_name, local_ioctx, remote_ioctx,
|
||||||
local_mirror_uuid, local_mirror_peer_uuid,
|
local_mirror_uuid, local_mirror_peer_uuid,
|
||||||
remote_pool_meta, threads,
|
remote_pool_meta, threads,
|
||||||
image_sync_throttler, image_deletion_throttler,
|
image_sync_throttler, image_deletion_throttler,
|
||||||
@ -63,7 +64,8 @@ public:
|
|||||||
pool_meta_cache);
|
pool_meta_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
NamespaceReplayer(const std::string &name,
|
NamespaceReplayer(const std::string &local_name,
|
||||||
|
const std::string &remote_name,
|
||||||
librados::IoCtx &local_ioctx,
|
librados::IoCtx &local_ioctx,
|
||||||
librados::IoCtx &remote_ioctx,
|
librados::IoCtx &remote_ioctx,
|
||||||
const std::string &local_mirror_uuid,
|
const std::string &local_mirror_uuid,
|
||||||
@ -95,6 +97,9 @@ public:
|
|||||||
void restart();
|
void restart();
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
|
std::string get_local_namespace();
|
||||||
|
std::string get_remote_namespace();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @verbatim
|
* @verbatim
|
||||||
@ -264,7 +269,8 @@ private:
|
|||||||
const std::string &instance_id,
|
const std::string &instance_id,
|
||||||
Context* on_finish);
|
Context* on_finish);
|
||||||
|
|
||||||
std::string m_namespace_name;
|
std::string m_local_namespace_name;
|
||||||
|
std::string m_remote_namespace_name;
|
||||||
librados::IoCtx m_local_io_ctx;
|
librados::IoCtx m_local_io_ctx;
|
||||||
librados::IoCtx m_remote_io_ctx;
|
librados::IoCtx m_remote_io_ctx;
|
||||||
std::string m_local_mirror_uuid;
|
std::string m_local_mirror_uuid;
|
||||||
|
@ -369,7 +369,7 @@ void PoolReplayer<I>::init(const std::string& site_name) {
|
|||||||
m_local_io_ctx.get_id(), {m_local_mirror_uuid});
|
m_local_io_ctx.get_id(), {m_local_mirror_uuid});
|
||||||
|
|
||||||
m_default_namespace_replayer.reset(NamespaceReplayer<I>::create(
|
m_default_namespace_replayer.reset(NamespaceReplayer<I>::create(
|
||||||
"", m_local_io_ctx, m_remote_io_ctx, m_local_mirror_uuid, m_peer.uuid,
|
"", "", m_local_io_ctx, m_remote_io_ctx, m_local_mirror_uuid, m_peer.uuid,
|
||||||
m_remote_pool_meta, m_threads, m_image_sync_throttler.get(),
|
m_remote_pool_meta, m_threads, m_image_sync_throttler.get(),
|
||||||
m_image_deletion_throttler.get(), m_service_daemon,
|
m_image_deletion_throttler.get(), m_service_daemon,
|
||||||
m_cache_manager_handler, m_pool_meta_cache));
|
m_cache_manager_handler, m_pool_meta_cache));
|
||||||
@ -638,7 +638,7 @@ void PoolReplayer<I>::update_namespace_replayers() {
|
|||||||
|
|
||||||
ceph_assert(ceph_mutex_is_locked(m_lock));
|
ceph_assert(ceph_mutex_is_locked(m_lock));
|
||||||
|
|
||||||
std::set<std::string> mirroring_namespaces;
|
std::map<std::string, std::string> mirroring_namespaces;
|
||||||
if (!m_stopping) {
|
if (!m_stopping) {
|
||||||
int r = list_mirroring_namespaces(&mirroring_namespaces);
|
int r = list_mirroring_namespaces(&mirroring_namespaces);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -652,7 +652,8 @@ void PoolReplayer<I>::update_namespace_replayers() {
|
|||||||
for (auto it = m_namespace_replayers.begin();
|
for (auto it = m_namespace_replayers.begin();
|
||||||
it != m_namespace_replayers.end(); ) {
|
it != m_namespace_replayers.end(); ) {
|
||||||
auto iter = mirroring_namespaces.find(it->first);
|
auto iter = mirroring_namespaces.find(it->first);
|
||||||
if (iter == mirroring_namespaces.end()) {
|
if (iter == mirroring_namespaces.end() ||
|
||||||
|
it->second->get_remote_namespace() != iter->second) {
|
||||||
auto namespace_replayer = it->second;
|
auto namespace_replayer = it->second;
|
||||||
auto on_shut_down = new LambdaContext(
|
auto on_shut_down = new LambdaContext(
|
||||||
[namespace_replayer, ctx=gather_ctx->new_sub()](int r) {
|
[namespace_replayer, ctx=gather_ctx->new_sub()](int r) {
|
||||||
@ -668,24 +669,24 @@ void PoolReplayer<I>::update_namespace_replayers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &name : mirroring_namespaces) {
|
for (auto &names : mirroring_namespaces) {
|
||||||
auto namespace_replayer = NamespaceReplayer<I>::create(
|
auto namespace_replayer = NamespaceReplayer<I>::create(
|
||||||
name, m_local_io_ctx, m_remote_io_ctx, m_local_mirror_uuid, m_peer.uuid,
|
names.first, names.second, m_local_io_ctx, m_remote_io_ctx,
|
||||||
m_remote_pool_meta, m_threads, m_image_sync_throttler.get(),
|
m_local_mirror_uuid, m_peer.uuid, m_remote_pool_meta, m_threads,
|
||||||
m_image_deletion_throttler.get(), m_service_daemon,
|
m_image_sync_throttler.get(), m_image_deletion_throttler.get(),
|
||||||
m_cache_manager_handler, m_pool_meta_cache);
|
m_service_daemon, m_cache_manager_handler, m_pool_meta_cache);
|
||||||
auto on_init = new LambdaContext(
|
auto on_init = new LambdaContext(
|
||||||
[this, namespace_replayer, name, &mirroring_namespaces,
|
[this, namespace_replayer, names, &mirroring_namespaces,
|
||||||
ctx=gather_ctx->new_sub()](int r) {
|
ctx=gather_ctx->new_sub()](int r) {
|
||||||
std::lock_guard locker{m_lock};
|
std::lock_guard locker{m_lock};
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
derr << "failed to initialize namespace replayer for namespace "
|
derr << "failed to initialize namespace replayer for namespace "
|
||||||
<< name << ": " << cpp_strerror(r) << dendl;
|
<< names.first << ": " << cpp_strerror(r) << dendl;
|
||||||
delete namespace_replayer;
|
delete namespace_replayer;
|
||||||
mirroring_namespaces.erase(name);
|
mirroring_namespaces.erase(names.first);
|
||||||
} else {
|
} else {
|
||||||
m_namespace_replayers[name] = namespace_replayer;
|
m_namespace_replayers[names.first] = namespace_replayer;
|
||||||
m_service_daemon->add_namespace(m_local_pool_id, name);
|
m_service_daemon->add_namespace(m_local_pool_id, names.first);
|
||||||
}
|
}
|
||||||
ctx->complete(r);
|
ctx->complete(r);
|
||||||
});
|
});
|
||||||
@ -702,8 +703,8 @@ void PoolReplayer<I>::update_namespace_replayers() {
|
|||||||
C_SaferCond acquire_cond;
|
C_SaferCond acquire_cond;
|
||||||
auto acquire_gather_ctx = new C_Gather(cct, &acquire_cond);
|
auto acquire_gather_ctx = new C_Gather(cct, &acquire_cond);
|
||||||
|
|
||||||
for (auto &name : mirroring_namespaces) {
|
for (auto &names : mirroring_namespaces) {
|
||||||
namespace_replayer_acquire_leader(name, acquire_gather_ctx->new_sub());
|
namespace_replayer_acquire_leader(names.first, acquire_gather_ctx->new_sub());
|
||||||
}
|
}
|
||||||
acquire_gather_ctx->activate();
|
acquire_gather_ctx->activate();
|
||||||
|
|
||||||
@ -714,8 +715,8 @@ void PoolReplayer<I>::update_namespace_replayers() {
|
|||||||
std::vector<std::string> instance_ids;
|
std::vector<std::string> instance_ids;
|
||||||
m_leader_watcher->list_instances(&instance_ids);
|
m_leader_watcher->list_instances(&instance_ids);
|
||||||
|
|
||||||
for (auto &name : mirroring_namespaces) {
|
for (auto &names : mirroring_namespaces) {
|
||||||
auto it = m_namespace_replayers.find(name);
|
auto it = m_namespace_replayers.find(names.first);
|
||||||
if (it == m_namespace_replayers.end()) {
|
if (it == m_namespace_replayers.end()) {
|
||||||
// acquire leader for this namespace replayer failed
|
// acquire leader for this namespace replayer failed
|
||||||
continue;
|
continue;
|
||||||
@ -725,8 +726,8 @@ void PoolReplayer<I>::update_namespace_replayers() {
|
|||||||
} else {
|
} else {
|
||||||
std::string leader_instance_id;
|
std::string leader_instance_id;
|
||||||
if (m_leader_watcher->get_leader_instance_id(&leader_instance_id)) {
|
if (m_leader_watcher->get_leader_instance_id(&leader_instance_id)) {
|
||||||
for (auto &name : mirroring_namespaces) {
|
for (auto &names : mirroring_namespaces) {
|
||||||
m_namespace_replayers[name]->handle_update_leader(leader_instance_id);
|
m_namespace_replayers[names.first]->handle_update_leader(leader_instance_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -734,7 +735,7 @@ void PoolReplayer<I>::update_namespace_replayers() {
|
|||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
int PoolReplayer<I>::list_mirroring_namespaces(
|
int PoolReplayer<I>::list_mirroring_namespaces(
|
||||||
std::set<std::string> *namespaces) {
|
std::map<std::string, std::string> *namespaces) {
|
||||||
dout(20) << dendl;
|
dout(20) << dendl;
|
||||||
ceph_assert(ceph_mutex_is_locked(m_lock));
|
ceph_assert(ceph_mutex_is_locked(m_lock));
|
||||||
|
|
||||||
@ -751,6 +752,7 @@ int PoolReplayer<I>::list_mirroring_namespaces(
|
|||||||
ns_ioctx.dup(m_local_io_ctx);
|
ns_ioctx.dup(m_local_io_ctx);
|
||||||
ns_ioctx.set_namespace(name);
|
ns_ioctx.set_namespace(name);
|
||||||
|
|
||||||
|
std::string remote_namespace;
|
||||||
cls::rbd::MirrorMode mirror_mode = cls::rbd::MIRROR_MODE_DISABLED;
|
cls::rbd::MirrorMode mirror_mode = cls::rbd::MIRROR_MODE_DISABLED;
|
||||||
int r = librbd::cls_client::mirror_mode_get(&ns_ioctx, &mirror_mode);
|
int r = librbd::cls_client::mirror_mode_get(&ns_ioctx, &mirror_mode);
|
||||||
if (r < 0 && r != -ENOENT) {
|
if (r < 0 && r != -ENOENT) {
|
||||||
@ -763,8 +765,21 @@ int PoolReplayer<I>::list_mirroring_namespaces(
|
|||||||
dout(10) << "mirroring is disabled for namespace " << name << dendl;
|
dout(10) << "mirroring is disabled for namespace " << name << dendl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
r = librbd::cls_client::mirror_remote_namespace_get(&ns_ioctx,
|
||||||
|
&remote_namespace);
|
||||||
|
if (r < 0) {
|
||||||
|
if (r != -ENOENT && r != -EOPNOTSUPP) {
|
||||||
|
derr << "failed to get remote mirror namespace: " << cpp_strerror(r)
|
||||||
|
<< dendl;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
remote_namespace = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespaces->insert(name);
|
dout(10) << " local namespace=" << name << ", remote namespace="
|
||||||
|
<< remote_namespace << dendl;
|
||||||
|
namespaces->insert(std::make_pair(name, remote_namespace));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -107,7 +107,7 @@ private:
|
|||||||
bool strip_cluster_overrides);
|
bool strip_cluster_overrides);
|
||||||
|
|
||||||
void update_namespace_replayers();
|
void update_namespace_replayers();
|
||||||
int list_mirroring_namespaces(std::set<std::string> *namespaces);
|
int list_mirroring_namespaces(std::map<std::string, std::string> *namespaces);
|
||||||
|
|
||||||
void namespace_replayer_acquire_leader(const std::string &name,
|
void namespace_replayer_acquire_leader(const std::string &name,
|
||||||
Context *on_finish);
|
Context *on_finish);
|
||||||
|
Loading…
Reference in New Issue
Block a user