diff --git a/src/ceph.in b/src/ceph.in index 144704ee05bdb..fe369f824679e 100755 --- a/src/ceph.in +++ b/src/ceph.in @@ -691,26 +691,34 @@ def main(): childargs.extend(['--format', parsed_args.output_format]) ret, outbuf, outs = send_command(cluster_handle, target, childargs, inbuf) - elif ret: - if ret < 0: - outs = 'problem getting command descriptions from {0}.{1}'.format(*target) - else: - sigdict = parse_json_funcsigs(outbuf, 'cli') - if parsed_args.completion: - return complete(sigdict, childargs, target) + if ret == -errno.EINVAL: + # did we race with a mon upgrade? try again! + ret, outbuf, outs = json_command(cluster_handle, target=target, + prefix='get_command_descriptions') + if ret == 0: + compat = False # yep, carry on + if not compat: + if ret: + if ret < 0: + outs = 'problem getting command descriptions from {0}.{1}'.format(*target) + else: + sigdict = parse_json_funcsigs(outbuf, 'cli') - ret, outbuf, outs = new_style_command(parsed_args, childargs, target, - sigdict, inbuf, verbose) + if parsed_args.completion: + return complete(sigdict, childargs, target) - # debug tool: send any successful command *again* to - # verify that it is idempotent. - if not ret and 'CEPH_CLI_TEST_DUP_COMMAND' in os.environ: ret, outbuf, outs = new_style_command(parsed_args, childargs, target, sigdict, inbuf, verbose) - if ret < 0: - ret = -ret - print >> sys.stderr, prefix + 'Second attempt of previously successful command failed with {0}: {1}'.format(errno.errorcode[ret], outs) + + # debug tool: send any successful command *again* to + # verify that it is idempotent. + if not ret and 'CEPH_CLI_TEST_DUP_COMMAND' in os.environ: + ret, outbuf, outs = new_style_command(parsed_args, childargs, target, + sigdict, inbuf, verbose) + if ret < 0: + ret = -ret + print >> sys.stderr, prefix + 'Second attempt of previously successful command failed with {0}: {1}'.format(errno.errorcode[ret], outs) if ret < 0: ret = -ret diff --git a/src/common/pick_address.cc b/src/common/pick_address.cc index ff036c613604e..f6853622ff9bb 100644 --- a/src/common/pick_address.cc +++ b/src/common/pick_address.cc @@ -50,15 +50,14 @@ static const struct sockaddr *find_ip_in_subnet_list(CephContext *cct, // observe this change struct Observer : public md_config_obs_t { - const char *conf_var; - Observer(const char *c) : conf_var(c) {} + const char *keys[2]; + Observer(const char *c) { + keys[0] = c; + keys[1] = NULL; + } const char** get_tracked_conf_keys() const { - static const char *foo[] = { - conf_var, - NULL - }; - return foo; + return (const char **)keys; } void handle_conf_change(const struct md_config_t *conf, const std::set &changed) { diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc index e8dd019af3a28..48b6a3cabf60f 100644 --- a/src/librados/RadosClient.cc +++ b/src/librados/RadosClient.cc @@ -229,7 +229,6 @@ void librados::RadosClient::shutdown() if (state == CONNECTED) { finisher.stop(); } - monclient.shutdown(); bool need_objecter = false; if (objecter && state == CONNECTED) { need_objecter = true; @@ -238,6 +237,7 @@ void librados::RadosClient::shutdown() state = DISCONNECTED; timer.shutdown(); // will drop+retake lock lock.Unlock(); + monclient.shutdown(); if (need_objecter) objecter->shutdown_unlocked(); if (messenger) { diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 8e4126de27188..8baee258d9059 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -127,6 +127,7 @@ using ceph::crypto::MD5; #define ERR_TOO_SMALL 2022 #define ERR_NOT_FOUND 2023 #define ERR_PERMANENT_REDIRECT 2024 +#define ERR_LOCKED 2025 #define ERR_USER_SUSPENDED 2100 #define ERR_INTERNAL_ERROR 2200 diff --git a/src/rgw/rgw_http_client.h b/src/rgw/rgw_http_client.h index cc69383b62de4..3c0040424a41c 100644 --- a/src/rgw/rgw_http_client.h +++ b/src/rgw/rgw_http_client.h @@ -21,9 +21,9 @@ class RGWHTTPClient headers.push_back(pair(name, val)); } - virtual int receive_header(void *ptr, size_t len) { return 0; } - virtual int receive_data(void *ptr, size_t len) { return 0; } - virtual int send_data(void *ptr, size_t len) { return 0; } + virtual int receive_header(void *ptr, size_t len) = 0; + virtual int receive_data(void *ptr, size_t len) = 0; + virtual int send_data(void *ptr, size_t len) = 0; void set_send_length(size_t len) { send_len = len; diff --git a/src/rgw/rgw_http_errors.h b/src/rgw/rgw_http_errors.h index 1eb4e12e695cf..6cb9fabf6c0e0 100644 --- a/src/rgw/rgw_http_errors.h +++ b/src/rgw/rgw_http_errors.h @@ -47,6 +47,7 @@ const static struct rgw_http_errors RGW_HTTP_ERRORS[] = { { ERR_PRECONDITION_FAILED, 412, "PreconditionFailed" }, { ERANGE, 416, "InvalidRange" }, { ERR_UNPROCESSABLE_ENTITY, 422, "UnprocessableEntity" }, + { ERR_LOCKED, 423, "Locked" }, { ERR_INTERNAL_ERROR, 500, "InternalError" }, }; diff --git a/src/rgw/rgw_rest_log.cc b/src/rgw/rgw_rest_log.cc index 7b50986cb374b..74e3c445ee935 100644 --- a/src/rgw/rgw_rest_log.cc +++ b/src/rgw/rgw_rest_log.cc @@ -228,6 +228,8 @@ void RGWOp_MDLog_Lock::execute() { } utime_t time(dur, 0); http_ret = meta_log->lock_exclusive(shard_id, time, zone_id, locker_id); + if (http_ret == -EBUSY) + http_ret = -ERR_LOCKED; } void RGWOp_MDLog_Unlock::execute() { @@ -577,6 +579,8 @@ void RGWOp_DATALog_Lock::execute() { } utime_t time(dur, 0); http_ret = store->data_log->lock_exclusive(shard_id, time, zone_id, locker_id); + if (http_ret == -EBUSY) + http_ret = -ERR_LOCKED; } void RGWOp_DATALog_Unlock::execute() { diff --git a/src/rgw/rgw_rest_metadata.cc b/src/rgw/rgw_rest_metadata.cc index de33df17446a9..fc1d6ded1669c 100644 --- a/src/rgw/rgw_rest_metadata.cc +++ b/src/rgw/rgw_rest_metadata.cc @@ -242,6 +242,8 @@ void RGWOp_Metadata_Lock::execute() { } utime_t time(dur, 0); http_ret = store->meta_mgr->lock_exclusive(metadata_key, time, lock_id); + if (http_ret == -EBUSY) + http_ret = -ERR_LOCKED; } void RGWOp_Metadata_Unlock::execute() { diff --git a/src/rgw/rgw_swift.cc b/src/rgw/rgw_swift.cc index 9be9757e5f89a..b62033b2764e3 100644 --- a/src/rgw/rgw_swift.cc +++ b/src/rgw/rgw_swift.cc @@ -28,12 +28,18 @@ class RGWValidateSwiftToken : public RGWHTTPClient { public: RGWValidateSwiftToken(CephContext *_cct, struct rgw_swift_auth_info *_info) : RGWHTTPClient(_cct), info(_info) {} - int read_header(void *ptr, size_t len); + int receive_header(void *ptr, size_t len); + int receive_data(void *ptr, size_t len) { + return 0; + } + int send_data(void *ptr, size_t len) { + return 0; + } friend class RGWKeystoneTokenCache; }; -int RGWValidateSwiftToken::read_header(void *ptr, size_t len) +int RGWValidateSwiftToken::receive_header(void *ptr, size_t len) { char line[len + 1]; @@ -291,10 +297,17 @@ class RGWValidateKeystoneToken : public RGWHTTPClient { public: RGWValidateKeystoneToken(CephContext *_cct, bufferlist *_bl) : RGWHTTPClient(_cct), bl(_bl) {} - int read_data(void *ptr, size_t len) { + int receive_data(void *ptr, size_t len) { bl->append((char *)ptr, len); return 0; } + int receive_header(void *ptr, size_t len) { + return 0; + } + int send_data(void *ptr, size_t len) { + return 0; + } + }; static RGWKeystoneTokenCache *keystone_token_cache = NULL; @@ -304,10 +317,16 @@ class RGWGetRevokedTokens : public RGWHTTPClient { public: RGWGetRevokedTokens(CephContext *_cct, bufferlist *_bl) : RGWHTTPClient(_cct), bl(_bl) {} - int read_data(void *ptr, size_t len) { + int receive_data(void *ptr, size_t len) { bl->append((char *)ptr, len); return 0; } + int receive_header(void *ptr, size_t len) { + return 0; + } + int send_data(void *ptr, size_t len) { + return 0; + } }; static int open_cms_envelope(CephContext *cct, string& src, string& dst)