cerr << " --end-date=<date>\n";
cerr << " --bucket-id=<bucket-id>\n";
cerr << " --fix besides checking bucket index, will also fix it\n";
+ cerr << " --check-objects bucket check: rebuilds bucket index according to\n";
+ cerr << " actual objects state\n";
cerr << " --format=<format> specify output format for certain operations: xml,\n";
cerr << " json\n";
cerr << " --purge-data when specified, user removal will also purge all the\n";
return ret;
}
+static bool bucket_object_check_filter(const string& name)
+{
+ string ns;
+ string obj = name;
+ return rgw_obj::translate_raw_obj_to_obj_in_ns(obj, ns);
+}
+
int main(int argc, char **argv)
{
vector<const char*> args;
int max_buckets = -1;
map<string, bool> categories;
string caps;
+ int check_objects = false;
std::string val;
std::ostringstream errs;
// do nothing
} else if (ceph_argparse_binary_flag(args, i, &fix, NULL, "--fix", (char*)NULL)) {
// do nothing
+ } else if (ceph_argparse_binary_flag(args, i, &check_objects, NULL, "--check-objects", (char*)NULL)) {
+ // do nothing
} else if (ceph_argparse_witharg(args, i, &val, "--caps", (char*)NULL)) {
caps = val;
} else {
map<RGWObjCategory, RGWBucketStats> existing_stats;
map<RGWObjCategory, RGWBucketStats> calculated_stats;
+ if (check_objects) {
+ if (!fix) {
+ cerr << "--check-objects flag requires --fix" << std::endl;
+ return 1;
+ }
+#define BUCKET_TAG_TIMEOUT 30
+ cout << "Checking objects, decreasing bucket 2-phase commit timeout.\n"
+ "** Note that timeout will reset only when operation completes successfully **" << std::endl;
+
+ store->cls_obj_set_bucket_tag_timeout(bucket, BUCKET_TAG_TIMEOUT);
+
+ string prefix;
+ string marker;
+ bool is_truncated = true;
+
+ while (is_truncated) {
+ map<string, RGWObjEnt> result;
+ string ns;
+ int r = store->cls_bucket_list(bucket, marker, prefix, 1000,
+ result, &is_truncated, &marker,
+ bucket_object_check_filter);
+
+ if (r < 0 && r != -ENOENT) {
+ cerr << "ERROR: failed operation r=" << r << std::endl;
+ }
+
+ if (r == -ENOENT)
+ break;
+
+ map<string, RGWObjEnt>::iterator iter;
+ for (iter = result.begin(); iter != result.end(); ++iter) {
+ cout << iter->first << std::endl;
+ }
+
+ }
+
+ store->cls_obj_set_bucket_tag_timeout(bucket, 0);
+
+ }
int r = store->bucket_check_index(bucket, &existing_stats, &calculated_stats);
if (r < 0) {
cerr << "failed to check index err=" << cpp_strerror(-r) << std::endl;
return r;
}
}
+
}
if (opt_cmd == OPT_BUCKET_RM) {
return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, 0, ent, RGW_OBJ_CATEGORY_NONE, NULL);
}
+int RGWRados::cls_obj_set_bucket_tag_timeout(rgw_bucket& bucket, uint64_t timeout)
+{
+ librados::IoCtx io_ctx;
+ string oid;
+
+ int r = open_bucket(bucket, io_ctx, oid);
+ if (r < 0)
+ return r;
+
+ ObjectWriteOperation o;
+ cls_rgw_bucket_set_tag_timeout(o, timeout);
+
+ r = io_ctx.operate(oid, &o);
+
+ return r;
+}
+
int RGWRados::cls_bucket_list(rgw_bucket& bucket, string start, string prefix,
uint32_t num, map<string, RGWObjEnt>& m,
- bool *is_truncated, string *last_entry)
+ bool *is_truncated, string *last_entry,
+ bool (*force_check_filter)(const string& name))
{
ldout(cct, 10) << "cls_bucket_list " << bucket << " start " << start << " num " << num << dendl;
continue;
}
- if (!dirent.exists || !dirent.pending_map.empty()) {
+ bool force_check = force_check_filter && force_check_filter(dirent.name);
+
+ if (!dirent.exists || !dirent.pending_map.empty() || force_check) {
/* there are uncommitted ops. We need to check the current state,
* and if the tags are old we need to do cleanup as well. */
librados::IoCtx sub_ctx;
int cls_obj_complete_add(rgw_bucket& bucket, string& tag, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category, list<string> *remove_objs);
int cls_obj_complete_del(rgw_bucket& bucket, string& tag, uint64_t epoch, string& name);
int cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name);
+ int cls_obj_set_bucket_tag_timeout(rgw_bucket& bucket, uint64_t timeout);
int cls_bucket_list(rgw_bucket& bucket, string start, string prefix, uint32_t num,
map<string, RGWObjEnt>& m, bool *is_truncated,
- string *last_entry = NULL);
+ string *last_entry, bool (*force_check_filter)(const string& name) = NULL);
int cls_bucket_head(rgw_bucket& bucket, struct rgw_bucket_dir_header& header);
int prepare_update_index(RGWObjState *state, rgw_bucket& bucket,
rgw_obj& oid, string& tag);