X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ceph%2Fsrc%2Frgw%2Frgw_admin.cc;h=a6eef9a54205c8527e94022b42bff5595d004190;hb=f91f0fd59dc16d284d230f8953e42d49a893715d;hp=fb463ea88c9da5fe7dae22d7421c24be9d0046b4;hpb=1911f103e16ae0d04db10fb41db8217ef4c320d3;p=ceph.git diff --git a/ceph/src/rgw/rgw_admin.cc b/ceph/src/rgw/rgw_admin.cc index fb463ea88..a6eef9a54 100644 --- a/ceph/src/rgw/rgw_admin.cc +++ b/ceph/src/rgw/rgw_admin.cc @@ -136,6 +136,7 @@ void usage() cout << " bucket rewrite rewrite all objects in the specified bucket\n"; cout << " bucket sync disable disable bucket sync\n"; cout << " bucket sync enable enable bucket sync\n"; + cout << " bucket radoslist list rados objects backing bucket's objects\n"; cout << " bi get retrieve bucket index object entries\n"; cout << " bi put store bucket index object entries\n"; cout << " bi list list raw bucket index entries\n"; @@ -242,9 +243,10 @@ void usage() cout << " datalog list list data log\n"; cout << " datalog trim trim data log\n"; cout << " datalog status read data log status\n"; - cout << " orphans find init and run search for leaked rados objects (use job-id, pool)\n"; - cout << " orphans finish clean up search for leaked rados objects\n"; - cout << " orphans list-jobs list the current job-ids for orphans search\n"; + cout << " orphans find deprecated -- init and run search for leaked rados objects (use job-id, pool)\n"; + cout << " orphans finish deprecated -- clean up search for leaked rados objects\n"; + cout << " orphans list-jobs deprecated -- list the current job-ids for orphans search\n"; + cout << " * the three 'orphans' sub-commands are now deprecated; consider using the `rgw-orphan-list` tool\n"; cout << " role create create a AWS role for use with STS\n"; cout << " role rm remove a role\n"; cout << " role get get a role\n"; @@ -586,6 +588,7 @@ enum class OPT { BUCKET_REWRITE, BUCKET_RESHARD, BUCKET_CHOWN, + BUCKET_RADOS_LIST, POLICY, POOL_ADD, POOL_RM, @@ -785,6 +788,8 @@ static SimpleCmd::Commands all_cmds = { { "bucket rewrite", OPT::BUCKET_REWRITE }, { "bucket reshard", OPT::BUCKET_RESHARD }, { "bucket chown", OPT::BUCKET_CHOWN }, + { "bucket radoslist", OPT::BUCKET_RADOS_LIST }, + { "bucket rados list", OPT::BUCKET_RADOS_LIST }, { "policy", OPT::POLICY }, { "pool add", OPT::POOL_ADD }, { "pool rm", OPT::POOL_RM }, @@ -1076,8 +1081,12 @@ public: } }; -static int init_bucket(const string& tenant_name, const string& bucket_name, const string& bucket_id, - RGWBucketInfo& bucket_info, rgw_bucket& bucket, map *pattrs = nullptr) +static int init_bucket(const string& tenant_name, + const string& bucket_name, + const string& bucket_id, + RGWBucketInfo& bucket_info, + rgw_bucket& bucket, + map *pattrs = nullptr) { if (!bucket_name.empty()) { auto obj_ctx = store->svc()->sysobj->init_obj_ctx(); @@ -1657,7 +1666,7 @@ static int commit_period(RGWRealm& realm, RGWPeriod& period, if (remote.empty() && url.empty()) { // use the new master zone's connection remote = master_zone.id; - cout << "Sending period to new master zone " << remote << std::endl; + cerr << "Sending period to new master zone " << remote << std::endl; } boost::optional conn; RGWRESTConn *remote_conn = nullptr; @@ -3781,6 +3790,9 @@ int main(int argc, const char **argv) // not a raw op if 'period update' needs to commit to master bool raw_period_update = opt_cmd == OPT::PERIOD_UPDATE && !commit; + // not a raw op if 'period pull' needs to read zone/period configuration + bool raw_period_pull = opt_cmd == OPT::PERIOD_PULL && !url.empty(); + std::set raw_storage_ops_list = {OPT::ZONEGROUP_ADD, OPT::ZONEGROUP_CREATE, OPT::ZONEGROUP_DELETE, OPT::ZONEGROUP_GET, OPT::ZONEGROUP_LIST, OPT::ZONEGROUP_SET, OPT::ZONEGROUP_DEFAULT, @@ -3798,7 +3810,6 @@ int main(int argc, const char **argv) OPT::ZONE_PLACEMENT_GET, OPT::REALM_CREATE, OPT::PERIOD_DELETE, OPT::PERIOD_GET, - OPT::PERIOD_PULL, OPT::PERIOD_GET_CURRENT, OPT::PERIOD_LIST, OPT::GLOBAL_QUOTA_GET, OPT::GLOBAL_QUOTA_SET, OPT::GLOBAL_QUOTA_ENABLE, OPT::GLOBAL_QUOTA_DISABLE, @@ -3869,7 +3880,7 @@ int main(int argc, const char **argv) bool raw_storage_op = (raw_storage_ops_list.find(opt_cmd) != raw_storage_ops_list.end() || - raw_period_update); + raw_period_update || raw_period_pull); bool need_cache = readonly_ops_list.find(opt_cmd) == readonly_ops_list.end(); if (raw_storage_op) { @@ -6033,10 +6044,17 @@ int main(int argc, const char **argv) return -ret; } formatter->open_array_section("entries"); - bool truncated; + + bool truncated = false; int count = 0; - if (max_entries < 0) - max_entries = 1000; + + static constexpr int MAX_PAGINATE_SIZE = 10000; + static constexpr int DEFAULT_MAX_ENTRIES = 1000; + + if (max_entries < 0) { + max_entries = DEFAULT_MAX_ENTRIES; + } + const int paginate_size = std::min(max_entries, MAX_PAGINATE_SIZE); string prefix; string delim; @@ -6056,7 +6074,10 @@ int main(int argc, const char **argv) list_op.params.allow_unordered = bool(allow_unordered); do { - ret = list_op.list_objects(max_entries - count, &result, &common_prefixes, &truncated, null_yield); + const int remaining = max_entries - count; + ret = list_op.list_objects(std::min(remaining, paginate_size), + &result, &common_prefixes, &truncated, + null_yield); if (ret < 0) { cerr << "ERROR: store->list_objects(): " << cpp_strerror(-ret) << std::endl; return -ret; @@ -6064,8 +6085,7 @@ int main(int argc, const char **argv) count += result.size(); - for (vector::iterator iter = result.begin(); iter != result.end(); ++iter) { - rgw_bucket_dir_entry& entry = *iter; + for (const auto& entry : result) { encode_json("entry", entry, formatter); } formatter->flush(cout); @@ -6076,6 +6096,29 @@ int main(int argc, const char **argv) } /* have bucket_name */ } /* OPT::BUCKETS_LIST */ + if (opt_cmd == OPT::BUCKET_RADOS_LIST) { + RGWRadosList lister(store, + max_concurrent_ios, orphan_stale_secs, tenant); + if (bucket_name.empty()) { + ret = lister.run(); + } else { + ret = lister.run(bucket_name); + } + + if (ret < 0) { + std::cerr << + "ERROR: bucket radoslist failed to finish before " << + "encountering error: " << cpp_strerror(-ret) << std::endl; + std::cerr << "************************************" + "************************************" << std::endl; + std::cerr << "WARNING: THE RESULTS ARE NOT RELIABLE AND SHOULD NOT " << + "BE USED IN DELETING ORPHANS" << std::endl; + std::cerr << "************************************" + "************************************" << std::endl; + return -ret; + } + } + if (opt_cmd == OPT::BUCKET_STATS) { if (bucket_name.empty() && !bucket_id.empty()) { rgw_bucket bucket; @@ -7192,27 +7235,35 @@ next: if (opt_cmd == OPT::LC_LIST) { formatter->open_array_section("lifecycle_list"); - map bucket_lc_map; + vector bucket_lc_map; string marker; + int index{0}; #define MAX_LC_LIST_ENTRIES 100 if (max_entries < 0) { max_entries = MAX_LC_LIST_ENTRIES; } do { - int ret = store->getRados()->list_lc_progress(marker, max_entries, &bucket_lc_map); + int ret = store->getRados()->list_lc_progress(marker, max_entries, + bucket_lc_map, index); if (ret < 0) { - cerr << "ERROR: failed to list objs: " << cpp_strerror(-ret) << std::endl; + cerr << "ERROR: failed to list objs: " << cpp_strerror(-ret) + << std::endl; return 1; } - map::iterator iter; - for (iter = bucket_lc_map.begin(); iter != bucket_lc_map.end(); ++iter) { + for (const auto& entry : bucket_lc_map) { formatter->open_object_section("bucket_lc_info"); - formatter->dump_string("bucket", iter->first); - string lc_status = LC_STATUS[iter->second]; + formatter->dump_string("bucket", entry.bucket); + char exp_buf[100]; + time_t t{time_t(entry.start_time)}; + if (std::strftime( + exp_buf, sizeof(exp_buf), + "%a, %d %b %Y %T %Z", std::gmtime(&t))) { + formatter->dump_string("started", exp_buf); + } + string lc_status = LC_STATUS[entry.status]; formatter->dump_string("status", lc_status); formatter->close_section(); // objs formatter->flush(cout); - marker = iter->first; } } while (!bucket_lc_map.empty()); @@ -7273,10 +7324,14 @@ next: if (opt_cmd == OPT::ORPHANS_FIND) { if (!yes_i_really_mean_it) { - cerr << "accidental removal of active objects can not be reversed; " + cerr << "this command is now deprecated; please consider using the rgw-orphan-list tool; " + << "accidental removal of active objects cannot be reversed; " << "do you really mean it? (requires --yes-i-really-mean-it)" << std::endl; return EINVAL; + } else { + cerr << "IMPORTANT: this command is now deprecated; please consider using the rgw-orphan-list tool" + << std::endl; } RGWOrphanSearch search(store, max_concurrent_ios, orphan_stale_secs); @@ -7308,6 +7363,17 @@ next: } if (opt_cmd == OPT::ORPHANS_FINISH) { + if (!yes_i_really_mean_it) { + cerr << "this command is now deprecated; please consider using the rgw-orphan-list tool; " + << "accidental removal of active objects cannot be reversed; " + << "do you really mean it? (requires --yes-i-really-mean-it)" + << std::endl; + return EINVAL; + } else { + cerr << "IMPORTANT: this command is now deprecated; please consider using the rgw-orphan-list tool" + << std::endl; + } + RGWOrphanSearch search(store, max_concurrent_ios, orphan_stale_secs); if (job_id.empty()) { @@ -7328,6 +7394,16 @@ next: } if (opt_cmd == OPT::ORPHANS_LIST_JOBS){ + if (!yes_i_really_mean_it) { + cerr << "this command is now deprecated; please consider using the rgw-orphan-list tool; " + << "do you really mean it? (requires --yes-i-really-mean-it)" + << std::endl; + return EINVAL; + } else { + cerr << "IMPORTANT: this command is now deprecated; please consider using the rgw-orphan-list tool" + << std::endl; + } + RGWOrphanStore orphan_store(store); int ret = orphan_store.init(); if (ret < 0){ @@ -8560,7 +8636,7 @@ next: do { list entries; if (specified_shard_id) { - ret = datalog_svc->list_entries(shard_id, start_time.to_real_time(), end_time.to_real_time(), max_entries - count, entries, marker, NULL, &truncated); + ret = datalog_svc->list_entries(shard_id, start_time.to_real_time(), end_time.to_real_time(), max_entries - count, entries, marker, &marker, &truncated); } else { ret = datalog_svc->list_entries(start_time.to_real_time(), end_time.to_real_time(), max_entries - count, entries, log_marker, &truncated); }