librbd: image create validates that pool supports overwrites

Fixes: http://tracker.ceph.com/issues/19081
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2017-03-15 14:49:13 -04:00
parent d4e27c48aa
commit a16beba784
2 changed files with 80 additions and 3 deletions

View File

@ -281,6 +281,7 @@ void CreateRequest<I>::validate_pool() {
librados::ObjectReadOperation op;
op.stat(NULL, NULL, NULL);
m_outbl.clear();
int r = m_ioctx.aio_operate(RBD_DIRECTORY, comp, &op, &m_outbl);
assert(r == 0);
comp->release();
@ -291,7 +292,7 @@ void CreateRequest<I>::handle_validate_pool(int r) {
ldout(m_cct, 20) << "r=" << r << dendl;
if (r == 0) {
create_id_object();
validate_overwrite();
return;
} else if ((r < 0) && (r != -ENOENT)) {
lderr(m_cct) << "failed to stat RBD directory: " << cpp_strerror(r)
@ -328,6 +329,73 @@ void CreateRequest<I>::handle_validate_pool(int r) {
<< ": " << cpp_strerror(r) << dendl;
}
validate_overwrite();
}
template <typename I>
void CreateRequest<I>::validate_overwrite() {
ldout(m_cct, 20) << dendl;
m_data_io_ctx = m_ioctx;
if (m_data_pool_id != -1) {
librados::Rados rados(m_ioctx);
int r = rados.ioctx_create2(m_data_pool_id, m_data_io_ctx);
if (r < 0) {
lderr(m_cct) << "data pool " << m_data_pool << " does not exist" << dendl;
complete(r);
return;
}
}
using klass = CreateRequest<I>;
librados::AioCompletion *comp =
create_rados_callback<klass, &klass::handle_validate_overwrite>(this);
librados::ObjectReadOperation op;
op.read(0, 0, nullptr, nullptr);
m_outbl.clear();
int r = m_data_io_ctx.aio_operate(RBD_INFO, comp, &op, &m_outbl);
assert(r == 0);
comp->release();
}
template <typename I>
void CreateRequest<I>::handle_validate_overwrite(int r) {
ldout(m_cct, 20) << "r=" << r << dendl;
bufferlist bl;
bl.append("overwrite validated");
if (r == 0 && m_outbl.contents_equal(bl)) {
create_id_object();
return;
} else if ((r < 0) && (r != -ENOENT)) {
lderr(m_cct) << "failed to read RBD info: " << cpp_strerror(r) << dendl;
complete(r);
return;
}
// validate the pool supports overwrites. We cannot use rbd_directory
// since the v1 images store the directory as tmap data within the object.
ldout(m_cct, 10) << "validating overwrite support" << dendl;
bufferlist initial_bl;
initial_bl.append("validate");
r = m_data_io_ctx.write(RBD_INFO, initial_bl, initial_bl.length(), 0);
if (r >= 0) {
r = m_data_io_ctx.write(RBD_INFO, bl, bl.length(), 0);
}
if (r == -EOPNOTSUPP) {
lderr(m_cct) << "pool missing required overwrite support" << dendl;
complete(-EINVAL);
return;
} else if (r < 0) {
lderr(m_cct) << "failed to validate overwrite support: " << cpp_strerror(r)
<< dendl;
complete(r);
return;
}
create_id_object();
}
@ -406,6 +474,8 @@ void CreateRequest<I>::negotiate_features() {
using klass = CreateRequest<I>;
librados::AioCompletion *comp =
create_rados_callback<klass, &klass::handle_negotiate_features>(this);
m_outbl.clear();
int r = m_ioctx.aio_operate(RBD_DIRECTORY, comp, &op, &m_outbl);
assert(r == 0);
comp->release();

View File

@ -54,8 +54,11 @@ private:
* <start> . . . . > . . . . .
* | .
* v .
* VALIDATE POOL v (pool validation
* | . disabled)
* VALIDATE POOL v (pool validation
* | . disabled)
* v .
* VALIDATE OVERWRITE .
* | .
* v .
* (error: bottom up) CREATE ID OBJECT. . < . . . . .
* _______<_______ |
@ -99,6 +102,7 @@ private:
ContextWQ *op_work_queue, Context *on_finish);
IoCtx &m_ioctx;
IoCtx m_data_io_ctx;
std::string m_image_name;
std::string m_image_id;
uint64_t m_size;
@ -132,6 +136,9 @@ private:
void validate_pool();
void handle_validate_pool(int r);
void validate_overwrite();
void handle_validate_overwrite(int r);
void create_id_object();
void handle_create_id_object(int r);