From: Yehuda Sadeh Date: Thu, 4 Jul 2013 00:09:56 +0000 (-0700) Subject: Merge remote-tracking branch 'origin/master' into wip-rgw-geo X-Git-Tag: v0.67-rc1~128^2~11 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d30fc4bdd12fe9356401a9752b083ea6cf2f0a9a;p=ceph.git Merge remote-tracking branch 'origin/master' into wip-rgw-geo Conflicts: src/Makefile.am src/include/rados/librados.hpp src/rgw/rgw_admin.cc src/rgw/rgw_bucket.cc src/rgw/rgw_common.cc src/rgw/rgw_common.h src/rgw/rgw_json_enc.cc src/rgw/rgw_main.cc src/rgw/rgw_op.h src/rgw/rgw_rados.cc src/rgw/rgw_tools.cc src/rgw/rgw_user.cc src/rgw/rgw_user.h Signed-off-by: Yehuda Sadeh --- d30fc4bdd12fe9356401a9752b083ea6cf2f0a9a diff --cc src/Makefile.am index 0e755a15b1f2,7b82e9d23e4e..c799e0f9415c --- a/src/Makefile.am +++ b/src/Makefile.am @@@ -408,10 -396,9 +405,10 @@@ librgw_a_CXXFLAGS = -Woverloaded-virtua noinst_LIBRARIES += librgw.a my_radosgw_ldadd = \ - librgw.a librados.la libcls_rgw_client.a \ - libcls_lock_client.a libcls_refcount_client.a -lcurl -lexpat \ - $(LIBGLOBAL_LDA) + libglobal.la librgw.a librados.la libcls_rgw_client.a libcls_log_client.a \ + libcls_statelog_client.a libcls_replica_log_client.a libcls_lock_client.a \ + libcls_refcount_client.a libcls_version_client.a -lcurl -lexpat \ - $(PTHREAD_LIBS) -lm $(CRYPTO_LIBS) $(EXTRALIBS) ++ $(PTHREAD_LIBS) -lm $(CRYPTO_LIBS) $(EXTRALIBS) $(LIBGLOBAL_LDA) radosgw_SOURCES = \ rgw/rgw_resolve.cc \ @@@ -971,31 -914,9 +983,30 @@@ check_PROGRAMS += unittest_texttabl if WITH_RADOSGW ceph_test_cors_SOURCES = test/test_cors.cc - ceph_test_cors_LDFLAGS = libglobal.la - ceph_test_cors_LDADD = librados.la librgw.a ${UNITTEST_LDADD} ${UNITTEST_STATIC_LDADD} $(CRYPTO_LIBS) -lcurl -luuid -lexpat + ceph_test_cors_LDADD = librados.la librgw.a $(LIBGLOBAL_LDA) ${UNITTEST_LDADD} ${UNITTEST_STATIC_LDADD} -lcurl -luuid -lexpat ceph_test_cors_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} bin_DEBUGPROGRAMS += ceph_test_cors + +cls_test_rgw_meta_SOURCES = test/test_rgw_admin_meta.cc +cls_test_rgw_meta_LDFLAGS = libglobal.la +cls_test_rgw_meta_LDADD = librgw.a ${UNITTEST_LDADD} ${UNITTEST_STATIC_LDADD} -lcryptopp -lcurl -luuid -lexpat librados.la libcls_version_client.a \ + libcls_log_client.a libcls_statelog_client.a libcls_refcount_client.a libcls_rgw_client.a libcls_lock_client.a +cls_test_rgw_meta_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} +bin_DEBUGPROGRAMS += cls_test_rgw_meta + +cls_test_rgw_log_SOURCES = test/test_rgw_admin_log.cc +cls_test_rgw_log_LDFLAGS = libglobal.la +cls_test_rgw_log_LDADD = librgw.a ${UNITTEST_LDADD} ${UNITTEST_STATIC_LDADD} -lcryptopp -lcurl -luuid -lexpat librados.la libcls_version_client.a \ + libcls_log_client.a libcls_statelog_client.a libcls_refcount_client.a libcls_rgw_client.a libcls_lock_client.a +cls_test_rgw_log_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} +bin_DEBUGPROGRAMS += cls_test_rgw_log + +cls_test_rgw_opstate_SOURCES = test/test_rgw_admin_opstate.cc +cls_test_rgw_opstate_LDFLAGS = libglobal.la +cls_test_rgw_opstate_LDADD = librgw.a ${UNITTEST_LDADD} ${UNITTEST_STATIC_LDADD} -lcryptopp -lcurl -luuid -lexpat librados.la libcls_version_client.a \ + libcls_log_client.a libcls_statelog_client.a libcls_refcount_client.a libcls_rgw_client.a libcls_lock_client.a +cls_test_rgw_opstate_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} +bin_DEBUGPROGRAMS += cls_test_rgw_opstate endif ceph_test_librbd_SOURCES = test/librbd/test_librbd.cc test/librados/test.cc diff --cc src/include/rados/librados.hpp index 697969f2fbcd,497fc212db19..b6ea02595839 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@@ -110,13 -120,19 +120,25 @@@ namespace librado OP_FAILOK = 2, }; - + class ObjectOperationCompletion { + public: + virtual ~ObjectOperationCompletion() {} + virtual void handle_completion(int r, bufferlist& outbl) = 0; + }; + + /** + * These flags apply to the ObjectOperation as a whole. + * + * BALANCE_READS and LOCALIZE_READS should only be used + * when reading from data you're certain won't change, + * like a snapshot, or where eventual consistency is ok. + */ + enum ObjectOperationGlobalFlags { + OPERATION_NOFLAG = 0, + OPERATION_BALANCE_READS = 1, + OPERATION_LOCALIZE_READS = 2, + }; + /* * ObjectOperation : compound object operation * Batch multiple object operations into a single request, to be applied diff --cc src/rgw/rgw_admin.cc index 24e27c17a5bf,c505cc207640..4f3d41530061 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@@ -693,26 -484,10 +695,27 @@@ int main(int argc, char **argv map categories; string caps; int check_objects = false; - std::string infile; RGWUserAdminOpState user_op; RGWBucketAdminOpState bucket_op; + string infile; + string metadata_key; + RGWObjVersionTracker objv_tracker; + string marker; + string start_marker; + string end_marker; + int max_entries = -1; + int system = false; + bool system_specified = false; + int shard_id = -1; + bool specified_shard_id = false; + string daemon_id; + bool specified_daemon_id = false; + string client_id; + string op_id; + string state_str; + string replica_log_type_str; + ReplicaLogType replica_log_type = ReplicaLog_Invalid; + string op_mask_str; std::string val; std::ostringstream errs; @@@ -741,12 -516,8 +744,14 @@@ pool_name = val; } else if (ceph_argparse_witharg(args, i, &val, "-o", "--object", (char*)NULL)) { object = val; + } else if (ceph_argparse_witharg(args, i, &val, "--client-id", (char*)NULL)) { + client_id = val; + } else if (ceph_argparse_witharg(args, i, &val, "--op-id", (char*)NULL)) { + op_id = val; + } else if (ceph_argparse_witharg(args, i, &val, "--state", (char*)NULL)) { + state_str = val; + } else if (ceph_argparse_witharg(args, i, &val, "--op-mask", (char*)NULL)) { + op_mask_str = val; } else if (ceph_argparse_witharg(args, i, &val, "--key-type", (char*)NULL)) { key_type_str = val; if (key_type_str.compare("swift") == 0) { @@@ -1724,8 -1151,8 +1740,7 @@@ next } if (opt_cmd == OPT_GC_LIST) { - int ret; int index = 0; - string marker; bool truncated; formatter->open_array_section("entries"); diff --cc src/rgw/rgw_bucket.cc index fc364cfec8dd,6a6b57623528..e86abfe6eabc --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@@ -309,9 -275,9 +309,8 @@@ int rgw_remove_bucket(RGWRados *store, return ret; obj.bucket = bucket; - int max = 1000; - ret = rgw_get_obj(store, NULL, store->zone.domain_root,\ - bucket.name, bl, NULL); + ret = rgw_get_system_obj(store, NULL, store->zone.domain_root, bucket.name, bl, NULL, NULL); bufferlist::iterator iter = bl.begin(); try { @@@ -322,9 -288,10 +321,10 @@@ } if (delete_children) { + int max = 1000; - ret = store->list_objects(bucket, max, prefix, delim, marker,\ - objs, common_prefixes,\ - false, ns, (bool *)false, NULL); + ret = store->list_objects(bucket, max, prefix, delim, marker, + objs, common_prefixes, + false, ns, true, NULL, NULL); if (ret < 0) return ret; diff --cc src/rgw/rgw_bucket.h index d5f023f7bd9f,e2f4d5eee405..5ee6a9b41cd3 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@@ -186,9 -173,11 +186,9 @@@ class RGWBucke private: public: - RGWBucket() : store(NULL), failure(false) {} + RGWBucket() : store(NULL), handle(NULL), failure(false) {} int init(RGWRados *storage, RGWBucketAdminOpState& op_state); - int create_bucket(string bucket_str, string& user_id, string& display_name); - int check_bad_index_multipart(RGWBucketAdminOpState& op_state, list& objs_to_unlink, std::string *err_msg = NULL); diff --cc src/rgw/rgw_common.cc index a17f1c2017e5,9e300ad6e04a..aea396bf3def --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@@ -507,14 -447,10 +507,15 @@@ int XMLArgs::parse( if (ret >= 0) { string& name = nv.get_name(); string& val = nv.get_val(); - val_map[name] = val; + + if (name.compare(0, sizeof(RGW_SYS_PARAM_PREFIX) - 1, RGW_SYS_PARAM_PREFIX) == 0) { + sys_val_map[name] = val; + } else { + val_map[name] = val; + } if ((name.compare("acl") == 0) || + (name.compare("cors") == 0) || (name.compare("location") == 0) || (name.compare("logging") == 0) || (name.compare("delete") == 0) || @@@ -703,64 -639,13 +704,62 @@@ bool url_decode(string& src_str, string return true; } +string rgw_trim_whitespace(const string& src) +{ + if (src.empty()) { + return string(); + } + + int start = 0; + for (; start != (int)src.size(); start++) { + if (!isspace(src[start])) + break; + } + + int end = src.size() - 1; + if (end <= start) { + return string(); + } + + for (; end > start; end--) { + if (!isspace(src[end])) + break; + } + + return src.substr(start, end - start + 1); +} + +string rgw_trim_quotes(const string& val) +{ + string s = rgw_trim_whitespace(val); + if (s.size() < 2) + return s; + + int start = 0; + int end = s.size() - 1; + int quotes_count = 0; + + if (s[start] == '"') { + start++; + quotes_count++; + } + if (s[end] == '"') { + end--; + quotes_count++; + } + if (quotes_count == 2) { + return s.substr(start, end - start + 1); + } + return s; +} + - static struct { + struct rgw_name_to_flag { const char *type_name; - uint32_t perm; - } cap_names[] = { {"*", RGW_CAP_ALL}, - {"read", RGW_CAP_READ}, - {"write", RGW_CAP_WRITE}, - {NULL, 0} }; + uint32_t flag; + }; - int RGWUserCaps::parse_cap_perm(const string& str, uint32_t *perm) + static int parse_list_of_flags(struct rgw_name_to_flag *mapping, + const string& str, uint32_t *perm) { list strs; get_str_list(str, strs); diff --cc src/rgw/rgw_common.h index c03ee74367ff,9b761810286f..c885724efbdb --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@@ -409,15 -387,13 +415,16 @@@ struct RGWUserInf map subusers; __u8 suspended; uint32_t max_buckets; + uint32_t op_mask; RGWUserCaps caps; + __u8 system; + string default_placement; + list placement_tags; - RGWUserInfo() : auid(0), suspended(0), max_buckets(RGW_DEFAULT_MAX_BUCKETS), system(0) {} - RGWUserInfo() : auid(0), suspended(0), max_buckets(RGW_DEFAULT_MAX_BUCKETS), op_mask(RGW_OP_TYPE_ALL) {} ++ RGWUserInfo() : auid(0), suspended(0), max_buckets(RGW_DEFAULT_MAX_BUCKETS), op_mask(RGW_OP_TYPE_ALL), system(0) {} void encode(bufferlist& bl) const { - ENCODE_START(12, 9, bl); + ENCODE_START(13, 9, bl); ::encode(auid, bl); string access_key; string secret_key; @@@ -448,13 -424,11 +455,14 @@@ ::encode(swift_keys, bl); ::encode(max_buckets, bl); ::encode(caps, bl); + ::encode(op_mask, bl); + ::encode(system, bl); + ::encode(default_placement, bl); + ::encode(placement_tags, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { -- DECODE_START_LEGACY_COMPAT_LEN_32(11, 9, 9, bl); ++ DECODE_START_LEGACY_COMPAT_LEN_32(13, 9, 9, bl); if (struct_v >= 2) ::decode(auid, bl); else auid = CEPH_AUTH_UID_DEFAULT; string access_key; @@@ -496,14 -470,11 +504,17 @@@ if (struct_v >= 11) { ::decode(caps, bl); } - system = 0; if (struct_v >= 12) { - ::decode(system, bl); + ::decode(op_mask, bl); + } else { + op_mask = RGW_OP_TYPE_ALL; } ++ system = 0; + if (struct_v >= 13) { ++ ::decode(system, bl); + ::decode(default_placement, bl); + ::decode(placement_tags, bl); /* tags of allowed placement rules */ + } DECODE_FINISH(bl); } void dump(Formatter *f) const; diff --cc src/rgw/rgw_json_enc.cc index face8534eb58,e26299f24add..6ab073bb9874 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@@ -368,11 -357,10 +385,16 @@@ void RGWUserInfo::dump(Formatter *f) co encode_json_map("swift_keys", NULL, "key", NULL, user_info_dump_swift_key,(void *)this, swift_keys, f); encode_json("caps", caps, f); + + char buf[256]; + op_type_to_str(op_mask, buf, sizeof(buf)); + encode_json("op_mask", (const char *)buf, f); ++ + if (system) { /* no need to show it for every user */ + encode_json("system", (bool)system, f); + } + encode_json("default_placement", default_placement, f); + encode_json("placement_tags", placement_tags, f); } @@@ -413,11 -401,10 +435,16 @@@ void RGWUserInfo::decode_json(JSONObj * JSONDecoder::decode_json("subusers", subusers, decode_subusers, obj); JSONDecoder::decode_json("caps", caps, obj); + + string mask_str; + JSONDecoder::decode_json("op_mask", mask_str, obj); + rgw_parse_op_type_list(mask_str, &op_mask); ++ + bool sys = false; + JSONDecoder::decode_json("system", sys, obj); + system = (__u8)sys; + JSONDecoder::decode_json("default_placement", default_placement, obj); + JSONDecoder::decode_json("placement_tags", placement_tags, obj); } void rgw_bucket::dump(Formatter *f) const diff --cc src/rgw/rgw_main.cc index c1f48579f9a8,3d6bfb908f04..f06e794b301f --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@@ -343,7 -335,14 +343,14 @@@ void RGWProcess::handle_request(RGWRequ req->log(s, "reading the cors attr"); handler->read_cors_config(); - + + req->log(s, "verifying op mask"); + ret = op->verify_op_mask(); + if (ret < 0) { + abort_early(s, ret); + goto done; + } + req->log(s, "verifying op permissions"); ret = op->verify_permission(); if (ret < 0) { diff --cc src/rgw/rgw_op.h index fc12470c3d67,184935228b34..7a2e4920ba8e --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@@ -26,7 -26,9 +26,6 @@@ using namespace std struct req_state; class RGWHandler; -void rgw_get_request_metadata(struct req_state *s, map& attrs); -int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, bool prefetch_data); -- /** * Provide the base class for all ops. */ @@@ -266,8 -271,36 +275,9 @@@ public virtual void send_response() = 0; virtual const char *name() { return "delete_bucket"; } + virtual uint32_t op_mask() { return RGW_OP_TYPE_DELETE; } }; -class RGWPutObjProcessor -{ -protected: - RGWRados *store; - struct req_state *s; - bool is_complete; - - virtual int do_complete(string& etag, map& attrs) = 0; - - list objs; - - void add_obj(rgw_obj& obj) { - objs.push_back(obj); - } -public: - RGWPutObjProcessor() : store(NULL), s(NULL), is_complete(false) {} - virtual ~RGWPutObjProcessor(); - virtual int prepare(RGWRados *_store, struct req_state *_s) { - store = _store; - s = _s; - return 0; - }; - virtual int handle_data(bufferlist& bl, off_t ofs, void **phandle) = 0; - virtual int throttle_data(void *handle) = 0; - virtual int complete(string& etag, map& attrs); -}; - class RGWPutObj : public RGWOp { friend class RGWPutObjProcessor; diff --cc src/rgw/rgw_rados.cc index d1fdce17d585,5c0bb6e8bbd5..c836a4eb0f18 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@@ -2479,97 -1303,25 +2481,97 @@@ int RGWRados::copy_obj(void *ctx void *handle = NULL; - map attrset; + map src_attrs; off_t ofs = 0; off_t end = -1; - ret = prepare_get_obj(ctx, src_obj, &ofs, &end, &attrset, - mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &obj_size, &handle, err); + if (!remote_src && source_zone.empty()) { + ret = prepare_get_obj(ctx, src_obj, &ofs, &end, &src_attrs, + mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &obj_size, NULL, &handle, err); + if (ret < 0) + return ret; + } else { + /* source is in a different region, copy it there */ - if (ret < 0) - return ret; + RGWRESTStreamReadRequest *in_stream_req; + string tag; + append_rand_alpha(cct, tag, tag, 32); - if (replace_attrs) { - if (!attrs[RGW_ATTR_ETAG].length()) - attrs[RGW_ATTR_ETAG] = attrset[RGW_ATTR_ETAG]; + RGWPutObjProcessor_Atomic processor(dest_obj.bucket, dest_obj.object, + cct->_conf->rgw_obj_stripe_size, tag); + ret = processor.prepare(this, ctx); + if (ret < 0) + return ret; - attrset = attrs; - } else { - /* copying attrs from source, however acls should not be copied */ - attrset[RGW_ATTR_ACL] = attrs[RGW_ATTR_ACL]; + RGWRESTConn *conn; + if (source_zone.empty()) { + conn = rest_master_conn; + } else { + map::iterator iter = zone_conn_map.find(source_zone); + if (iter == zone_conn_map.end()) { + ldout(cct, 0) << "could not find zone connection to zone: " << source_zone << dendl; + return -ENOENT; + } + conn = iter->second; + } + + string obj_name = dest_obj.bucket.name + "/" + dest_obj.object; + + RGWOpStateSingleOp opstate(this, client_id, op_id, obj_name); + + int ret = opstate.set_state(RGWOpState::OPSTATE_IN_PROGRESS); + if (ret < 0) { + ldout(cct, 0) << "ERROR: failed to set opstate ret=" << ret << dendl; + return ret; + } + RGWRadosPutObj cb(&processor, &opstate); + string etag; + map req_headers; + time_t set_mtime; + + ret = conn->get_obj(user_id, info, src_obj, true, &cb, &in_stream_req); + if (ret < 0) + goto set_err_state; + + ret = conn->complete_request(in_stream_req, etag, &set_mtime, req_headers); + if (ret < 0) + goto set_err_state; + + { /* opening scope so that we can do goto, sorry */ + bufferlist& extra_data_bl = processor.get_extra_data(); + if (extra_data_bl.length()) { + JSONParser jp; + if (!jp.parse(extra_data_bl.c_str(), extra_data_bl.length())) { + ldout(cct, 0) << "failed to parse response extra data. len=" << extra_data_bl.length() << " data=" << extra_data_bl.c_str() << dendl; + goto set_err_state; + } + + JSONDecoder::decode_json("attrs", src_attrs, &jp); + + src_attrs.erase(RGW_ATTR_MANIFEST); // not interested in original object layout + } + } + + set_copy_attrs(src_attrs, attrs, replace_attrs, !source_zone.empty()); + + ret = cb.complete(etag, mtime, set_mtime, src_attrs); + if (ret < 0) + goto set_err_state; + + ret = opstate.set_state(RGWOpState::OPSTATE_COMPLETE); + if (ret < 0) { + ldout(cct, 0) << "ERROR: failed to set opstate ret=" << ret << dendl; + } + + return 0; +set_err_state: + int r = opstate.set_state(RGWOpState::OPSTATE_ERROR); + if (r < 0) { + ldout(cct, 0) << "ERROR: failed to set opstate r=" << ret << dendl; + } + return ret; } - - attrset.erase(RGW_ATTR_ID_TAG); + set_copy_attrs(src_attrs, attrs, replace_attrs, false); ++ src_attrs.erase(RGW_ATTR_ID_TAG); RGWObjManifest manifest; RGWObjState *astate = NULL; @@@ -3917,33 -2702,27 +3920,32 @@@ int RGWRados::get_obj(void *ctx, RGWObj r = append_atomic_test(rctx, read_obj, op, &astate); if (r < 0) goto done_ret; - } - if (objv_tracker) { - objv_tracker->prepare_op_for_read(&op); - } + if (astate) { + if (!ofs && astate->data.length() >= len) { + bl = astate->data; + goto done; + } - read_len = len; + if (ofs < astate->data.length()) { + unsigned copy_len = min((uint64_t)astate->data.length() - ofs, len); + astate->data.copy(ofs, copy_len, bl); + read_len -= copy_len; + read_ofs += copy_len; + if (!read_len) + goto done; - if (astate) { - if (!ofs && astate->data.length() >= len) { - bl = astate->data; - goto done; + merge_bl = true; + pbl = &read_bl; + } } + } - if (ofs < astate->data.length()) { - unsigned copy_len = min((uint64_t)astate->data.length(), len); - astate->data.copy(ofs, copy_len, bl); - read_len -= copy_len; - read_ofs += copy_len; - if (!read_len) - goto done; - - merge_bl = true; - pbl = &read_bl; - } ++ if (objv_tracker) { ++ objv_tracker->prepare_op_for_read(&op); + } + ++ ldout(cct, 20) << "rados->read obj-ofs=" << ofs << " read_ofs=" << read_ofs << " read_len=" << read_len << dendl; op.read(read_ofs, read_len, pbl, NULL); diff --cc src/rgw/rgw_rest.cc index 04223dd00ce4,a9fb136a4df9..623bb0b5e16a --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@@ -1119,10 -1208,10 +1144,10 @@@ RGWRESTMgr *RGWRESTMgr::get_resource_mg for (iter = resources_by_size.rbegin(); iter != resources_by_size.rend(); ++iter) { string& resource = iter->second; if (uri.compare(0, iter->first, resource) == 0 && - (resource.size() == iter->first || - resource[iter->first] == '/')) { + (uri.size() == iter->first || + uri[iter->first] == '/')) { string suffix = uri.substr(iter->first); - return resource_mgrs[resource]->get_resource_mgr(s, suffix); + return resource_mgrs[resource]->get_resource_mgr(s, suffix, out_uri); } } diff --cc src/rgw/rgw_tools.cc index 10f29df4b26f,20aa02292c8f..49894eae7ced --- a/src/rgw/rgw_tools.cc +++ b/src/rgw/rgw_tools.cc @@@ -34,19 -33,16 +34,19 @@@ int rgw_put_system_obj(RGWRados *rgwsto return ret; } -int rgw_get_obj(RGWRados *rgwstore, void *ctx, rgw_bucket& bucket, string& key, bufferlist& bl, map *pattrs) +int rgw_get_system_obj(RGWRados *rgwstore, void *ctx, rgw_bucket& bucket, const string& key, bufferlist& bl, + RGWObjVersionTracker *objv_tracker, time_t *pmtime, map *pattrs) { - int ret; struct rgw_err err; void *handle = NULL; bufferlist::iterator iter; int request_len = READ_CHUNK_LEN; rgw_obj obj(bucket, key); + do { - ret = rgwstore->prepare_get_obj(ctx, obj, NULL, NULL, pattrs, NULL, - NULL, pmtime, NULL, NULL, NULL, NULL, objv_tracker, &handle, &err); + int ret = rgwstore->prepare_get_obj(ctx, obj, NULL, NULL, pattrs, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, &handle, &err); ++ NULL, pmtime, NULL, NULL, NULL, NULL, ++ objv_tracker, &handle, &err); if (ret < 0) return ret; diff --cc src/rgw/rgw_user.cc index 8cb28a2b3147,781fce46eda8..391c61d854cd --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@@ -1675,8 -1640,10 +1677,11 @@@ int RGWUser::execute_add(RGWUserAdminOp user_info.max_buckets = op_state.get_max_buckets(); user_info.suspended = op_state.get_suspension_status(); + user_info.system = op_state.system; + if (op_state.op_mask_specified) + user_info.op_mask = op_state.get_op_mask(); + // update the request op_state.set_user_info(user_info); op_state.set_populated(); @@@ -1873,9 -1840,9 +1878,12 @@@ int RGWUser::execute_modify(RGWUserAdmi if (op_state.max_buckets_specified) user_info.max_buckets = max_buckets; + if (op_state.system_specified) + user_info.system = op_state.system; + + if (op_state.op_mask_specified) + user_info.op_mask = op_state.get_op_mask(); + if (op_state.has_suspension_op()) { __u8 suspended = op_state.get_suspension_status(); user_info.suspended = suspended; diff --cc src/rgw/rgw_user.h index 5051b9abca49,42e6097dddfc..32bcf199001c --- a/src/rgw/rgw_user.h +++ b/src/rgw/rgw_user.h @@@ -127,9 -138,8 +127,10 @@@ struct RGWUserAdminOpState std::string display_name; uint32_t max_buckets; __u8 suspended; + __u8 system; std::string caps; + RGWObjVersionTracker objv; + uint32_t op_mask; // subuser attributes std::string subuser; @@@ -158,9 -168,9 +159,10 @@@ bool user_email_specified; bool max_buckets_specified; bool perm_specified; + bool op_mask_specified; bool caps_specified; bool suspension_op; + bool system_specified; bool key_op; // req parameters @@@ -366,7 -378,7 +374,8 @@@ key_type = -1; perm_mask = 0; suspended = 0; + system = 0; + op_mask = 0; existing_user = false; existing_key = false;