)]}'
{"id":"openstack%2Fcinder~1000102","triplet_id":"openstack%2Fcinder~master~I28a7a98d2d0bc1d7bba641ded8c84b240dad5e0d","project":"openstack/cinder","branch":"master","topic":"fix-num-dependent-backups-race","attention_set":{},"removed_from_attention_set":{"13425":{"account":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"last_update":"2026-08-07 14:45:51.000000000","reason":"\u003cGERRIT_ACCOUNT_13425\u003e replied on the change","reason_account":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"}},"4523":{"account":{"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"},"last_update":"2026-08-07 14:46:25.000000000","reason":"Change was abandoned"}},"hashtags":[],"change_id":"I28a7a98d2d0bc1d7bba641ded8c84b240dad5e0d","subject":"Fix lost update race on num_dependent_backups","status":"ABANDONED","created":"2026-08-07 14:15:19.000000000","updated":"2026-08-07 14:47:04.000000000","total_comment_count":2,"unresolved_comment_count":0,"has_review_started":true,"meta_rev_id":"6c020839f10b17140526ed067310c21c728ef7ba","_number":1000102,"virtual_id_number":1000102,"owner":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"actions":{},"labels":{"Verified":{"all":[{"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"}],"values":{"-2":"Fails","-1":"Doesn\u0027t seem to work"," 0":"No score","+1":"Works for me","+2":"Verified"},"description":"","default_value":0,"optional":true},"Code-Review":{"disliked":{"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"},"all":[{"value":-1,"date":"2026-08-07 14:24:08.000000000","permitted_voting_range":{"min":-2,"max":2},"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"}],"values":{"-2":"Do not merge","-1":"This patch needs further work before it can be merged"," 0":"No score","+1":"Looks good to me, but someone else must approve","+2":"Looks good to me (core reviewer)"},"description":"","value":-1,"default_value":0,"optional":true},"Workflow":{"all":[{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"}],"values":{"-1":"Work in progress"," 0":"Ready for reviews","+1":"Approved"},"description":"","default_value":0,"optional":true},"Review-Priority":{"all":[{"value":0,"permitted_voting_range":{"min":-1,"max":2},"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"}],"values":{"-1":"Branch Freeze"," 0":"No Priority","+1":"Important Change","+2":"Gate Blocker Fix / Urgent Change"},"description":"","default_value":0,"optional":true}},"removable_reviewers":[],"reviewers":{"REVIEWER":[{"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"}],"CC":[{"_account_id":14384,"name":"Quobyte CI","email":"openstack-ci-external@quobyte.com","username":"quobyteci","tags":["SERVICE_USER"]},{"_account_id":33746,"name":"YADRO TATLIN CI","email":"tatlin_ci@yadro.com","username":"tatlin-ci"}]},"pending_reviewers":{},"reviewer_updates":[{"updated":"2026-08-07 14:23:56.000000000","updated_by":{"_account_id":33746,"name":"YADRO TATLIN CI","email":"tatlin_ci@yadro.com","username":"tatlin-ci"},"reviewer":{"_account_id":33746,"name":"YADRO TATLIN CI","email":"tatlin_ci@yadro.com","username":"tatlin-ci"},"state":"CC"},{"updated":"2026-08-07 14:24:08.000000000","updated_by":{"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"},"reviewer":{"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"},"state":"REVIEWER"},{"updated":"2026-08-07 14:47:04.000000000","updated_by":{"_account_id":14384,"name":"Quobyte CI","email":"openstack-ci-external@quobyte.com","username":"quobyteci","tags":["SERVICE_USER"]},"reviewer":{"_account_id":14384,"name":"Quobyte CI","email":"openstack-ci-external@quobyte.com","username":"quobyteci","tags":["SERVICE_USER"]},"state":"CC"}],"messages":[{"id":"42faff8b65b9c8f665a5541ca09d4af4e4834916","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"date":"2026-08-07 14:15:19.000000000","message":"Uploaded patch set 1.","accounts_in_message":[],"_revision_number":1},{"id":"6b137d506ca094a9f709afd50c314e4c610c025f","author":{"_account_id":33746,"name":"YADRO TATLIN CI","email":"tatlin_ci@yadro.com","username":"tatlin-ci"},"date":"2026-08-07 14:23:56.000000000","message":"Patch Set 1:\n\nBuild failed (iSCSI).\nLogs: http://tempest-openstack.spb.yadro.com/openstack-gerrit-trigger-iscsi/5057/.","accounts_in_message":[],"_revision_number":1},{"id":"4e5c5e1cd0b4c23c9add5c8a290e21bfb314d5f3","author":{"_account_id":4523,"name":"Eric Harney","email":"eharney@redhat.com","username":"eharney"},"date":"2026-08-07 14:24:08.000000000","message":"Patch Set 1: Code-Review-1\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"5a3c8c2a0f59d3319036b1099a8a1b479d452825","author":{"_account_id":33746,"name":"YADRO TATLIN CI","email":"tatlin_ci@yadro.com","username":"tatlin-ci"},"date":"2026-08-07 14:29:09.000000000","message":"Patch Set 1:\n\nBuild failed (FC).\nLogs: http://tempest-openstack.spb.yadro.com/openstack-gerrit-trigger-fc/4881/.","accounts_in_message":[],"_revision_number":1},{"id":"08b3ab138808e4e441b9bfaa5569afb9ade0fd36","author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"date":"2026-08-07 14:45:51.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"80a95e51c8934f1f414c86c7a72a108d987c18d6","tag":"autogenerated:gerrit:abandon","author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"date":"2026-08-07 14:46:25.000000000","message":"Abandoned\n\nAlready covered by https://review.opendev.org/c/openstack/cinder/+/1000097","accounts_in_message":[],"_revision_number":1},{"id":"6c020839f10b17140526ed067310c21c728ef7ba","author":{"_account_id":14384,"name":"Quobyte CI","email":"openstack-ci-external@quobyte.com","username":"quobyteci","tags":["SERVICE_USER"]},"date":"2026-08-07 14:47:04.000000000","message":"Patch Set 1:\n\nBuild Failed \n\n* quobyteci:  cinder_quobyteci : FAILURE, logs at: https://oscilogs.quobyte.com/logs/I28a7a98d2d0bc1d7bba641ded8c84b240dad5e0d .","accounts_in_message":[],"_revision_number":1}],"current_revision_number":1,"current_revision":"d4068dfb61c95042d8251ca1b3a4798224146a2a","revisions":{"d4068dfb61c95042d8251ca1b3a4798224146a2a":{"kind":"REWORK","_number":1,"created":"2026-08-07 14:15:19.000000000","uploader":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"ref":"refs/changes/02/1000102/1","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/cinder","ref":"refs/changes/02/1000102/1","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/cinder refs/changes/02/1000102/1 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/cinder refs/changes/02/1000102/1 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/cinder refs/changes/02/1000102/1 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/cinder refs/changes/02/1000102/1"}}},"commit":{"parents":[{"commit":"c9291171cf1448ce5a887c513418772191f11123","subject":"Merge \"Storwize: stop tests spawning cinder-manage subprocesses\"","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/cinder/commit/c9291171cf1448ce5a887c513418772191f11123"}]}],"author":{"name":"Simon Dodsley","email":"simon@purestorage.com","date":"2026-08-07 13:58:47.000000000","tz":-240},"committer":{"name":"Simon Dodsley","email":"simon@purestorage.com","date":"2026-08-07 14:15:06.000000000","tz":-240},"subject":"Fix lost update race on num_dependent_backups","message":"Fix lost update race on num_dependent_backups\n\nSeveral incremental backups can share a single parent. Two incrementals\ntaken from the same snapshot both get the full backup as their parent,\nbecause a backup-from-snapshot carries data_timestamp \u003d\u003d snapshot\ncreated_at and the parent lookup requires data_timestamp \u003c that, which\nexcludes the first incremental from being the second one\u0027s parent.\n\nThe parent\u0027s num_dependent_backups counter was maintained as a\nread-modify-write cycle: load the parent object, adjust the integer in\nPython, save it back. cinder-backup runs these as concurrent\ngreenthreads, so two operations against the same parent can interleave\nbetween the read and the write and lose an update.\n\nA counter left too high never returns to zero, so has_dependent_backups\nstays true forever and the parent can never be deleted by anyone - it\nbecomes an orphaned backup consuming quota and object storage until an\noperator edits the database by hand. The same race on the create path\ncan leave the counter too low, allowing a parent to be deleted while\nchildren still depend on its data.\n\nDo the arithmetic in the database instead, in a single statement, so the\nnew value is computed from the stored value under the row lock. For a\ndecrement the statement also carries a \u003e\u003d 1 condition, which is the\natomic equivalent of the has_dependent_backups guard and keeps the\ncounter from going negative. coalesce covers rows written before the\ncolumn was maintained, which hold NULL. This also drops a SELECT from\neach path, since the parent no longer has to be loaded to be adjusted.\n\nA serial test cannot tell an atomic update from a read-modify-write\ncycle, so the regression tests assert that the emitted UPDATE computes\nthe new value from the column rather than from a value read beforehand.\n\nThis does not repair counters that have already drifted; a deployment\nthat has hit this will still have undeletable backups until those rows\nare corrected. Deriving has_dependent_backups from the child rows\ninstead of storing a counter would be self-healing, but the column is a\nversioned object field and appears in notification payloads, so that is\nleft as a follow-up.\n\nCloses-Bug: #2163047\nChange-Id: I28a7a98d2d0bc1d7bba641ded8c84b240dad5e0d\nSigned-off-by: Simon Dodsley \u003csimon@purestorage.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/cinder/commit/d4068dfb61c95042d8251ca1b3a4798224146a2a"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/cinder/commit/d4068dfb61c95042d8251ca1b3a4798224146a2a"}]},"branch":"refs/heads/master"}},"requirements":[],"submit_records":[],"submit_requirements":[{"name":"Verified","description":"Verified in gate by CI","status":"UNSATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Verified\u003dMAX AND -label:Verified\u003dMIN","fulfilled":false,"status":"FAIL","passing_atoms":[],"failing_atoms":["label:Verified\u003dMAX","label:Verified\u003dMIN"],"atom_explanations":{"label:Verified\u003dMAX":"","label:Verified\u003dMIN":""}}},{"name":"Code-Review","description":"Code reviewed by core reviewer","status":"UNSATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Code-Review\u003dMAX AND -label:Code-Review\u003dMIN","fulfilled":false,"status":"FAIL","passing_atoms":[],"failing_atoms":["label:Code-Review\u003dMAX","label:Code-Review\u003dMIN"],"atom_explanations":{"label:Code-Review\u003dMAX":"","label:Code-Review\u003dMIN":""}}},{"name":"Review-Priority","description":"Review priority","status":"SATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"-label:Review-Priority\u003dMIN","fulfilled":true,"status":"PASS","passing_atoms":[],"failing_atoms":["label:Review-Priority\u003dMIN"],"atom_explanations":{"label:Review-Priority\u003dMIN":""}}},{"name":"Workflow","description":"Approved for gate by core reviewer","status":"UNSATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Workflow\u003dMAX AND -label:Workflow\u003dMIN","fulfilled":false,"status":"FAIL","passing_atoms":[],"failing_atoms":["label:Workflow\u003dMAX","label:Workflow\u003dMIN"],"atom_explanations":{"label:Workflow\u003dMAX":"","label:Workflow\u003dMIN":""}}}]}
