From: Ilya Dryomov Date: Sat, 27 Aug 2022 09:09:00 +0000 (+0200) Subject: librbd: use actual monitor addresses when creating a peer bootstrap token X-Git-Tag: v16.2.11~352^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=62b51d63fb09cb400cc35631448ee50d171b8185;p=ceph.git librbd: use actual monitor addresses when creating a peer bootstrap token Relying on mon_host config option is fragile, as the user may confuse v1 and v2 addresses, group them incorrectly, etc. Get mon_host value only as a fallback. Fixes: https://tracker.ceph.com/issues/57317 Signed-off-by: Ilya Dryomov (cherry picked from commit de0ba80b37bf3df22bb2976871332344a4fb141e) --- diff --git a/qa/workunits/rbd/cli_generic.sh b/qa/workunits/rbd/cli_generic.sh index 2b3de518af63..41f721f61829 100755 --- a/qa/workunits/rbd/cli_generic.sh +++ b/qa/workunits/rbd/cli_generic.sh @@ -1407,6 +1407,52 @@ test_perf_image_iostat() { ceph osd pool rm rbd1 rbd1 --yes-i-really-really-mean-it } +test_mirror_pool_peer_bootstrap_create() { + echo "testing mirror pool peer bootstrap create..." + remove_images + + ceph osd pool create rbd1 8 + rbd pool init rbd1 + rbd mirror pool enable rbd1 image + ceph osd pool create rbd2 8 + rbd pool init rbd2 + rbd mirror pool enable rbd2 pool + + readarray -t MON_ADDRS < <(ceph mon dump | + sed -n 's/^[0-9]: \(.*\) mon\.[a-z]$/\1/p') + + # check that all monitors make it to the token even if only one + # valid monitor is specified + BAD_MON_ADDR="1.2.3.4:6789" + MON_HOST="${MON_ADDRS[0]},$BAD_MON_ADDR" + TOKEN="$(rbd mirror pool peer bootstrap create \ + --mon-host "$MON_HOST" rbd1 | base64 -d)" + TOKEN_FSID="$(jq -r '.fsid' <<< "$TOKEN")" + TOKEN_CLIENT_ID="$(jq -r '.client_id' <<< "$TOKEN")" + TOKEN_KEY="$(jq -r '.key' <<< "$TOKEN")" + TOKEN_MON_HOST="$(jq -r '.mon_host' <<< "$TOKEN")" + + test "$TOKEN_FSID" = "$(ceph fsid)" + test "$TOKEN_KEY" = "$(ceph auth get-key client.$TOKEN_CLIENT_ID)" + for addr in "${MON_ADDRS[@]}"; do + fgrep "$addr" <<< "$TOKEN_MON_HOST" + done + expect_fail fgrep "$BAD_MON_ADDR" <<< "$TOKEN_MON_HOST" + + # check that the token does not change, including across pools + test "$(rbd mirror pool peer bootstrap create \ + --mon-host "$MON_HOST" rbd1 | base64 -d)" = "$TOKEN" + test "$(rbd mirror pool peer bootstrap create \ + rbd1 | base64 -d)" = "$TOKEN" + test "$(rbd mirror pool peer bootstrap create \ + --mon-host "$MON_HOST" rbd2 | base64 -d)" = "$TOKEN" + test "$(rbd mirror pool peer bootstrap create \ + rbd2 | base64 -d)" = "$TOKEN" + + ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it + ceph osd pool rm rbd1 rbd1 --yes-i-really-really-mean-it +} + test_pool_image_args test_rename test_ls @@ -1430,5 +1476,6 @@ test_namespace test_trash_purge_schedule test_mirror_snapshot_schedule test_perf_image_iostat +test_mirror_pool_peer_bootstrap_create echo OK diff --git a/src/librbd/api/Mirror.cc b/src/librbd/api/Mirror.cc index 825d430bc05b..bbaa4eff7bb1 100644 --- a/src/librbd/api/Mirror.cc +++ b/src/librbd/api/Mirror.cc @@ -115,6 +115,26 @@ int remove_peer_config_key(librados::IoCtx& io_ctx, return 0; } +std::string get_mon_host(CephContext* cct) { + std::string mon_host; + if (auto mon_addrs = cct->get_mon_addrs(); + mon_addrs != nullptr && !mon_addrs->empty()) { + CachedStackStringStream css; + for (auto it = mon_addrs->begin(); it != mon_addrs->end(); ++it) { + if (it != mon_addrs->begin()) { + *css << ","; + } + *css << *it; + } + mon_host = css->str(); + } else { + ldout(cct, 20) << "falling back to mon_host in conf" << dendl; + mon_host = cct->_conf.get_val("mon_host"); + } + ldout(cct, 20) << "mon_host=" << mon_host << dendl; + return mon_host; +} + int create_bootstrap_user(CephContext* cct, librados::Rados& rados, std::string* peer_client_id, std::string* cephx_key) { ldout(cct, 20) << dendl; @@ -1298,8 +1318,7 @@ int Mirror::peer_bootstrap_create(librados::IoCtx& io_ctx, return r; } - std::string mon_host = cct->_conf.get_val("mon_host"); - ldout(cct, 20) << "mon_host=" << mon_host << dendl; + std::string mon_host = get_mon_host(cct); // format the token response bufferlist token_bl; @@ -1471,7 +1490,7 @@ int Mirror::peer_bootstrap_import(librados::IoCtx& io_ctx, return r; } - std::string local_mon_host = cct->_conf.get_val("mon_host"); + std::string local_mon_host = get_mon_host(cct); // create local cluster peer in remote cluster r = create_bootstrap_peer(cct, remote_io_ctx,