namespace {
int validate_pool(IoCtx &io_ctx, CephContext *cct) {
- if (!cct->_conf->rbd_validate_pool) {
+ if (!cct->_conf->get_val<bool>("rbd_validate_pool")) {
return 0;
}
CephContext *cct = ictx->cct;
ldout(cct, 20) << "children flatten " << ictx->name << dendl;
+ int r = ictx->state->refresh_if_required();
+ if (r < 0) {
+ return r;
+ }
+
RWLock::RLocker l(ictx->snap_lock);
snap_t snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace(), snap_name);
ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, snap_id);
map< pair<int64_t, string>, set<string> > image_info;
- int r = api::Image<>::list_children(ictx, parent_spec, &image_info);
+ r = api::Image<>::list_children(ictx, parent_spec, &image_info);
if (r < 0) {
return r;
}
return r;
}
+ if ((imctx->features & RBD_FEATURE_DEEP_FLATTEN) == 0 &&
+ !imctx->snaps.empty()) {
+ lderr(cct) << "snapshot in-use by " << pool << "/" << imctx->name
+ << dendl;
+ imctx->state->close();
+ return -EBUSY;
+ }
+
librbd::NoOpProgressContext prog_ctx;
r = imctx->operations->flatten(prog_ctx);
if (r < 0) {
return r;
}
- if ((imctx->features & RBD_FEATURE_DEEP_FLATTEN) == 0 &&
- !imctx->snaps.empty()) {
- imctx->parent_lock.get_read();
- ParentInfo parent_info = imctx->parent_md;
- imctx->parent_lock.put_read();
-
- r = cls_client::remove_child(&imctx->md_ctx, RBD_CHILDREN,
- parent_info.spec, imctx->id);
- if (r < 0 && r != -ENOENT) {
- lderr(cct) << "error removing child from children list" << dendl;
- imctx->state->close();
- return r;
- }
- }
-
r = imctx->state->close();
if (r < 0) {
lderr(cct) << "failed to close image: " << cpp_strerror(r) << dendl;
CephContext *cct = ictx->cct;
ldout(cct, 20) << "children list " << ictx->name << dendl;
+ int r = ictx->state->refresh_if_required();
+ if (r < 0) {
+ return r;
+ }
+
RWLock::RLocker l(ictx->snap_lock);
ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, ictx->snap_id);
map< pair<int64_t, string>, set<string> > image_info;
- int r = api::Image<>::list_children(ictx, parent_spec, &image_info);
+ r = api::Image<>::list_children(ictx, parent_spec, &image_info);
if (r < 0) {
return r;
}
uint64_t format;
if (opts.get(RBD_IMAGE_OPTION_FORMAT, &format) != 0)
- format = cct->_conf->rbd_default_format;
+ format = cct->_conf->get_val<int64_t>("rbd_default_format");
bool old_format = format == 1;
// make sure it doesn't already exist, in either format
uint64_t order = 0;
if (opts.get(RBD_IMAGE_OPTION_ORDER, &order) != 0 || order == 0) {
- order = cct->_conf->rbd_default_order;
+ order = cct->_conf->get_val<int64_t>("rbd_default_order");
}
r = image::CreateRequest<>::validate_order(cct, order);
if (r < 0) {
ImageCtx *ictx = new ImageCtx(srcname, "", "", io_ctx, false);
int r = ictx->state->open(false);
if (r < 0) {
- lderr(ictx->cct) << "error opening source image: " << cpp_strerror(r)
- << dendl;
+ lderr(cct) << "error opening source image: " << cpp_strerror(r) << dendl;
return r;
}
BOOST_SCOPE_EXIT((ictx)) {
int is_exclusive_lock_owner(ImageCtx *ictx, bool *is_owner)
{
+ CephContext *cct = ictx->cct;
+ ldout(cct, 20) << __func__ << ": ictx=" << ictx << dendl;
*is_owner = false;
RWLock::RLocker owner_locker(ictx->owner_lock);
- if (ictx->exclusive_lock == nullptr ||
- !ictx->exclusive_lock->is_lock_owner()) {
+ if (ictx->exclusive_lock == nullptr) {
return 0;
}
}
RWLock::RLocker l(ictx->owner_lock);
-
- if (ictx->exclusive_lock == nullptr ||
- !ictx->exclusive_lock->is_lock_owner()) {
+ if (ictx->exclusive_lock == nullptr) {
+ return -EINVAL;
+ } else if (!ictx->exclusive_lock->is_lock_owner()) {
lderr(cct) << "failed to acquire exclusive lock" << dendl;
- return -EROFS;
+ return ictx->exclusive_lock->get_unlocked_op_error();
}
return 0;
image_id = ictx->id;
ictx->owner_lock.get_read();
if (ictx->exclusive_lock != nullptr) {
- r = ictx->operations->prepare_image_update();
- if (r < 0 || (ictx->exclusive_lock != nullptr &&
- !ictx->exclusive_lock->is_lock_owner())) {
+ r = ictx->operations->prepare_image_update(false);
+ if (r < 0) {
lderr(cct) << "cannot obtain exclusive lock - not removing" << dendl;
ictx->owner_lock.put_read();
ictx->state->close();
CephContext *cct((CephContext *)io_ctx.cct());
ldout(cct, 20) << "trash_list " << &io_ctx << dendl;
- map<string, cls::rbd::TrashImageSpec> trash_entries;
- int r = cls_client::trash_list(&io_ctx, &trash_entries);
- if (r < 0) {
- if (r != -ENOENT) {
- lderr(cct) << "error listing rbd_trash entries: " << cpp_strerror(r)
+ bool more_entries;
+ uint32_t max_read = 1024;
+ std::string last_read = "";
+ do {
+ map<string, cls::rbd::TrashImageSpec> trash_entries;
+ int r = cls_client::trash_list(&io_ctx, last_read, max_read,
+ &trash_entries);
+ if (r < 0 && r != -ENOENT) {
+ lderr(cct) << "error listing rbd trash entries: " << cpp_strerror(r)
<< dendl;
- } else {
- r = 0;
+ return r;
+ } else if (r == -ENOENT) {
+ break;
}
- return r;
- }
- for (const auto &entry : trash_entries) {
- rbd_trash_image_source_t source =
- static_cast<rbd_trash_image_source_t>(entry.second.source);
- entries.push_back({entry.first, entry.second.name, source,
- entry.second.deletion_time.sec(),
- entry.second.deferment_end_time.sec()});
- }
+ if (trash_entries.empty()) {
+ break;
+ }
+
+ for (const auto &entry : trash_entries) {
+ rbd_trash_image_source_t source =
+ static_cast<rbd_trash_image_source_t>(entry.second.source);
+ entries.push_back({entry.first, entry.second.name, source,
+ entry.second.deletion_time.sec(),
+ entry.second.deferment_end_time.sec()});
+ }
+ last_read = trash_entries.rbegin()->first;
+ more_entries = (trash_entries.size() >= max_read);
+ } while (more_entries);
+
return 0;
}
return -EINVAL;
}
int r;
+ const uint32_t MAX_KEYS = 64;
map<string, bufferlist> pairs;
+ std::string last_key = "";
+ bool more_results = true;
- r = cls_client::metadata_list(&src->md_ctx, src->header_oid, "", 0, &pairs);
- if (r < 0 && r != -EOPNOTSUPP && r != -EIO) {
- lderr(cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl;
- return r;
- } else if (r == 0 && !pairs.empty()) {
- r = cls_client::metadata_set(&dest->md_ctx, dest->header_oid, pairs);
- if (r < 0) {
- lderr(cct) << "couldn't set metadata: " << cpp_strerror(r) << dendl;
+ while (more_results) {
+ r = cls_client::metadata_list(&src->md_ctx, src->header_oid, last_key, 0, &pairs);
+ if (r < 0 && r != -EOPNOTSUPP && r != -EIO) {
+ lderr(cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl;
return r;
+ } else if (r == 0 && !pairs.empty()) {
+ r = cls_client::metadata_set(&dest->md_ctx, dest->header_oid, pairs);
+ if (r < 0) {
+ lderr(cct) << "couldn't set metadata: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+
+ last_key = pairs.rbegin()->first;
}
+
+ more_results = (pairs.size() == MAX_KEYS);
+ pairs.clear();
}
ZTracer::Trace trace;
- if (cct->_conf->rbd_blkin_trace_all) {
+ if (src->blkin_trace_all) {
trace.init("copy", &src->trace_endpoint);
}
uint64_t left = mylen;
ZTracer::Trace trace;
- if (ictx->cct->_conf->rbd_blkin_trace_all) {
+ if (ictx->blkin_trace_all) {
trace.init("read_iterate", &ictx->trace_endpoint);
}
}
RWLock::RLocker owner_locker(ictx->owner_lock);
- RWLock::WLocker md_locker(ictx->md_lock);
r = ictx->invalidate_cache(false);
ictx->perfcounter->inc(l_librbd_invalidate_cache);
return r;