f->dump_string(name, val);
}
+void encode_json(const char *name, bool val, Formatter *f)
+{
+ string s;
+ if (val)
+ s = "true";
+ else
+ s = "false";
+
+ f->dump_string(name, s);
+}
+
void encode_json(const char *name, int val, Formatter *f)
{
f->dump_int(name, val);
void encode_json(const char *name, const string& val, Formatter *f);
void encode_json(const char *name, const char *val, Formatter *f);
+void encode_json(const char *name, bool val, Formatter *f);
void encode_json(const char *name, int val, Formatter *f);
void encode_json(const char *name, unsigned val, Formatter *f);
void encode_json(const char *name, long val, Formatter *f);
OPT_REGION_DEFAULT,
OPT_REGIONMAP_SHOW,
OPT_REGIONMAP_SET,
+ OPT_REGIONMAP_UPDATE,
OPT_ZONE_INFO,
OPT_ZONE_SET,
OPT_ZONE_LIST,
return OPT_REGIONMAP_SHOW;
if (strcmp(cmd, "set") == 0)
return OPT_REGIONMAP_SET;
+ if (strcmp(cmd, "update") == 0)
+ return OPT_REGIONMAP_UPDATE;
} else if (strcmp(prev_cmd, "zone") == 0) {
if (strcmp(cmd, "info") == 0)
return OPT_ZONE_INFO;
bool raw_storage_op = (opt_cmd == OPT_REGION_INFO || opt_cmd == OPT_REGION_LIST ||
opt_cmd == OPT_REGION_SET || opt_cmd == OPT_REGION_DEFAULT ||
opt_cmd == OPT_REGIONMAP_SHOW || opt_cmd == OPT_REGIONMAP_SET ||
+ opt_cmd == OPT_REGIONMAP_UPDATE ||
opt_cmd == OPT_ZONE_INFO || opt_cmd == OPT_ZONE_SET ||
opt_cmd == OPT_ZONE_LIST);
formatter->flush(cout);
}
+ if (opt_cmd == OPT_REGIONMAP_UPDATE) {
+ RGWRegionMap regionmap;
+ int ret = regionmap.read(g_ceph_context, store);
+ if (ret < 0 && ret != -ENOENT) {
+ cerr << "failed to read region map: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ RGWRegion region;
+ ret = region.init(g_ceph_context, store, false);
+ if (ret < 0) {
+ cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ list<string> regions;
+ ret = store->list_regions(regions);
+ if (ret < 0) {
+ cerr << "failed to list regions: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ for (list<string>::iterator iter = regions.begin(); iter != regions.end(); ++iter) {
+ ret = region.read_info(*iter);
+ if (ret < 0) {
+ cerr << "failed to read region info (name=" << *iter << "): " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+ regionmap.update(region);
+ }
+
+ ret = regionmap.store(g_ceph_context, store);
+ if (ret < 0) {
+ cerr << "ERROR: couldn't store region map info: " << cpp_strerror(-ret) << std::endl;
+ return 1;
+ }
+
+ encode_json("region-map", regionmap, formatter);
+ formatter->flush(cout);
+ }
+
if (opt_cmd == OPT_ZONE_INFO) {
RGWRegion region;
int ret = region.init(g_ceph_context, store);
void RGWRegion::dump(Formatter *f) const
{
encode_json("name", name, f);
+ encode_json("api_name", api_name, f);
+ encode_json("is_master", is_master, f);
encode_json("endpoints", endpoints, f);
encode_json("master_zone", master_zone, f);
encode_json("zones", zones, f);
void RGWRegion::decode_json(JSONObj *obj)
{
JSONDecoder::decode_json("name", name, obj);
+ JSONDecoder::decode_json("api_name", api_name, obj);
+ JSONDecoder::decode_json("is_master", is_master, obj);
JSONDecoder::decode_json("endpoints", endpoints, obj);
JSONDecoder::decode_json("master_zone", master_zone, obj);
JSONDecoder::decode_json("zones", zones, decode_zones, obj);
if (!setup_region)
return 0;
- string pool_name = get_pool_name(cct);
-
- name = cct->_conf->rgw_region;
+ string region_name = cct->_conf->rgw_region;
if (name.empty()) {
RGWDefaultRegionInfo default_info;
lderr(cct) << "failed reading default region info: " << cpp_strerror(-r) << dendl;
return r;
}
- name = default_info.default_region;
+ string region_name = default_info.default_region;
}
+ return read_info(name);
+}
+
+int RGWRegion::read_info(const string& region_name)
+{
+ string pool_name = get_pool_name(cct);
rgw_bucket pool(pool_name.c_str());
bufferlist bl;
+ name = region_name;
+
string oid = region_info_oid_prefix + name;
int ret = rgw_get_obj(store, NULL, pool, oid, bl);
return ret;
}
+void RGWRegionMap::encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ ::encode(regions, bl);
+ ::encode(master_region, bl);
+ ENCODE_FINISH(bl);
+}
+
+void RGWRegionMap::decode(bufferlist::iterator& bl) {
+ DECODE_START(1, bl);
+ ::decode(regions, bl);
+ ::decode(master_region, bl);
+ DECODE_FINISH(bl);
+
+ regions_by_api.clear();
+ for (map<string, RGWRegion>::iterator iter = regions.begin();
+ iter != regions.end(); ++iter) {
+ RGWRegion& region = iter->second;
+ regions_by_api[region.api_name] = region;
+ if (region.is_master) {
+ master_region = region.name;
+ }
+ }
+}
+
void RGWRegionMap::get_params(CephContext *cct, string& pool_name, string& oid)
{
pool_name = cct->_conf->rgw_zone_root_pool;
if (ret < 0)
return ret;
+
+ Mutex::Locker l(lock);
try {
bufferlist::iterator iter = bl.begin();
::decode(*this, iter);
rgw_bucket pool(pool_name.c_str());
+ Mutex::Locker l(lock);
+
bufferlist bl;
::encode(*this, bl);
int ret = rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), false, NULL);
return ret;
}
+int RGWRegionMap::update(RGWRegion& region)
+{
+ Mutex::Locker l(lock);
+
+ if (region.is_master && !master_region.empty() &&
+ master_region.compare(region.name) != 0) {
+ derr << "cannot update region map, master_region conflict" << dendl;
+ return -EINVAL;
+ }
+ map<string, RGWRegion>::iterator iter = regions.find(region.name);
+ if (iter != regions.end()) {
+ RGWRegion& old_region = iter->second;
+ if (!old_region.api_name.empty()) {
+ regions_by_api.erase(old_region.api_name);
+ }
+ }
+ regions[region.name] = region;
+
+ if (!region.api_name.empty()) {
+ regions_by_api[region.api_name] = region;
+ }
+
+ if (region.is_master) {
+ master_region = region.name;
+ }
+ return 0;
+}
+
void RGWObjManifest::append(RGWObjManifest& m)
{
map<uint64_t, RGWObjManifestPart>::iterator iter;
struct RGWRegion {
string name;
+ string api_name;
list<string> endpoints;
+ bool is_master;
string master_zone;
map<string, RGWZone> zones;
CephContext *cct;
RGWRados *store;
+ RGWRegion() : is_master(false) {}
+
void encode(bufferlist& bl) const {
ENCODE_START(1, 1, bl);
+ ::encode(name, bl);
+ ::encode(api_name, bl);
+ ::encode(is_master, bl);
::encode(endpoints, bl);
::encode(master_zone, bl);
::encode(zones, bl);
void decode(bufferlist::iterator& bl) {
DECODE_START(1, bl);
+ ::decode(name, bl);
+ ::decode(api_name, bl);
+ ::decode(is_master, bl);
::decode(endpoints, bl);
::decode(master_zone, bl);
::decode(zones, bl);
int init(CephContext *_cct, RGWRados *_store, bool setup_region = true);
int create_default();
int store_info(bool exclusive);
+ int read_info(const string& region_name);
int read_default(RGWDefaultRegionInfo& default_region);
int set_as_default();
WRITE_CLASS_ENCODER(RGWRegion);
struct RGWRegionMap {
+ Mutex lock;
map<string, RGWRegion> regions;
+ map<string, RGWRegion> regions_by_api;
string master_region;
- void encode(bufferlist& bl) const {
- ENCODE_START(1, 1, bl);
- ::encode(regions, bl);
- ENCODE_FINISH(bl);
- }
+ RGWRegionMap() : lock("RGWRegionMap") {}
- void decode(bufferlist::iterator& bl) {
- DECODE_START(1, bl);
- ::decode(regions, bl);
- DECODE_FINISH(bl);
- }
+ void encode(bufferlist& bl) const;
+ void decode(bufferlist::iterator& bl);
void get_params(CephContext *cct, string& pool_name, string& oid);
int read(CephContext *cct, RGWRados *store);
int store(CephContext *cct, RGWRados *store);
+ int update(RGWRegion& region);
+
void dump(Formatter *f) const;
void decode_json(JSONObj *obj);
};