diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2024-09-18 15:13:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-18 15:13:31 +0200 |
commit | 2ae674d09c24b20a8c4fe80a4ec3a24271d73b09 (patch) | |
tree | d5d96bb10088f4b07d2dc6bca8b2c024674c799b /src/tools | |
parent | Merge pull request #59543 from xxhdx1985126/wip-63844 (diff) | |
parent | rbd: display mirror uuid for mirror pool info output (diff) | |
download | ceph-2ae674d09c24b20a8c4fe80a4ec3a24271d73b09.tar.xz ceph-2ae674d09c24b20a8c4fe80a4ec3a24271d73b09.zip |
Merge pull request #59417 from nbalacha/wip-nbalacha-ns-mirroring
rbd-mirror: allow mirroring to a different namespace
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/rbd/action/MirrorPool.cc | 74 | ||||
-rw-r--r-- | src/tools/rbd_mirror/NamespaceReplayer.cc | 27 | ||||
-rw-r--r-- | src/tools/rbd_mirror/NamespaceReplayer.h | 14 | ||||
-rw-r--r-- | src/tools/rbd_mirror/PoolReplayer.cc | 59 | ||||
-rw-r--r-- | src/tools/rbd_mirror/PoolReplayer.h | 2 |
5 files changed, 131 insertions, 45 deletions
diff --git a/src/tools/rbd/action/MirrorPool.cc b/src/tools/rbd/action/MirrorPool.cc index a7877870a04..58e2d4dc329 100644 --- a/src/tools/rbd/action/MirrorPool.cc +++ b/src/tools/rbd/action/MirrorPool.cc @@ -41,6 +41,7 @@ namespace po = boost::program_options; static const std::string ALL_NAME("all"); static const std::string SITE_NAME("site-name"); +static const std::string REMOTE_NAMESPACE_NAME("remote-namespace"); namespace { @@ -1242,6 +1243,10 @@ void get_enable_arguments(po::options_description *positional, positional->add_options() ("mode", "mirror mode [image or pool]"); 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, @@ -1310,6 +1315,7 @@ int execute_enable(const po::variables_map &vm, const std::vector<std::string> &ceph_global_init_args) { std::string pool_name; std::string namespace_name; + std::string remote_namespace; size_t arg_index = 0; int r = utils::get_pool_and_namespace_names(vm, true, &pool_name, &namespace_name, &arg_index); @@ -1336,15 +1342,36 @@ int execute_enable(const po::variables_map &vm, 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; if (vm.count(SITE_NAME)) { - librbd::RBD rbd; - auto site_name = vm[SITE_NAME].as<std::string>(); std::string original_site_name; r = rbd.mirror_site_name_get(rados, &original_site_name); updated = (r >= 0 && site_name != original_site_name); - r = set_site_name(rados, site_name); if (r < 0) { return r; @@ -1366,6 +1393,8 @@ int execute_info(const po::variables_map &vm, const std::vector<std::string> &ceph_global_init_args) { std::string pool_name; std::string namespace_name; + std::string remote_namespace; + std::string mirror_uuid; size_t arg_index = 0; int r = utils::get_pool_and_namespace_names(vm, false, &pool_name, &namespace_name, &arg_index); @@ -1407,6 +1436,17 @@ int execute_info(const po::variables_map &vm, } } + if (mirror_mode != RBD_MIRROR_MODE_DISABLED) { + r = rbd.mirror_uuid_get(io_ctx, &mirror_uuid); + if (r < 0) { + return r; + } + r = rbd.mirror_remote_namespace_get(io_ctx, &remote_namespace); + if (r < 0) { + return r; + } + } + std::string mirror_mode_desc; switch (mirror_mode) { case RBD_MIRROR_MODE_DISABLED: @@ -1430,18 +1470,28 @@ int execute_info(const po::variables_map &vm, 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 (namespace_name.empty()) { + if (formatter != nullptr) { + formatter->dump_string("site_name", site_name); + } else { + std::cout << "Site Name: " << site_name << std::endl; + } + } if (formatter != nullptr) { - formatter->dump_string("site_name", site_name); + formatter->dump_string("mirror_uuid", mirror_uuid); + formatter->dump_string("remote_namespace", remote_namespace); } else { - std::cout << "Site Name: " << site_name << std::endl - << std::endl; + std::cout << "Mirror UUID: " << mirror_uuid << std::endl; + std::cout << "Remote Namespace: " << remote_namespace << std::endl + << std::endl; } - - r = format_mirror_peers(io_ctx, formatter, mirror_peers, - vm[ALL_NAME].as<bool>()); - if (r < 0) { - return r; + 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) { diff --git a/src/tools/rbd_mirror/NamespaceReplayer.cc b/src/tools/rbd_mirror/NamespaceReplayer.cc index d305d847215..3f558e8ddba 100644 --- a/src/tools/rbd_mirror/NamespaceReplayer.cc +++ b/src/tools/rbd_mirror/NamespaceReplayer.cc @@ -36,7 +36,8 @@ const std::string SERVICE_DAEMON_REMOTE_COUNT_KEY("image_remote_count"); template <typename I> 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, const std::string &local_mirror_uuid, const std::string& local_mirror_peer_uuid, @@ -47,7 +48,8 @@ NamespaceReplayer<I>::NamespaceReplayer( ServiceDaemon<I> *service_daemon, journal::CacheManagerHandler *cache_manager_handler, 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_peer_uuid(local_mirror_peer_uuid), m_remote_pool_meta(remote_pool_meta), @@ -57,16 +59,19 @@ NamespaceReplayer<I>::NamespaceReplayer( m_cache_manager_handler(cache_manager_handler), m_pool_meta_cache(pool_meta_cache), 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_remote_pool_watcher_listener(this, false), 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.set_namespace(name); + m_local_io_ctx.set_namespace(local_name); 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> @@ -856,6 +861,16 @@ void NamespaceReplayer<I>::handle_remove_image(const std::string &mirror_uuid, 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 rbd diff --git a/src/tools/rbd_mirror/NamespaceReplayer.h b/src/tools/rbd_mirror/NamespaceReplayer.h index e304b8253f8..25b3369de78 100644 --- a/src/tools/rbd_mirror/NamespaceReplayer.h +++ b/src/tools/rbd_mirror/NamespaceReplayer.h @@ -43,7 +43,8 @@ template <typename ImageCtxT = librbd::ImageCtx> class NamespaceReplayer { public: static NamespaceReplayer *create( - const std::string &name, + const std::string &local_name, + const std::string &remote_name, librados::IoCtx &local_ioctx, librados::IoCtx &remote_ioctx, const std::string &local_mirror_uuid, @@ -55,7 +56,7 @@ public: ServiceDaemon<ImageCtxT> *service_daemon, journal::CacheManagerHandler *cache_manager_handler, 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, remote_pool_meta, threads, image_sync_throttler, image_deletion_throttler, @@ -63,7 +64,8 @@ public: 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 &remote_ioctx, const std::string &local_mirror_uuid, @@ -95,6 +97,9 @@ public: void restart(); void flush(); + std::string get_local_namespace(); + std::string get_remote_namespace(); + private: /** * @verbatim @@ -264,7 +269,8 @@ private: const std::string &instance_id, 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_remote_io_ctx; std::string m_local_mirror_uuid; diff --git a/src/tools/rbd_mirror/PoolReplayer.cc b/src/tools/rbd_mirror/PoolReplayer.cc index dcbedc67e42..2efb8bae38b 100644 --- a/src/tools/rbd_mirror/PoolReplayer.cc +++ b/src/tools/rbd_mirror/PoolReplayer.cc @@ -369,7 +369,7 @@ void PoolReplayer<I>::init(const std::string& site_name) { m_local_io_ctx.get_id(), {m_local_mirror_uuid}); 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_image_deletion_throttler.get(), m_service_daemon, 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)); - std::set<std::string> mirroring_namespaces; + std::map<std::string, std::string> mirroring_namespaces; if (!m_stopping) { int r = list_mirroring_namespaces(&mirroring_namespaces); if (r < 0) { @@ -652,7 +652,8 @@ void PoolReplayer<I>::update_namespace_replayers() { for (auto it = m_namespace_replayers.begin(); it != m_namespace_replayers.end(); ) { 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 on_shut_down = new LambdaContext( [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( - name, 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_image_deletion_throttler.get(), m_service_daemon, - m_cache_manager_handler, m_pool_meta_cache); + names.first, names.second, 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_image_deletion_throttler.get(), + m_service_daemon, m_cache_manager_handler, m_pool_meta_cache); auto on_init = new LambdaContext( - [this, namespace_replayer, name, &mirroring_namespaces, + [this, namespace_replayer, names, &mirroring_namespaces, ctx=gather_ctx->new_sub()](int r) { std::lock_guard locker{m_lock}; if (r < 0) { derr << "failed to initialize namespace replayer for namespace " - << name << ": " << cpp_strerror(r) << dendl; + << names.first << ": " << cpp_strerror(r) << dendl; delete namespace_replayer; - mirroring_namespaces.erase(name); + mirroring_namespaces.erase(names.first); } else { - m_namespace_replayers[name] = namespace_replayer; - m_service_daemon->add_namespace(m_local_pool_id, name); + m_namespace_replayers[names.first] = namespace_replayer; + m_service_daemon->add_namespace(m_local_pool_id, names.first); } ctx->complete(r); }); @@ -702,8 +703,8 @@ void PoolReplayer<I>::update_namespace_replayers() { C_SaferCond acquire_cond; auto acquire_gather_ctx = new C_Gather(cct, &acquire_cond); - for (auto &name : mirroring_namespaces) { - namespace_replayer_acquire_leader(name, acquire_gather_ctx->new_sub()); + for (auto &names : mirroring_namespaces) { + namespace_replayer_acquire_leader(names.first, acquire_gather_ctx->new_sub()); } acquire_gather_ctx->activate(); @@ -714,8 +715,8 @@ void PoolReplayer<I>::update_namespace_replayers() { std::vector<std::string> instance_ids; m_leader_watcher->list_instances(&instance_ids); - for (auto &name : mirroring_namespaces) { - auto it = m_namespace_replayers.find(name); + for (auto &names : mirroring_namespaces) { + auto it = m_namespace_replayers.find(names.first); if (it == m_namespace_replayers.end()) { // acquire leader for this namespace replayer failed continue; @@ -725,8 +726,8 @@ void PoolReplayer<I>::update_namespace_replayers() { } else { std::string leader_instance_id; if (m_leader_watcher->get_leader_instance_id(&leader_instance_id)) { - for (auto &name : mirroring_namespaces) { - m_namespace_replayers[name]->handle_update_leader(leader_instance_id); + for (auto &names : mirroring_namespaces) { + m_namespace_replayers[names.first]->handle_update_leader(leader_instance_id); } } } @@ -734,7 +735,7 @@ void PoolReplayer<I>::update_namespace_replayers() { template <typename I> int PoolReplayer<I>::list_mirroring_namespaces( - std::set<std::string> *namespaces) { + std::map<std::string, std::string> *namespaces) { dout(20) << dendl; 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.set_namespace(name); + std::string remote_namespace; cls::rbd::MirrorMode mirror_mode = cls::rbd::MIRROR_MODE_DISABLED; int r = librbd::cls_client::mirror_mode_get(&ns_ioctx, &mirror_mode); if (r < 0 && r != -ENOENT) { @@ -763,8 +765,21 @@ int PoolReplayer<I>::list_mirroring_namespaces( dout(10) << "mirroring is disabled for namespace " << name << dendl; continue; } - - namespaces->insert(name); + 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; + } + } + + dout(10) << " local namespace=" << name << ", remote namespace=" + << remote_namespace << dendl; + namespaces->insert(std::make_pair(name, remote_namespace)); } return 0; diff --git a/src/tools/rbd_mirror/PoolReplayer.h b/src/tools/rbd_mirror/PoolReplayer.h index e0fd753778d..4635f1ae6ba 100644 --- a/src/tools/rbd_mirror/PoolReplayer.h +++ b/src/tools/rbd_mirror/PoolReplayer.h @@ -107,7 +107,7 @@ private: bool strip_cluster_overrides); 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, Context *on_finish); |