This method will be called on the bucket index shard.
Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
return write_bucket_header(hctx, &header);
}
+static int rgw_guard_bucket_resharding(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+ cls_rgw_guard_bucket_resharding_op op;
+
+ bufferlist::iterator in_iter = in->begin();
+ try {
+ ::decode(op, in_iter);
+ } catch (buffer::error& err) {
+ CLS_LOG(1, "ERROR: cls_rgw_clear_bucket_resharding: failed to decode entry\n");
+ return -EINVAL;
+ }
+
+ struct rgw_bucket_dir_header header;
+ int rc = read_bucket_header(hctx, &header);
+ if (rc < 0) {
+ CLS_LOG(1, "ERROR: %s(): failed to read header\n", __func__);
+ return rc;
+ }
+
+ if (header.resharding()) {
+ return op.ret_err;
+ }
+
+ return 0;
+}
+
static int rgw_get_bucket_resharding(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
{
cls_rgw_get_bucket_resharding_op op;
cls_method_handle_t h_rgw_reshard_remove;
cls_method_handle_t h_rgw_set_bucket_resharding;
cls_method_handle_t h_rgw_clear_bucket_resharding;
+ cls_method_handle_t h_rgw_guard_bucket_resharding;
cls_method_handle_t h_rgw_get_bucket_resharding;
rgw_set_bucket_resharding, &h_rgw_set_bucket_resharding);
cls_register_cxx_method(h_class, "clear_bucket_resharding", CLS_METHOD_RD | CLS_METHOD_WR,
rgw_clear_bucket_resharding, &h_rgw_clear_bucket_resharding);
+ cls_register_cxx_method(h_class, "guard_bucket_resharding", CLS_METHOD_RD ,
+ rgw_guard_bucket_resharding, &h_rgw_guard_bucket_resharding);
cls_register_cxx_method(h_class, "get_bucket_resharding", CLS_METHOD_RD ,
rgw_get_bucket_resharding, &h_rgw_get_bucket_resharding);
return 0;
}
+
+void cls_rgw_guard_bucket_resharding(librados::ObjectWriteOperation& op, int ret_err)
+{
+ bufferlist in, out;
+ struct cls_rgw_guard_bucket_resharding_op call;
+ call.ret_err = ret_err;
+ ::encode(call, in);
+ op.exec("rgw", "guard_bucket_resharding", in);
+}
int cls_rgw_set_bucket_resharding(librados::IoCtx& io_ctx, const string& oid,
const cls_rgw_bucket_instance_entry& entry);
int cls_rgw_clear_bucket_resharding(librados::IoCtx& io_ctx, const string& oid);
+void cls_rgw_guard_bucket_resharding(librados::ObjectWriteOperation& op, int ret_err);
int cls_rgw_get_bucket_resharding(librados::IoCtx& io_ctx, const string& oid,
cls_rgw_bucket_instance_entry *entry);
{
}
+void cls_rgw_guard_bucket_resharding_op::generate_test_instances(
+ list<cls_rgw_guard_bucket_resharding_op*>& ls)
+{
+ ls.push_back(new cls_rgw_guard_bucket_resharding_op);
+ ls.push_back(new cls_rgw_guard_bucket_resharding_op);
+}
+
+void cls_rgw_guard_bucket_resharding_op::dump(Formatter *f) const
+{
+ ::encode_json("ret_err", ret_err, f);
+}
+
+
void cls_rgw_get_bucket_resharding_op::generate_test_instances(
list<cls_rgw_get_bucket_resharding_op*>& ls)
{
};
WRITE_CLASS_ENCODER(cls_rgw_clear_bucket_resharding_op)
+struct cls_rgw_guard_bucket_resharding_op {
+ int ret_err{0};
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ ::encode(ret_err, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::iterator& bl) {
+ DECODE_START(1, bl);
+ ::decode(ret_err, bl);
+ DECODE_FINISH(bl);
+ }
+
+ static void generate_test_instances(list<cls_rgw_guard_bucket_resharding_op*>& o);
+ void dump(Formatter *f) const;
+};
+WRITE_CLASS_ENCODER(cls_rgw_guard_bucket_resharding_op)
+
struct cls_rgw_get_bucket_resharding_op {
void encode(bufferlist& bl) const {
#define ERR_MALFORMED_DOC 2204
#define ERR_NO_ROLE_FOUND 2205
#define ERR_DELETE_CONFLICT 2206
+#define ERR_BUSY_RESHARDING 2300
#ifndef UINT32_MAX
#define UINT32_MAX (0xffffffffu)
RGWRados *store = target->get_store();
BucketShard *bs;
- /* handle on going bucket resharding */
- BucketIndexLockGuard guard(store->ctx(), store, target->get_bucket().bucket_id, target->get_bucket().oid,
- store->reshard_pool_ctx);
- int ret = store->reshard->block_while_resharding(target->get_bucket().oid, guard);
- if (ret < 0) {
- return ret;
- }
-
ret = get_bucket_shard(&bs);
if (ret < 0) {
ldout(store->ctx(), 5) << "failed to get BucketShard object: ret=" << ret << dendl;
ObjectWriteOperation o;
cls_rgw_obj_key key(obj.key.get_index_key_name(), obj.key.instance);
+ cls_rgw_guard_resharding(o, -ERR_BUSY_RESHARDING);
cls_rgw_bucket_prepare_op(o, op, tag, key, obj.key.get_loc(), get_zone().log_data, bilog_flags, zones_trace);
return bs.index_ctx.operate(bs.bucket_obj, &o);
}
ver.pool = pool;
ver.epoch = epoch;
cls_rgw_obj_key key(ent.key.name, ent.key.instance);
+ cls_rgw_guard_resharding(o, -ERR_BUSY_RESHARDING);
cls_rgw_bucket_complete_op(o, op, tag, ver, key, dir_meta, pro,
get_zone().log_data, bilog_flags, zones_trace);
const int default_reshard_sleep_duration = 30;
int RGWReshard::block_while_resharding(const string& bucket_instance_oid,
- BucketIndexLockGuard& guard)
+ BucketIndexLockGuard& guard)
{
int ret = 0;
cls_rgw_bucket_instance_entry entry;
return ret;
}
- if (entry.resharding) {
- /* clear resharding uses the same lock */
- ret = guard.unlock();
- if (ret < 0) {
- return ret;
- }
- sleep(default_reshard_sleep_duration);
- } else {
+ ret = guard.unlock();
+ if (ret < 0) {
+ return ret;
+ }
+ if (!entry.resharding) {
return 0;
}
+ /* needed to unlock as clear resharding uses the same lock */
+ sleep(default_reshard_sleep_duration);
}
ldout(cct, 0) << "RGWReshard::" << __func__ << " ERROR: bucket is still resharding, please retry" << dendl;
return -EAGAIN;