namespace po = boost::program_options;
static const std::string ALL_NAME("all");
+static const std::string SITE_NAME("site-name");
namespace {
+void add_site_name_optional(po::options_description *options) {
+ options->add_options()
+ (SITE_NAME.c_str(), po::value<std::string>(), "local site name");
+}
+
+int set_site_name(librados::Rados& rados, const std::string& site_name) {
+ librbd::RBD rbd;
+ int r = rbd.mirror_site_name_set(rados, site_name);
+ if (r == -EOPNOTSUPP) {
+ std::cerr << "rbd: cluster does not support site names" << std::endl;
+ return r;
+ } else if (r < 0) {
+ std::cerr << "rbd: failed to set site name" << cpp_strerror(r)
+ << std::endl;
+ return r;
+ }
+
+ return 0;
+}
+
int validate_mirroring_enabled(librados::IoCtx& io_ctx) {
librbd::RBD rbd;
rbd_mirror_mode_t mirror_mode;
at::add_pool_options(positional, options, true);
positional->add_options()
("mode", "mirror mode [image or pool]");
+ add_site_name_optional(options);
}
-int execute_enable_disable(const std::string &pool_name,
- const std::string &namespace_name,
+int execute_enable_disable(librados::IoCtx& io_ctx,
rbd_mirror_mode_t next_mirror_mode,
- const std::string &mode) {
- librados::Rados rados;
- librados::IoCtx io_ctx;
- rbd_mirror_mode_t current_mirror_mode;
-
- int r = utils::init(pool_name, namespace_name, &rados, &io_ctx);
- if (r < 0) {
- return r;
- }
-
+ const std::string &mode, bool ignore_no_update) {
librbd::RBD rbd;
- r = rbd.mirror_mode_get(io_ctx, ¤t_mirror_mode);
+ rbd_mirror_mode_t current_mirror_mode;
+ int r = rbd.mirror_mode_get(io_ctx, ¤t_mirror_mode);
if (r < 0) {
std::cerr << "rbd: failed to retrieve mirror mode: "
<< cpp_strerror(r) << std::endl;
}
if (current_mirror_mode == next_mirror_mode) {
- if (mode == "disabled") {
- std::cout << "mirroring is already " << mode << std::endl;
- } else {
- std::cout << "mirroring is already configured for "
- << mode << " mode" << std::endl;
+ if (!ignore_no_update) {
+ if (mode == "disabled") {
+ std::cout << "rbd: mirroring is already " << mode << std::endl;
+ } else {
+ std::cout << "rbd: mirroring is already configured for "
+ << mode << " mode" << std::endl;
+ }
}
return 0;
} else if (next_mirror_mode == RBD_MIRROR_MODE_IMAGE &&
return r;
}
- return execute_enable_disable(pool_name, namespace_name,
- RBD_MIRROR_MODE_DISABLED, "disabled");
+ librados::Rados rados;
+ librados::IoCtx io_ctx;
+
+ r = utils::init(pool_name, namespace_name, &rados, &io_ctx);
+ if (r < 0) {
+ return r;
+ }
+
+ return execute_enable_disable(io_ctx, RBD_MIRROR_MODE_DISABLED, "disabled",
+ false);
}
int execute_enable(const po::variables_map &vm,
return -EINVAL;
}
- return execute_enable_disable(pool_name, namespace_name, mirror_mode, mode);
+ librados::Rados rados;
+ librados::IoCtx io_ctx;
+
+ r = utils::init(pool_name, namespace_name, &rados, &io_ctx);
+ if (r < 0) {
+ 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;
+ }
+ }
+
+ return execute_enable_disable(io_ctx, mirror_mode, mode, updated);
}
void get_info_arguments(po::options_description *positional,
return r;
}
+ std::string site_name;
+ r = rbd.mirror_site_name_get(rados, &site_name);
+ if (r < 0 && r != -EOPNOTSUPP) {
+ return r;
+ }
+
std::vector<librbd::mirror_peer_t> mirror_peers;
if (namespace_name.empty()) {
r = rbd.mirror_peer_list(io_ctx, &mirror_peers);
}
if (mirror_mode != RBD_MIRROR_MODE_DISABLED && namespace_name.empty()) {
+ if (formatter != nullptr) {
+ formatter->dump_string("site_name", site_name);
+ } else {
+ std::cout << "Site Name: " << site_name << std::endl;
+ }
+
r = format_mirror_peers(io_ctx, formatter, mirror_peers,
vm[ALL_NAME].as<bool>());
if (r < 0) {