)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"535693d48661ddfccc3d33d69a33483e34179ca9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"35774ce3_31705c61","updated":"2026-04-22 14:00:28.000000000","message":"Everpure are in the process of working on a similar feature which we were going to create a spec for. Happy to work with you on this.","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":36686,"name":"Inyong Hong","display_name":"hongp","email":"inyong.hong@samsung.com","username":"hong-p"},"change_message_id":"77e2cbd71b9ddef570b472f3c699ddc054337c90","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"b28f482f_f4ead4a3","updated":"2026-05-01 17:03:51.000000000","message":"Sorry for the late response, and thank you so much for the thorough review!\nYou mentioned similar work underway at Pure Storage — would you like\nto include Pure Storage FlashArray CBT support in this spec as well?\nHappy to collaborate if so.","commit_id":"ec7e8e6c0a859b6cbbbd7ae6745a947c34ff932e"}],"specs/2026.1/incremental-backup-cbt.rst":[{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"3ba1ee18041c53db830025303deb7e3531d48d22","unresolved":true,"context_lines":[{"line_number":86,"context_line":""},{"line_number":87,"context_line":"Volume drivers implement ``get_cbt_extents(volume, from_snapshot, to_snapshot)``"},{"line_number":88,"context_line":"using backend-native APIs. ``cinder/backup/manager.py`` detects this method on"},{"line_number":89,"context_line":"the volume driver and wraps ``volume_file`` with a lightweight wrapper that"},{"line_number":90,"context_line":"exposes ``get_cbt_extents()`` to the backup driver. ``chunkeddriver.py`` detects"},{"line_number":91,"context_line":"the presence of this method and uses it when available::"},{"line_number":92,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"7520efd6_63759579","line":89,"range":{"start_line":89,"start_character":49,"end_line":89,"end_character":70},"updated":"2026-04-22 13:37:38.000000000","message":"can you create a short pseudocode sketch of the wrapper class:\n* What other methods it exposes?\n* Does it wrap the raw file handle, or sit alongside?\n* How does chunkeddriver.py detect whether the wrapped volume_file has get_cbt_extents available (simple hasattr check? A protocol class?)\n* What is the lifetime of the wrapper — is it created per-backup-operation or per-volume?","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":36686,"name":"Inyong Hong","display_name":"hongp","email":"inyong.hong@samsung.com","username":"hong-p"},"change_message_id":"77e2cbd71b9ddef570b472f3c699ddc054337c90","unresolved":true,"context_lines":[{"line_number":86,"context_line":""},{"line_number":87,"context_line":"Volume drivers implement ``get_cbt_extents(volume, from_snapshot, to_snapshot)``"},{"line_number":88,"context_line":"using backend-native APIs. ``cinder/backup/manager.py`` detects this method on"},{"line_number":89,"context_line":"the volume driver and wraps ``volume_file`` with a lightweight wrapper that"},{"line_number":90,"context_line":"exposes ``get_cbt_extents()`` to the backup driver. ``chunkeddriver.py`` detects"},{"line_number":91,"context_line":"the presence of this method and uses it when available::"},{"line_number":92,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"bd3d3e91_0cb870fd","line":89,"range":{"start_line":89,"start_character":49,"end_line":89,"end_character":70},"in_reply_to":"7520efd6_63759579","updated":"2026-05-01 17:03:51.000000000","message":"Added detailed pseudocode for CBTVolumeFileWrapper, backup/manager.py\nwrapper creation, and chunkeddriver.py CBT detection. Also clarified\nthat snapshot creation and diff_iterate run in the same RBD session,\nfollowing the same pattern as CephBackupDriver._backup_rbd().","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"3ba1ee18041c53db830025303deb7e3531d48d22","unresolved":true,"context_lines":[{"line_number":107,"context_line":"provides ``offset``, ``length``, and ``exists`` (boolean: ``True`` \u003d data,"},{"line_number":108,"context_line":"``False`` \u003d zero block) for each changed extent."},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"**For NetApp ONTAP**:"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"NetApp SnapDiff API provides CBT capabilities, but integration requires"},{"line_number":113,"context_line":"cooperation from the NetApp volume driver to expose capabilities through"},{"line_number":114,"context_line":"``get_cbt_extents()``. The feasibility and scope of NetApp CBT integration will"},{"line_number":115,"context_line":"be evaluated separately."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"**Reference Point Management**:"},{"line_number":118,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"137903c8_611dc2d7","line":115,"range":{"start_line":110,"start_character":0,"end_line":115,"end_character":24},"updated":"2026-04-22 13:37:38.000000000","message":"Are you going to do this NetApp work? If not, I would not mention NetApp. If you aren\u0027t doing the work and still want to mention NetApp then you should also mention other vendors wit the same capabilities, such as the Everpure FlashArray.","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":36686,"name":"Inyong Hong","display_name":"hongp","email":"inyong.hong@samsung.com","username":"hong-p"},"change_message_id":"77e2cbd71b9ddef570b472f3c699ddc054337c90","unresolved":true,"context_lines":[{"line_number":107,"context_line":"provides ``offset``, ``length``, and ``exists`` (boolean: ``True`` \u003d data,"},{"line_number":108,"context_line":"``False`` \u003d zero block) for each changed extent."},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"**For NetApp ONTAP**:"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"NetApp SnapDiff API provides CBT capabilities, but integration requires"},{"line_number":113,"context_line":"cooperation from the NetApp volume driver to expose capabilities through"},{"line_number":114,"context_line":"``get_cbt_extents()``. The feasibility and scope of NetApp CBT integration will"},{"line_number":115,"context_line":"be evaluated separately."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"**Reference Point Management**:"},{"line_number":118,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"2486bc1a_6ae93cd8","line":115,"range":{"start_line":110,"start_character":0,"end_line":115,"end_character":24},"in_reply_to":"137903c8_611dc2d7","updated":"2026-05-01 17:03:51.000000000","message":"Removed. checked that NetApp SnapDiff API only works with SnapMirror,\nnot general snapshot-based CBT. NetApp section has been dropped.","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"3ba1ee18041c53db830025303deb7e3531d48d22","unresolved":true,"context_lines":[{"line_number":160,"context_line":"        \"version\": \"1.0\","},{"line_number":161,"context_line":"        \"cbt_method\": \"\","},{"line_number":162,"context_line":"        \"cbt_backend\": \"ceph\","},{"line_number":163,"context_line":"        \"reference_point\": {"},{"line_number":164,"context_line":"            \"type\": \"rbd_snapshot\","},{"line_number":165,"context_line":"            \"snapshot_id\": \"backup.\u003cbackup_id\u003e.snap.\u003ctimestamp\u003e\""},{"line_number":166,"context_line":"        },"}],"source_content_type":"text/x-rst","patch_set":6,"id":"7b9ba4be_8eb070bf","line":163,"range":{"start_line":163,"start_character":9,"end_line":163,"end_character":24},"updated":"2026-04-22 13:37:38.000000000","message":"what is the lifecycle of this reference_point? who creates it and when, who deletes it and when, what happens is a snapshot deletion fails, what happens if the backup fails after the snapshot is created but before the metadata is written?\nYou should specify:\n* The reference point snapshot is created at the start of a backup operation and recorded in metadata on success\n* On the next incremental backup, after the new reference point is successfully recorded, the previous reference point snapshot is deleted\n* If backup fails after snapshot creation, the snapshot is cleaned up as part of the backup failure path\n* A periodic audit/cleanup mechanism should be noted as a follow-on work item for orphaned reference snapshots","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":36686,"name":"Inyong Hong","display_name":"hongp","email":"inyong.hong@samsung.com","username":"hong-p"},"change_message_id":"77e2cbd71b9ddef570b472f3c699ddc054337c90","unresolved":true,"context_lines":[{"line_number":160,"context_line":"        \"version\": \"1.0\","},{"line_number":161,"context_line":"        \"cbt_method\": \"\","},{"line_number":162,"context_line":"        \"cbt_backend\": \"ceph\","},{"line_number":163,"context_line":"        \"reference_point\": {"},{"line_number":164,"context_line":"            \"type\": \"rbd_snapshot\","},{"line_number":165,"context_line":"            \"snapshot_id\": \"backup.\u003cbackup_id\u003e.snap.\u003ctimestamp\u003e\""},{"line_number":166,"context_line":"        },"}],"source_content_type":"text/x-rst","patch_set":6,"id":"276ba4a3_dad4724d","line":163,"range":{"start_line":163,"start_character":9,"end_line":163,"end_character":24},"in_reply_to":"7b9ba4be_8eb070bf","updated":"2026-05-01 17:03:51.000000000","message":"Added full snapshot lifecycle documentation: creation inside\nget_cbt_extents(), retention via backup_ceph_max_snapshots (recommended\nvalue: 1), failure cleanup in except block, and crash recovery via\n_cleanup_temp_volumes_snapshots_for_one_backup(). Naming follows existing\nCeph-to-Ceph convention using _get_new_snap_name().","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"3ba1ee18041c53db830025303deb7e3531d48d22","unresolved":true,"context_lines":[{"line_number":184,"context_line":"* CBT API call fails"},{"line_number":185,"context_line":"* Inconsistent reference chain detected"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"In all cases, log the reason and proceed with standard full scan without user"},{"line_number":188,"context_line":"impact."},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"**Restore Compatibility**:"},{"line_number":191,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"97513bce_f8ceffdb","line":188,"range":{"start_line":187,"start_character":0,"end_line":188,"end_character":7},"updated":"2026-04-22 13:37:38.000000000","message":"what log level and what message content should be supplied here?","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":36686,"name":"Inyong Hong","display_name":"hongp","email":"inyong.hong@samsung.com","username":"hong-p"},"change_message_id":"77e2cbd71b9ddef570b472f3c699ddc054337c90","unresolved":true,"context_lines":[{"line_number":184,"context_line":"* CBT API call fails"},{"line_number":185,"context_line":"* Inconsistent reference chain detected"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"In all cases, log the reason and proceed with standard full scan without user"},{"line_number":188,"context_line":"impact."},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"**Restore Compatibility**:"},{"line_number":191,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"d02c3bef_9536e140","line":188,"range":{"start_line":187,"start_character":0,"end_line":188,"end_character":7},"in_reply_to":"97513bce_f8ceffdb","updated":"2026-05-01 17:03:51.000000000","message":"Added explicit log levels: LOG.info for CBT usage with extent stats,\nLOG.info for fallback cases with reason.","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"3ba1ee18041c53db830025303deb7e3531d48d22","unresolved":true,"context_lines":[{"line_number":189,"context_line":""},{"line_number":190,"context_line":"**Restore Compatibility**:"},{"line_number":191,"context_line":""},{"line_number":192,"context_line":"Restore operations work with both CBT-optimized and traditional backups."},{"line_number":193,"context_line":"Layer incremental changes on top of full backups regardless of whether CBT"},{"line_number":194,"context_line":"was used. CBT metadata is informational for performance analysis only."},{"line_number":195,"context_line":""},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"Data model impact"}],"source_content_type":"text/x-rst","patch_set":6,"id":"c074bf05_cda03465","line":194,"range":{"start_line":192,"start_character":0,"end_line":194,"end_character":70},"updated":"2026-04-22 13:37:38.000000000","message":"The changed_blocks array stored in cbt_metadata is not purely informational — it is the only record of which byte ranges were written during a CBT incremental backup. Without it, a restore of a CBT incremental has no way to know which extents to apply to the target volume or in what order.\nYou should add a Restore Path section covering chain reconstruction, extent ordering and integrity and cross-backend restore","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":36686,"name":"Inyong Hong","display_name":"hongp","email":"inyong.hong@samsung.com","username":"hong-p"},"change_message_id":"77e2cbd71b9ddef570b472f3c699ddc054337c90","unresolved":true,"context_lines":[{"line_number":189,"context_line":""},{"line_number":190,"context_line":"**Restore Compatibility**:"},{"line_number":191,"context_line":""},{"line_number":192,"context_line":"Restore operations work with both CBT-optimized and traditional backups."},{"line_number":193,"context_line":"Layer incremental changes on top of full backups regardless of whether CBT"},{"line_number":194,"context_line":"was used. CBT metadata is informational for performance analysis only."},{"line_number":195,"context_line":""},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"Data model impact"}],"source_content_type":"text/x-rst","patch_set":6,"id":"e070b114_5b0952c4","line":194,"range":{"start_line":192,"start_character":0,"end_line":194,"end_character":70},"in_reply_to":"c074bf05_cda03465","updated":"2026-05-01 17:03:51.000000000","message":"Added Restore Path section. CBT does not affect restore — the existing\nChunkedBackupDriver.restore() handles chain reconstruction via parent_id,\nordered application, MD5 integrity, and cross-backend restore using\nchunk offsets stored in backup storage. See inline comment for details.","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"3ba1ee18041c53db830025303deb7e3531d48d22","unresolved":true,"context_lines":[{"line_number":235,"context_line":"  ``false`` if known zero block"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"**Storage Location**:"},{"line_number":238,"context_line":"* Metadata is stored in the backup object\u0027s metadata field"},{"line_number":239,"context_line":"* Generated and stored by the backup driver during backup operations"},{"line_number":240,"context_line":"* Used by subsequent incremental backups to locate the reference point"},{"line_number":241,"context_line":"* Not required for restore operations"}],"source_content_type":"text/x-rst","patch_set":6,"id":"44b8d014_919a3212","line":238,"range":{"start_line":238,"start_character":2,"end_line":238,"end_character":58},"updated":"2026-04-22 13:37:38.000000000","message":"this is convenient, but can create a scale problem. For example, a 10 TB volume with 4 KB block granularity and 10% change rate, the changed block list could contain on the order of 250,000 entries. At approximately 80 bytes per JSON entry (offset, length, exists, plus a checksum if added), that is ~20 MB of JSON in a single backup metadata field. Most database backends have practical limits on field size well below this.\nSpecify either a maximum extent map size and define what happens when it is exceeded or note that the changed_blocks array should store consolidated extents — merging adjacent or near-adjacent changed regions into single entries — rather than raw block-level granularity from the backend API.\nI would add a note to the Data Model section specifying that adjacent extents should be consolidated by the driver before being stored, and document a recommended maximum for the changed_blocks array size (suggest 10,000 entries as a soft limit, with fallback to full scan if exceeded).","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":36686,"name":"Inyong Hong","display_name":"hongp","email":"inyong.hong@samsung.com","username":"hong-p"},"change_message_id":"77e2cbd71b9ddef570b472f3c699ddc054337c90","unresolved":true,"context_lines":[{"line_number":235,"context_line":"  ``false`` if known zero block"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"**Storage Location**:"},{"line_number":238,"context_line":"* Metadata is stored in the backup object\u0027s metadata field"},{"line_number":239,"context_line":"* Generated and stored by the backup driver during backup operations"},{"line_number":240,"context_line":"* Used by subsequent incremental backups to locate the reference point"},{"line_number":241,"context_line":"* Not required for restore operations"}],"source_content_type":"text/x-rst","patch_set":6,"id":"9a219ce1_b8673c50","line":238,"range":{"start_line":238,"start_character":2,"end_line":238,"end_character":58},"in_reply_to":"44b8d014_919a3212","updated":"2026-05-01 17:03:51.000000000","message":"Resolved by removing changed_blocks from backup metadata entirely.\nThe list is used only in memory during backup and discarded afterward.\nChunk objects already store offset/length, so no persistent storage needed.","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"3ba1ee18041c53db830025303deb7e3531d48d22","unresolved":true,"context_lines":[{"line_number":241,"context_line":"* Not required for restore operations"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"Performance Impact"},{"line_number":245,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"**Positive Impact**:"}],"source_content_type":"text/x-rst","patch_set":6,"id":"d7dc1c67_5c6bdb7c","line":244,"range":{"start_line":244,"start_character":0,"end_line":244,"end_character":18},"updated":"2026-04-22 13:37:38.000000000","message":"This whole section is pitched entirely at software-defined storage, eg. Ceph, but array-backed volumes may have near zero CBT query overhead, so mentioning this will add weight to this spec as a generic interface.","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":36686,"name":"Inyong Hong","display_name":"hongp","email":"inyong.hong@samsung.com","username":"hong-p"},"change_message_id":"77e2cbd71b9ddef570b472f3c699ddc054337c90","unresolved":true,"context_lines":[{"line_number":241,"context_line":"* Not required for restore operations"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"Performance Impact"},{"line_number":245,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"**Positive Impact**:"}],"source_content_type":"text/x-rst","patch_set":6,"id":"ebcf7de0_9305c756","line":244,"range":{"start_line":244,"start_character":0,"end_line":244,"end_character":18},"in_reply_to":"d7dc1c67_5c6bdb7c","updated":"2026-05-01 17:03:51.000000000","message":"Added note to Performance Impact: hardware storage arrays implement CBT\nin hardware, resulting in near-zero overhead compared to software-defined\nbackends.","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@purestorage.com","username":"sdodsley"},"change_message_id":"3ba1ee18041c53db830025303deb7e3531d48d22","unresolved":true,"context_lines":[{"line_number":365,"context_line":"  volume driver and wrap ``volume_file`` with a lightweight CBT-aware wrapper"},{"line_number":366,"context_line":"* Extend ``chunkeddriver.py`` with CBT support: ``_backup_with_cbt()``,"},{"line_number":367,"context_line":"  ``_get_cbt_reference_point()``, ``_save_cbt_metadata()``"},{"line_number":368,"context_line":"* Evaluate NetApp CBT integration feasibility with volume driver"},{"line_number":369,"context_line":"  cooperation (NetApp SnapDiff API may provide CBT capabilities but requires"},{"line_number":370,"context_line":"  volume driver cooperation)"},{"line_number":371,"context_line":"* Implement automatic fallback behavior"},{"line_number":372,"context_line":"* Unit tests for CBT detection and fallback"},{"line_number":373,"context_line":"* Unit tests for CBT API integration (mocked backends)"}],"source_content_type":"text/x-rst","patch_set":6,"id":"fa69d174_9e0ba80c","line":370,"range":{"start_line":368,"start_character":2,"end_line":370,"end_character":28},"updated":"2026-04-22 13:37:38.000000000","message":"see previous comment","commit_id":"166d8e420662bf818b141f8f743f81792ba05617"}]}
