Skip to content

Commit 0359613

Browse files
authored
Merge pull request ceph#55162 from cfsnyder/wip-64014-cfsnyder-pacific
rgw: fix issue with concurrent versioned deletes leaving behind olh entries Reviewed-by: J. Eric Ivancich <[email protected]>
2 parents 868a8eb + 66ac828 commit 0359613

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

qa/workunits/rgw/test_rgw_versioning.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import uuid
66
import botocore
77
import time
8+
import threading
89
from common import exec_cmd, create_user, boto_connect
910
from botocore.config import Config
1011

@@ -100,7 +101,33 @@ def main():
100101
exec_cmd('ceph config rm client rgw_debug_inject_set_olh_err')
101102
get_resp = bucket.Object(key).get()
102103
assert put_resp.e_tag == get_resp['ETag'], 'get did not return null version with correct etag'
103-
104+
105+
# TESTCASE 'verify that concurrent delete requests do not leave behind olh entries'
106+
log.debug('TEST: verify that concurrent delete requests do not leave behind olh entries\n')
107+
bucket.object_versions.all().delete()
108+
109+
key = 'concurrent-delete'
110+
# create a delete marker
111+
resp = bucket.Object(key).delete()
112+
version_id = resp['ResponseMetadata']['HTTPHeaders']['x-amz-version-id']
113+
try:
114+
exec_cmd('ceph config set client rgw_debug_inject_latency_bi_unlink 2')
115+
time.sleep(1)
116+
117+
def do_delete():
118+
connection.ObjectVersion(bucket.name, key, version_id).delete()
119+
120+
t2 = threading.Thread(target=do_delete)
121+
t2.start()
122+
do_delete()
123+
t2.join()
124+
finally:
125+
exec_cmd('ceph config rm client rgw_debug_inject_latency_bi_unlink')
126+
out = exec_cmd(f'radosgw-admin bucket check olh --bucket {bucket.name} --dump-keys')
127+
num_leftover_olh_entries = len(json.loads(out))
128+
assert num_leftover_olh_entries == 0, \
129+
'Found leftover olh entries after concurrent deletes'
130+
104131
# Clean up
105132
log.debug("Deleting bucket {}".format(BUCKET_NAME))
106133
bucket.object_versions.all().delete()

src/cls/rgw/cls_rgw.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,11 +1906,10 @@ static int rgw_bucket_unlink_instance(cls_method_context_t hctx, bufferlist *in,
19061906
BIOLHEntry olh(hctx, dest_key);
19071907

19081908
int ret = obj.init();
1909-
if (ret == -ENOENT) {
1910-
return 0; /* already removed */
1911-
}
19121909
if (ret < 0) {
1913-
CLS_LOG(0, "ERROR: obj.init() returned ret=%d", ret);
1910+
if (ret != -ENOENT) {
1911+
CLS_LOG(0, "ERROR: obj.init() returned ret=%d", ret);
1912+
}
19141913
return ret;
19151914
}
19161915

src/common/options/rgw.yaml.in

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,6 +2642,16 @@ options:
26422642
- rgw
26432643
- rgw
26442644
min: 30
2645+
- name: rgw_debug_inject_latency_bi_unlink
2646+
type: uint
2647+
level: dev
2648+
desc: Latency (in seconds) injected before rgw bucket index unlink op calls to simulate
2649+
queueing latency and validate behavior of simultaneuous delete requests which
2650+
target the same object.
2651+
default: 0
2652+
with_legacy: true
2653+
services:
2654+
- rgw
26452655
- name: rgw_debug_inject_set_olh_err
26462656
type: uint
26472657
level: dev

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8387,6 +8387,12 @@ int RGWRados::unlink_obj_instance(const DoutPrefixProvider *dpp, RGWObjectCtx& o
83878387
}
83888388

83898389
string olh_tag(state->olh_tag.c_str(), state->olh_tag.length());
8390+
8391+
if (cct->_conf->rgw_debug_inject_latency_bi_unlink) {
8392+
// simulates queue latency for unlink ops to validate behavior with
8393+
// concurrent delete requests for the same object version instance
8394+
std::this_thread::sleep_for(cct->_conf->rgw_debug_inject_latency_bi_unlink * std::chrono::seconds{1});
8395+
}
83908396

83918397
ret = bucket_index_unlink_instance(dpp, bucket_info, target_obj, op_tag, olh_tag, olh_epoch, y, zones_trace, log_op);
83928398
if (ret < 0) {

0 commit comments

Comments
 (0)