Also, implement key listing for user metadata.
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
OPT_CAPS_ADD,
OPT_CAPS_RM,
OPT_METADATA_GET,
+ OPT_METADATA_LIST,
};
static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
} else if (strcmp(prev_cmd, "metadata") == 0) {
if (strcmp(cmd, "get") == 0)
return OPT_METADATA_GET;
+ if (strcmp(cmd, "list") == 0)
+ return OPT_METADATA_LIST;
}
return -EINVAL;
cout << std::endl;
}
-
static void dump_bucket_usage(map<RGWObjCategory, RGWBucketStats>& stats, Formatter *formatter)
{
map<RGWObjCategory, RGWBucketStats>::iterator iter;
formatter->flush(cout);
}
+ if (opt_cmd == OPT_METADATA_LIST) {
+ void *handle;
+ int max = 1000;
+ int ret = store->meta_mgr->list_keys_init(metadata_key, &handle);
+ if (ret < 0) {
+ cerr << "ERROR: can't get key: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ bool truncated;
+
+ formatter->open_array_section("keys");
+
+ do {
+ list<string> keys;
+ ret = store->meta_mgr->list_keys_next(handle, max, keys, &truncated);
+ if (ret < 0) {
+ cerr << "ERROR: lists_keys_next(): " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ for (list<string>::iterator iter = keys.begin(); iter != keys.end(); ++iter) {
+ formatter->dump_string("key", *iter);
+ }
+ formatter->flush(cout);
+
+ } while (!truncated);
+
+ formatter->close_section();
+ formatter->flush(cout);
+
+ store->meta_mgr->list_keys_complete(handle);
+ }
+
return 0;
}
{
RGWMetadataHandler *handler;
string entry;
-
int ret = find_handler(metadata_key, &handler, entry);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
return handler->get(store, metadata_key, entry, f);
}
return handler->update(store, entry, bl);
}
+struct list_keys_handle {
+ void *handle;
+ RGWMetadataHandler *handler;
+};
+
+
+int RGWMetadataManager::list_keys_init(string& section, void **handle)
+{
+ string entry;
+ RGWMetadataHandler *handler;
+ int ret = find_handler(section, &handler, entry);
+ if (ret < 0) {
+ return -ENOENT;
+ }
+
+ list_keys_handle *h = new list_keys_handle;
+ h->handler = handler;
+ ret = handler->list_keys_init(store, &h->handle);
+ if (ret < 0) {
+ delete h;
+ return ret;
+ }
+
+ *handle = (void *)h;
+
+ return 0;
+}
+
+int RGWMetadataManager::list_keys_next(void *handle, int max, list<string>& keys, bool *truncated)
+{
+ list_keys_handle *h = (list_keys_handle *)handle;
+
+ RGWMetadataHandler *handler = h->handler;
+
+ return handler->list_keys_next(h->handle, max, keys, truncated);
+}
+
+
+void RGWMetadataManager::list_keys_complete(void *handle)
+{
+ list_keys_handle *h = (list_keys_handle *)handle;
+
+ RGWMetadataHandler *handler = h->handler;
+
+ handler->list_keys_complete(h->handle);
+ delete h;
+}
+
virtual int get(RGWRados *store, string& key, string& entry, Formatter *f) = 0;
virtual int update(RGWRados *store, string& entry, bufferlist& bl) = 0;
+
+ virtual int list_keys_init(RGWRados *store, void **phandle) = 0;
+ virtual int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated) = 0;
+ virtual void list_keys_complete(void *handle) = 0;
};
int get(string& metadata_key, Formatter *f);
int update(string& metadata_key, bufferlist& bl);
+
+ int list_keys_init(string& section, void **phandle);
+ int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated);
+ void list_keys_complete(void *handle);
};
#endif
bool is_truncated;
RGWListRawObjsCtx ctx;
do {
- vector<string> oids;
+ list<string> oids;
int r = list_raw_objects(pool, prefix, 1000,
ctx, oids, &is_truncated);
if (r < 0) {
return r;
}
- vector<string>::iterator iter;
+ list<string>::iterator iter;
for (iter = oids.begin(); iter != oids.end(); ++iter) {
string& val = *iter;
if (val.size() > prefix.size())
};
int RGWRados::list_raw_objects(rgw_bucket& pool, const string& prefix_filter,
- int max, RGWListRawObjsCtx& ctx, vector<string>& oids,
+ int max, RGWListRawObjsCtx& ctx, list<string>& oids,
bool *is_truncated)
{
RGWAccessListFilterPrefix filter(prefix_filter);
}
}
+ int list_raw_objects(rgw_bucket& pool, const string& prefix_filter, int max,
+ RGWListRawObjsCtx& ctx, list<string>& oids,
+ bool *is_truncated);
+
int list_raw_prefixed_objs(string pool_name, const string& prefix, list<string>& result);
int list_regions(list<string>& regions);
int list_zones(list<string>& zones);
int pool_iterate(RGWPoolIterCtx& ctx, uint32_t num, vector<RGWObjEnt>& objs,
bool *is_truncated, RGWAccessListFilter *filter);
- int list_raw_objects(rgw_bucket& pool, const string& prefix_filter, int max,
- RGWListRawObjsCtx& ctx, vector<string>& oids,
- bool *is_truncated);
-
uint64_t instance_id();
uint64_t next_bucket_id();
int update(RGWRados *store, string& metadata_key, bufferlist& bl) {
return 0;
}
+
+ struct list_keys_info {
+ RGWRados *store;
+ RGWListRawObjsCtx ctx;
+ };
+
+ int list_keys_init(RGWRados *store, void **phandle)
+ {
+ list_keys_info *info = new list_keys_info;
+
+ info->store = store;
+
+ *phandle = (void *)info;
+
+ return 0;
+ }
+
+ int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated) {
+ list_keys_info *info = (list_keys_info *)handle;
+
+ string no_filter;
+
+ keys.clear();
+
+ RGWRados *store = info->store;
+
+ return store->list_raw_objects(store->zone.user_uid_pool, no_filter,
+ max, info->ctx, keys, truncated);
+ }
+
+ void list_keys_complete(void *handle) {
+ list_keys_info *info = (list_keys_info *)handle;
+ delete info;
+ }
};
void rgw_user_init(RGWMetadataManager *mm)