Skip to content

Commit b1e7c06

Browse files
committed
rgw/logging: retry attribuite set in case of race
Signed-off-by: Yuval Lifshitz <[email protected]>
1 parent b7174ca commit b1e7c06

File tree

1 file changed

+56
-45
lines changed

1 file changed

+56
-45
lines changed

src/rgw/rgw_rest_bucket_logging.cc

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -167,61 +167,72 @@ class RGWPutBucketLoggingOp : public RGWDefaultResponseOp {
167167
return;
168168
}
169169

170-
auto& attrs = src_bucket->get_attrs();
171170
if (!configuration.enabled) {
172-
if (auto iter = attrs.find(RGW_ATTR_BUCKET_LOGGING); iter != attrs.end()) {
173-
attrs.erase(iter);
174-
}
175-
} else {
176-
std::string target_bucket_name;
177-
std::string target_tenant_name;
178-
op_ret = rgw_parse_url_bucket(configuration.target_bucket, s->bucket_tenant, target_tenant_name, target_bucket_name);
179-
if (op_ret < 0) {
180-
ldpp_dout(this, 1) << "ERROR: failed to parse target bucket '" << configuration.target_bucket << "', ret = " << op_ret << dendl;
181-
return;
182-
}
183-
const rgw_bucket target_bucket_id(target_tenant_name, target_bucket_name);
184-
if (target_bucket_id == src_bucket_id) {
185-
ldpp_dout(this, 1) << "ERROR: target bucket '" << target_bucket_id << "' must be different from source bucket" << dendl;
186-
op_ret = -EINVAL;
187-
return;
188-
}
189-
std::unique_ptr<rgw::sal::Bucket> target_bucket;
190-
op_ret = driver->load_bucket(this, target_bucket_id,
191-
&target_bucket, y);
171+
// remove logging configuration
172+
op_ret = retry_raced_bucket_write(this, s->bucket.get(), [this, &src_bucket, y] {
173+
auto& attrs = src_bucket->get_attrs();
174+
if (auto iter = attrs.find(RGW_ATTR_BUCKET_LOGGING); iter != attrs.end()) {
175+
attrs.erase(iter);
176+
}
177+
return src_bucket->merge_and_store_attrs(this, attrs, y);
178+
}, y);
192179
if (op_ret < 0) {
193-
ldpp_dout(this, 1) << "ERROR: failed to get target bucket '" << target_bucket_id << "', ret = " << op_ret << dendl;
194-
return;
195-
}
196-
const auto& target_attrs = target_bucket->get_attrs();
197-
if (target_attrs.find(RGW_ATTR_BUCKET_LOGGING) != target_attrs.end()) {
198-
// target bucket must not have logging set on it
199-
ldpp_dout(this, 1) << "ERROR: logging target bucket '" << target_bucket_id << "', is configured with bucket logging" << dendl;
200-
op_ret = -EINVAL;
201-
return;
202-
}
203-
// verify target bucket does not have encryption
204-
if (target_attrs.find(RGW_ATTR_BUCKET_ENCRYPTION_POLICY) != target_attrs.end()) {
205-
ldpp_dout(this, 1) << "ERROR: logging target bucket '" << target_bucket_id << "', is configured with encryption" << dendl;
206-
op_ret = -EINVAL;
180+
ldpp_dout(this, 1) << "ERROR: failed to remove logging attribute '" << RGW_ATTR_BUCKET_LOGGING << "' from bucket '" <<
181+
src_bucket_id << "', ret = " << op_ret << dendl;
207182
return;
208183
}
209-
bufferlist conf_bl;
210-
encode(configuration, conf_bl);
211-
attrs[RGW_ATTR_BUCKET_LOGGING] = conf_bl;
212-
// TODO: should we add attribute to target bucket indicating it is target to bucket logging?
213-
// if we do, how do we maintain it when bucket logging changes?
184+
ldpp_dout(this, 20) << "INFO: removed logging configuration from bucket '" << src_bucket_id << "'" << dendl;
185+
return;
214186
}
215-
// TODO: use retry_raced_bucket_write from rgw_op.cc
216-
op_ret = src_bucket->merge_and_store_attrs(this, attrs, y);
187+
188+
// set logging configuration
189+
std::string target_bucket_name;
190+
std::string target_tenant_name;
191+
op_ret = rgw_parse_url_bucket(configuration.target_bucket, s->bucket_tenant, target_tenant_name, target_bucket_name);
192+
if (op_ret < 0) {
193+
ldpp_dout(this, 1) << "ERROR: failed to parse target bucket '" << configuration.target_bucket << "', ret = " << op_ret << dendl;
194+
return;
195+
}
196+
const rgw_bucket target_bucket_id(target_tenant_name, target_bucket_name);
197+
if (target_bucket_id == src_bucket_id) {
198+
ldpp_dout(this, 1) << "ERROR: target bucket '" << target_bucket_id << "' must be different from source bucket" << dendl;
199+
op_ret = -EINVAL;
200+
return;
201+
}
202+
std::unique_ptr<rgw::sal::Bucket> target_bucket;
203+
op_ret = driver->load_bucket(this, target_bucket_id,
204+
&target_bucket, y);
205+
if (op_ret < 0) {
206+
ldpp_dout(this, 1) << "ERROR: failed to get target bucket '" << target_bucket_id << "', ret = " << op_ret << dendl;
207+
return;
208+
}
209+
const auto& target_attrs = target_bucket->get_attrs();
210+
if (target_attrs.find(RGW_ATTR_BUCKET_LOGGING) != target_attrs.end()) {
211+
// target bucket must not have logging set on it
212+
ldpp_dout(this, 1) << "ERROR: logging target bucket '" << target_bucket_id << "', is configured with bucket logging" << dendl;
213+
op_ret = -EINVAL;
214+
return;
215+
}
216+
// verify target bucket does not have encryption
217+
if (target_attrs.find(RGW_ATTR_BUCKET_ENCRYPTION_POLICY) != target_attrs.end()) {
218+
ldpp_dout(this, 1) << "ERROR: logging target bucket '" << target_bucket_id << "', is configured with encryption" << dendl;
219+
op_ret = -EINVAL;
220+
return;
221+
}
222+
bufferlist conf_bl;
223+
encode(configuration, conf_bl);
224+
op_ret = retry_raced_bucket_write(this, src_bucket.get(), [this, &conf_bl, &src_bucket, y] {
225+
auto& attrs = src_bucket->get_attrs();
226+
attrs[RGW_ATTR_BUCKET_LOGGING] = conf_bl;
227+
return src_bucket->merge_and_store_attrs(this, attrs, y);
228+
}, y);
217229
if (op_ret < 0) {
218230
ldpp_dout(this, 1) << "ERROR: failed to set logging attribute '" << RGW_ATTR_BUCKET_LOGGING << "' to bucket '" <<
219-
src_bucket->get_name() << "', ret = " << op_ret << dendl;
231+
src_bucket_id << "', ret = " << op_ret << dendl;
220232
return;
221233
}
222234

223-
ldpp_dout(this, 20) << "INFO: " << (configuration.enabled ? "wrote" : "removed")
224-
<< " logging configuration. bucket '" << src_bucket_id << "'. configuration: " <<
235+
ldpp_dout(this, 20) << "INFO: wrote logging configuration to bucket '" << src_bucket_id << "'. configuration: " <<
225236
configuration.to_json_str() << dendl;
226237
}
227238
};

0 commit comments

Comments
 (0)