mirror of
https://github.com/ceph/ceph
synced 2025-02-10 04:19:56 +00:00
radosgw-admin bucket check [--fix] --bucket=<bucket> The command will dump the existing bucket header stats, and the calculated bucket header stats. If --fix is provided the bucket stats will be overwritten by the recalculated stats. Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
267 lines
6.3 KiB
C++
267 lines
6.3 KiB
C++
#include <errno.h>
|
|
|
|
#include "include/types.h"
|
|
#include "cls/rgw/cls_rgw_ops.h"
|
|
#include "include/rados/librados.hpp"
|
|
|
|
using namespace librados;
|
|
|
|
void cls_rgw_bucket_init(ObjectWriteOperation& o)
|
|
{
|
|
bufferlist in;
|
|
o.exec("rgw", "bucket_init_index", in);
|
|
}
|
|
|
|
void cls_rgw_bucket_set_tag_timeout(ObjectWriteOperation& o, uint64_t tag_timeout)
|
|
{
|
|
bufferlist in;
|
|
struct rgw_cls_tag_timeout_op call;
|
|
call.tag_timeout = tag_timeout;
|
|
::encode(call, in);
|
|
o.exec("rgw", "bucket_set_tag_timeout", in);
|
|
}
|
|
|
|
void cls_rgw_bucket_prepare_op(ObjectWriteOperation& o, uint8_t op, string& tag,
|
|
string& name, string& locator)
|
|
{
|
|
struct rgw_cls_obj_prepare_op call;
|
|
call.op = op;
|
|
call.tag = tag;
|
|
call.name = name;
|
|
call.locator = locator;
|
|
bufferlist in;
|
|
::encode(call, in);
|
|
o.exec("rgw", "bucket_prepare_op", in);
|
|
}
|
|
|
|
void cls_rgw_bucket_complete_op(ObjectWriteOperation& o, uint8_t op, string& tag,
|
|
uint64_t epoch, string& name, rgw_bucket_dir_entry_meta& dir_meta)
|
|
{
|
|
|
|
bufferlist in;
|
|
struct rgw_cls_obj_complete_op call;
|
|
call.op = op;
|
|
call.tag = tag;
|
|
call.name = name;
|
|
call.epoch = epoch;
|
|
call.meta = dir_meta;
|
|
::encode(call, in);
|
|
o.exec("rgw", "bucket_complete_op", in);
|
|
}
|
|
|
|
|
|
int cls_rgw_list_op(IoCtx& io_ctx, string& oid, string& start_obj,
|
|
string& filter_prefix, uint32_t num_entries,
|
|
rgw_bucket_dir *dir, bool *is_truncated)
|
|
{
|
|
bufferlist in, out;
|
|
struct rgw_cls_list_op call;
|
|
call.start_obj = start_obj;
|
|
call.filter_prefix = filter_prefix;
|
|
call.num_entries = num_entries;
|
|
::encode(call, in);
|
|
int r = io_ctx.exec(oid, "rgw", "bucket_list", in, out);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
struct rgw_cls_list_ret ret;
|
|
try {
|
|
bufferlist::iterator iter = out.begin();
|
|
::decode(ret, iter);
|
|
} catch (buffer::error& err) {
|
|
return -EIO;
|
|
}
|
|
|
|
if (dir)
|
|
*dir = ret.dir;
|
|
if (is_truncated)
|
|
*is_truncated = ret.is_truncated;
|
|
|
|
return r;
|
|
}
|
|
|
|
int cls_rgw_bucket_check_index_op(IoCtx& io_ctx, string& oid,
|
|
rgw_bucket_dir_header *existing_header,
|
|
rgw_bucket_dir_header *calculated_header)
|
|
{
|
|
bufferlist in, out;
|
|
int r = io_ctx.exec(oid, "rgw", "bucket_check_index", in, out);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
struct rgw_cls_check_index_ret ret;
|
|
try {
|
|
bufferlist::iterator iter = out.begin();
|
|
::decode(ret, iter);
|
|
} catch (buffer::error& err) {
|
|
return -EIO;
|
|
}
|
|
|
|
if (existing_header)
|
|
*existing_header = ret.existing_header;
|
|
if (calculated_header)
|
|
*calculated_header = ret.calculated_header;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cls_rgw_bucket_rebuild_index_op(IoCtx& io_ctx, string& oid)
|
|
{
|
|
bufferlist in, out;
|
|
int r = io_ctx.exec(oid, "rgw", "bucket_rebuild_index", in, out);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void cls_rgw_encode_suggestion(char op, rgw_bucket_dir_entry& dirent, bufferlist& updates)
|
|
{
|
|
updates.append(op);
|
|
::encode(dirent, updates);
|
|
}
|
|
|
|
void cls_rgw_suggest_changes(ObjectWriteOperation& o, bufferlist& updates)
|
|
{
|
|
o.exec("rgw", "dir_suggest_changes", updates);
|
|
}
|
|
|
|
int cls_rgw_get_dir_header(IoCtx& io_ctx, string& oid, rgw_bucket_dir_header *header)
|
|
{
|
|
bufferlist in, out;
|
|
struct rgw_cls_list_op call;
|
|
call.num_entries = 0;
|
|
::encode(call, in);
|
|
int r = io_ctx.exec(oid, "rgw", "bucket_list", in, out);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
struct rgw_cls_list_ret ret;
|
|
try {
|
|
bufferlist::iterator iter = out.begin();
|
|
::decode(ret, iter);
|
|
} catch (buffer::error& err) {
|
|
return -EIO;
|
|
}
|
|
|
|
if (header)
|
|
*header = ret.dir.header;
|
|
|
|
return r;
|
|
}
|
|
|
|
int cls_rgw_usage_log_read(IoCtx& io_ctx, string& oid, string& user,
|
|
uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries,
|
|
string& read_iter, map<rgw_user_bucket, rgw_usage_log_entry>& usage,
|
|
bool *is_truncated)
|
|
{
|
|
*is_truncated = false;
|
|
|
|
bufferlist in, out;
|
|
rgw_cls_usage_log_read_op call;
|
|
call.start_epoch = start_epoch;
|
|
call.end_epoch = end_epoch;
|
|
call.owner = user;
|
|
call.max_entries = max_entries;
|
|
call.iter = read_iter;
|
|
::encode(call, in);
|
|
int r = io_ctx.exec(oid, "rgw", "user_usage_log_read", in, out);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
try {
|
|
rgw_cls_usage_log_read_ret result;
|
|
bufferlist::iterator iter = out.begin();
|
|
::decode(result, iter);
|
|
read_iter = result.next_iter;
|
|
if (is_truncated)
|
|
*is_truncated = result.truncated;
|
|
|
|
usage = result.usage;
|
|
} catch (buffer::error& e) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void cls_rgw_usage_log_trim(ObjectWriteOperation& op, string& user,
|
|
uint64_t start_epoch, uint64_t end_epoch)
|
|
{
|
|
bufferlist in;
|
|
rgw_cls_usage_log_trim_op call;
|
|
call.start_epoch = start_epoch;
|
|
call.end_epoch = end_epoch;
|
|
call.user = user;
|
|
::encode(call, in);
|
|
op.exec("rgw", "user_usage_log_trim", in);
|
|
}
|
|
|
|
void cls_rgw_usage_log_add(ObjectWriteOperation& op, rgw_usage_log_info& info)
|
|
{
|
|
bufferlist in;
|
|
rgw_cls_usage_log_add_op call;
|
|
call.info = info;
|
|
::encode(call, in);
|
|
op.exec("rgw", "user_usage_log_add", in);
|
|
}
|
|
|
|
/* garbage collection */
|
|
|
|
void cls_rgw_gc_set_entry(ObjectWriteOperation& op, uint32_t expiration_secs, cls_rgw_gc_obj_info& info)
|
|
{
|
|
bufferlist in;
|
|
cls_rgw_gc_set_entry_op call;
|
|
call.expiration_secs = expiration_secs;
|
|
call.info = info;
|
|
::encode(call, in);
|
|
op.exec("rgw", "gc_set_entry", in);
|
|
}
|
|
|
|
void cls_rgw_gc_defer_entry(ObjectWriteOperation& op, uint32_t expiration_secs, const string& tag)
|
|
{
|
|
bufferlist in;
|
|
cls_rgw_gc_defer_entry_op call;
|
|
call.expiration_secs = expiration_secs;
|
|
call.tag = tag;
|
|
::encode(call, in);
|
|
op.exec("rgw", "gc_defer_entry", in);
|
|
}
|
|
|
|
int cls_rgw_gc_list(IoCtx& io_ctx, string& oid, string& marker, uint32_t max,
|
|
list<cls_rgw_gc_obj_info>& entries, bool *truncated)
|
|
{
|
|
bufferlist in, out;
|
|
cls_rgw_gc_list_op call;
|
|
call.marker = marker;
|
|
call.max = max;
|
|
::encode(call, in);
|
|
int r = io_ctx.exec(oid, "rgw", "gc_list", in, out);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
cls_rgw_gc_list_ret ret;
|
|
try {
|
|
bufferlist::iterator iter = out.begin();
|
|
::decode(ret, iter);
|
|
} catch (buffer::error& err) {
|
|
return -EIO;
|
|
}
|
|
|
|
entries = ret.entries;
|
|
|
|
if (truncated)
|
|
*truncated = ret.truncated;
|
|
|
|
return r;
|
|
}
|
|
|
|
void cls_rgw_gc_remove(librados::ObjectWriteOperation& op, const list<string>& tags)
|
|
{
|
|
bufferlist in;
|
|
cls_rgw_gc_remove_op call;
|
|
call.tags = tags;
|
|
::encode(call, in);
|
|
op.exec("rgw", "gc_remove", in);
|
|
}
|