summaryrefslogtreecommitdiffstats
path: root/src/librbd
diff options
context:
space:
mode:
Diffstat (limited to 'src/librbd')
-rw-r--r--src/librbd/ObjectMap.cc26
-rw-r--r--src/librbd/ObjectMap.h1
-rw-r--r--src/librbd/migration/HttpClient.cc119
-rw-r--r--src/librbd/migration/HttpClient.h11
-rw-r--r--src/librbd/operation/FlattenRequest.cc9
5 files changed, 76 insertions, 90 deletions
diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc
index 65e3fc4a4c2..160bb4dcf9e 100644
--- a/src/librbd/ObjectMap.cc
+++ b/src/librbd/ObjectMap.cc
@@ -107,32 +107,6 @@ bool ObjectMap<I>::object_may_exist(uint64_t object_no) const
}
template <typename I>
-bool ObjectMap<I>::object_may_not_exist(uint64_t object_no) const
-{
- ceph_assert(ceph_mutex_is_locked(m_image_ctx.image_lock));
-
- // Fall back to default logic if object map is disabled or invalid
- if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
- m_image_ctx.image_lock)) {
- return true;
- }
-
- bool flags_set;
- int r = m_image_ctx.test_flags(m_image_ctx.snap_id,
- RBD_FLAG_OBJECT_MAP_INVALID,
- m_image_ctx.image_lock, &flags_set);
- if (r < 0 || flags_set) {
- return true;
- }
-
- uint8_t state = (*this)[object_no];
- bool nonexistent = (state != OBJECT_EXISTS && state != OBJECT_EXISTS_CLEAN);
- ldout(m_image_ctx.cct, 20) << "object_no=" << object_no << " r="
- << nonexistent << dendl;
- return nonexistent;
-}
-
-template <typename I>
bool ObjectMap<I>::update_required(const ceph::BitVector<2>::Iterator& it,
uint8_t new_state) {
ceph_assert(ceph_mutex_is_locked(m_lock));
diff --git a/src/librbd/ObjectMap.h b/src/librbd/ObjectMap.h
index 35ea4cb88f9..5e7fcbbe9dd 100644
--- a/src/librbd/ObjectMap.h
+++ b/src/librbd/ObjectMap.h
@@ -65,7 +65,6 @@ public:
void close(Context *on_finish);
bool set_object_map(ceph::BitVector<2> &target_object_map);
bool object_may_exist(uint64_t object_no) const;
- bool object_may_not_exist(uint64_t object_no) const;
void aio_save(Context *on_finish);
void aio_resize(uint64_t new_size, uint8_t default_object_state,
diff --git a/src/librbd/migration/HttpClient.cc b/src/librbd/migration/HttpClient.cc
index 6a504d3a9ac..d212981a917 100644
--- a/src/librbd/migration/HttpClient.cc
+++ b/src/librbd/migration/HttpClient.cc
@@ -63,14 +63,13 @@ public:
m_on_shutdown = on_finish;
auto current_state = m_state;
+ m_state = STATE_SHUTTING_DOWN;
+
if (current_state == STATE_UNINITIALIZED) {
// never initialized or resolve/connect failed
on_finish->complete(0);
return;
- }
-
- m_state = STATE_SHUTTING_DOWN;
- if (current_state != STATE_READY) {
+ } else if (current_state != STATE_READY) {
// delay shutdown until current state transition completes
return;
}
@@ -118,7 +117,7 @@ public:
ceph_assert(m_http_client->m_strand.running_in_this_thread());
auto cct = m_http_client->m_cct;
- ldout(cct, 20) << "work=" << work.get() << ", r=" << -ec.value() << dendl;
+ ldout(cct, 20) << "work=" << work.get() << ", ec=" << ec.what() << dendl;
ceph_assert(m_in_flight_requests > 0);
--m_in_flight_requests;
@@ -187,13 +186,14 @@ protected:
virtual void connect(boost::asio::ip::tcp::resolver::results_type results,
Context* on_finish) = 0;
virtual void disconnect(Context* on_finish) = 0;
+ virtual void reset_stream() = 0;
void close_socket() {
auto cct = m_http_client->m_cct;
ldout(cct, 15) << dendl;
boost::system::error_code ec;
- boost::beast::get_lowest_layer(derived().stream()).socket().close(ec);
+ derived().stream().lowest_layer().close(ec);
}
private:
@@ -229,7 +229,6 @@ private:
auto cct = m_http_client->m_cct;
ldout(cct, 15) << dendl;
- shutdown_socket();
m_resolver.async_resolve(
m_http_client->m_url_spec.host, m_http_client->m_url_spec.port,
[this, on_finish](boost::system::error_code ec, auto results) {
@@ -358,8 +357,7 @@ private:
}
int shutdown_socket() {
- if (!boost::beast::get_lowest_layer(
- derived().stream()).socket().is_open()) {
+ if (!derived().stream().lowest_layer().is_open()) {
return 0;
}
@@ -367,7 +365,7 @@ private:
ldout(cct, 15) << dendl;
boost::system::error_code ec;
- boost::beast::get_lowest_layer(derived().stream()).socket().shutdown(
+ derived().stream().lowest_layer().shutdown(
boost::asio::ip::tcp::socket::shutdown_both, ec);
if (ec && ec != boost::beast::errc::not_connected) {
@@ -414,7 +412,7 @@ private:
void handle_receive(boost::system::error_code ec,
std::shared_ptr<Work>&& work) {
auto cct = m_http_client->m_cct;
- ldout(cct, 15) << "work=" << work.get() << ", r=" << -ec.value() << dendl;
+ ldout(cct, 15) << "work=" << work.get() << ", ec=" << ec.what() << dendl;
ceph_assert(m_in_flight_requests > 0);
--m_in_flight_requests;
@@ -445,10 +443,10 @@ private:
ldout(cct, 5) << "remote peer stream closed, retrying request" << dendl;
m_receive_queue.push_front(work);
} else if (ec == boost::beast::error::timeout) {
- lderr(cct) << "timed-out while issuing request" << dendl;
+ lderr(cct) << "timed-out while receiving response" << dendl;
work->complete(-ETIMEDOUT, {});
} else {
- lderr(cct) << "failed to issue request: " << ec.message() << dendl;
+ lderr(cct) << "failed to receive response: " << ec.message() << dendl;
work->complete(-ec.value(), {});
}
@@ -473,7 +471,7 @@ private:
r = -EACCES;
} else if (boost::beast::http::to_status_class(result) !=
boost::beast::http::status_class::successful) {
- lderr(cct) << "failed to retrieve size: HTTP " << result << dendl;
+ lderr(cct) << "failed to retrieve resource: HTTP " << result << dendl;
r = -EIO;
}
@@ -501,7 +499,10 @@ private:
<< "next_state=" << next_state << ", "
<< "r=" << r << dendl;
- m_state = next_state;
+ if (current_state != STATE_SHUTTING_DOWN) {
+ m_state = next_state;
+ }
+
if (current_state == STATE_CONNECTING) {
if (next_state == STATE_UNINITIALIZED) {
shutdown_socket();
@@ -512,14 +513,17 @@ private:
return;
}
} else if (current_state == STATE_SHUTTING_DOWN) {
+ ceph_assert(m_on_shutdown != nullptr);
if (next_state == STATE_READY) {
// shut down requested while connecting/resetting
disconnect(new LambdaContext([this](int r) { handle_shut_down(r); }));
return;
} else if (next_state == STATE_UNINITIALIZED ||
- next_state == STATE_SHUTDOWN ||
next_state == STATE_RESET_CONNECTING) {
- ceph_assert(m_on_shutdown != nullptr);
+ shutdown_socket();
+ m_on_shutdown->complete(r);
+ return;
+ } else if (next_state == STATE_SHUTDOWN) {
m_on_shutdown->complete(r);
return;
}
@@ -528,6 +532,7 @@ private:
ceph_assert(next_state == STATE_RESET_CONNECTING);
ceph_assert(on_finish == nullptr);
shutdown_socket();
+ reset_stream();
resolve_host(nullptr);
return;
} else if (current_state == STATE_RESET_CONNECTING) {
@@ -589,7 +594,7 @@ public:
this->close_socket();
}
- inline boost::beast::tcp_stream&
+ inline boost::asio::ip::tcp::socket&
stream() {
return m_stream;
}
@@ -601,20 +606,25 @@ protected:
auto cct = http_client->m_cct;
ldout(cct, 15) << dendl;
- m_stream.async_connect(
- results,
- [on_finish](boost::system::error_code ec, const auto& endpoint) {
- on_finish->complete(-ec.value());
- });
+ ceph_assert(!m_stream.is_open());
+ boost::asio::async_connect(m_stream,
+ results,
+ [on_finish](boost::system::error_code ec,
+ const auto& endpoint) {
+ on_finish->complete(-ec.value());
+ });
}
void disconnect(Context* on_finish) override {
on_finish->complete(0);
}
-private:
- boost::beast::tcp_stream m_stream;
+ void reset_stream() override {
+ // no-op -- tcp_stream object can be reused after shut down
+ }
+private:
+ boost::asio::ip::tcp::socket m_stream;
};
#undef dout_prefix
@@ -633,7 +643,7 @@ public:
this->close_socket();
}
- inline boost::beast::ssl_stream<boost::beast::tcp_stream>&
+ inline boost::asio::ssl::stream<boost::asio::ip::tcp::socket>&
stream() {
return m_stream;
}
@@ -645,7 +655,9 @@ protected:
auto cct = http_client->m_cct;
ldout(cct, 15) << dendl;
- boost::beast::get_lowest_layer(m_stream).async_connect(
+ ceph_assert(!m_stream.lowest_layer().is_open());
+ async_connect(
+ m_stream.lowest_layer(),
results,
[this, on_finish](boost::system::error_code ec, const auto& endpoint) {
handle_connect(-ec.value(), on_finish);
@@ -657,19 +669,25 @@ protected:
auto cct = http_client->m_cct;
ldout(cct, 15) << dendl;
- if (!m_ssl_enabled) {
- on_finish->complete(0);
- return;
- }
-
m_stream.async_shutdown(
- asio::util::get_callback_adapter([this, on_finish](int r) {
- shutdown(r, on_finish); }));
+ [this, on_finish](boost::system::error_code ec) {
+ handle_disconnect(ec, on_finish);
+ });
+ }
+
+ void reset_stream() override {
+ auto http_client = this->m_http_client;
+ auto cct = http_client->m_cct;
+ ldout(cct, 15) << dendl;
+
+ // ssl_stream object can't be reused after shut down -- move-in
+ // a freshly constructed instance
+ m_stream = boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(
+ http_client->m_strand, http_client->m_ssl_context);
}
private:
- boost::beast::ssl_stream<boost::beast::tcp_stream> m_stream;
- bool m_ssl_enabled = false;
+ boost::asio::ssl::stream<boost::asio::ip::tcp::socket> m_stream;
void handle_connect(int r, Context* on_finish) {
auto http_client = this->m_http_client;
@@ -728,33 +746,38 @@ private:
// Perform the SSL/TLS handshake
m_stream.async_handshake(
boost::asio::ssl::stream_base::client,
- asio::util::get_callback_adapter(
- [this, on_finish](int r) { handle_handshake(r, on_finish); }));
+ [this, on_finish](boost::system::error_code ec) {
+ handle_handshake(ec, on_finish);
+ });
}
- void handle_handshake(int r, Context* on_finish) {
+ void handle_handshake(boost::system::error_code ec, Context* on_finish) {
auto http_client = this->m_http_client;
auto cct = http_client->m_cct;
- ldout(cct, 15) << "r=" << r << dendl;
+ ldout(cct, 15) << "ec=" << ec.what() << dendl;
- if (r < 0) {
- lderr(cct) << "failed to complete handshake: " << cpp_strerror(r)
+ if (ec) {
+ lderr(cct) << "failed to complete SSL handshake: " << ec.message()
<< dendl;
- disconnect(new LambdaContext([r, on_finish](int) {
- on_finish->complete(r); }));
+ on_finish->complete(-ec.value());
return;
}
- m_ssl_enabled = true;
on_finish->complete(0);
}
- void shutdown(int r, Context* on_finish) {
+ void handle_disconnect(boost::system::error_code ec, Context* on_finish) {
auto http_client = this->m_http_client;
auto cct = http_client->m_cct;
- ldout(cct, 15) << "r=" << r << dendl;
+ ldout(cct, 15) << "ec=" << ec.what() << dendl;
- on_finish->complete(r);
+ if (ec && ec != boost::asio::ssl::error::stream_truncated) {
+ lderr(cct) << "failed to shut down SSL: " << ec.message() << dendl;
+ on_finish->complete(-ec.value());
+ return;
+ }
+
+ on_finish->complete(0);
}
};
diff --git a/src/librbd/migration/HttpClient.h b/src/librbd/migration/HttpClient.h
index 3997e6159e7..5844f918693 100644
--- a/src/librbd/migration/HttpClient.h
+++ b/src/librbd/migration/HttpClient.h
@@ -13,13 +13,12 @@
#include <boost/asio/strand.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/context.hpp>
+#include <boost/asio/ssl/stream.hpp>
#include <boost/beast/version.hpp>
-#include <boost/beast/core/tcp_stream.hpp>
#include <boost/beast/http/empty_body.hpp>
#include <boost/beast/http/message.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/beast/http/write.hpp>
-#include <boost/beast/ssl/ssl_stream.hpp>
#include <functional>
#include <memory>
#include <string>
@@ -97,7 +96,7 @@ public:
completion(r, std::move(response));
}
- void operator()(boost::beast::tcp_stream& stream) override {
+ void operator()(boost::asio::ip::tcp::socket& stream) override {
preprocess_request();
boost::beast::http::async_write(
@@ -110,7 +109,7 @@ public:
}
void operator()(
- boost::beast::ssl_stream<boost::beast::tcp_stream>& stream) override {
+ boost::asio::ssl::stream<boost::asio::ip::tcp::socket>& stream) override {
preprocess_request();
boost::beast::http::async_write(
@@ -152,9 +151,9 @@ private:
virtual bool need_eof() const = 0;
virtual bool header_only() const = 0;
virtual void complete(int r, Response&&) = 0;
- virtual void operator()(boost::beast::tcp_stream& stream) = 0;
+ virtual void operator()(boost::asio::ip::tcp::socket& stream) = 0;
virtual void operator()(
- boost::beast::ssl_stream<boost::beast::tcp_stream>& stream) = 0;
+ boost::asio::ssl::stream<boost::asio::ip::tcp::socket>& stream) = 0;
};
template <typename D> struct HttpSession;
diff --git a/src/librbd/operation/FlattenRequest.cc b/src/librbd/operation/FlattenRequest.cc
index 7bc34681924..8034637e8e6 100644
--- a/src/librbd/operation/FlattenRequest.cc
+++ b/src/librbd/operation/FlattenRequest.cc
@@ -49,15 +49,6 @@ public:
return -ERESTART;
}
- {
- std::shared_lock image_lock{image_ctx.image_lock};
- if (image_ctx.object_map != nullptr &&
- !image_ctx.object_map->object_may_not_exist(m_object_no)) {
- // can skip because the object already exists
- return 1;
- }
- }
-
if (!io::util::trigger_copyup(
&image_ctx, m_object_no, m_io_context, this)) {
// stop early if the parent went away - it just means