)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"11cec3390b3d3e6a0db92a888f8faa1f02585bda","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":18,"id":"f7f022a5_424b161e","updated":"2026-08-21 15:32:36.000000000","message":"setting -w not ready for review","commit_id":"eef237dfe7ca10fe10de23978eab8642e09261d3"}],"cyborg/accelerator/drivers/nvme/driver.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d2b43ea978881969a0cf5a0774b1da18d55c826b","unresolved":false,"context_lines":[{"line_number":329,"context_line":"                if status_bits \u003d\u003d 0x1:"},{"line_number":330,"context_line":"                    return"},{"line_number":331,"context_line":"                if status_bits \u003d\u003d 0x3:"},{"line_number":332,"context_line":"                    raise RuntimeError(\u0027Sanitize failed: sstat\u003d%r\u0027 % sstat)"},{"line_number":333,"context_line":"            time.sleep(5)"},{"line_number":334,"context_line":"        raise RuntimeError("},{"line_number":335,"context_line":"            \u0027Sanitize on %s did not complete within %ds\u0027 % (nvme_dev, timeout)"}],"source_content_type":"text/x-python","patch_set":2,"id":"6fed2bb7_6c021bba","line":332,"updated":"2026-08-06 11:16:16.000000000","message":"The _poll_sanitize method raises bare RuntimeError for sanitize failure and timeout conditions instead of using cyborg.common.exception subclasses. This breaks the project convention where all operational errors are represented as CyborgException subclasses, preventing callers from handling clean...\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: Callers of NVMeDriver.cleanup() cannot distinguish sanitize failures from other errors using cyborg\u0027s exception hierarchy. Code that expects to catch CyborgException subclasses will not catch RuntimeError, potentially causing unhandled exceptions in the agent cleanup path.\n\n**Suggestion**:\nReplace RuntimeError with appropriate cyborg exception subclasses. For sanitize failure, create or use an existing exception such as a new DeviceCleanupFailed exception extending CyborgException. For timeout, consider using the existing exception patterns with appropriate msg_fmt.","commit_id":"acc375509fcdd0580d5567bd0d7b50e99997e509"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"b8b7819650e3e4dfb089cf9600ccfaf0e8ae56f0","unresolved":false,"context_lines":[{"line_number":358,"context_line":"            for nsid in range(1, nn + 1):"},{"line_number":359,"context_line":"                try:"},{"line_number":360,"context_line":"                    nvme_cli.nvme_delete_ns(nvme_dev, nsid)"},{"line_number":361,"context_line":"                except Exception:"},{"line_number":362,"context_line":"                    LOG.warning(\u0027Failed to delete ns %d on %s\u0027, nsid, nvme_dev)"},{"line_number":363,"context_line":"            tnvmcap \u003d id_ctrl.get(\u0027tnvmcap\u0027, 0)"},{"line_number":364,"context_line":"            nvme_cli.nvme_create_ns(nvme_dev, tnvmcap, tnvmcap)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9331047b_8700f889","line":361,"updated":"2026-08-06 15:24:59.000000000","message":"The _consolidate_namespaces method catches bare Exception around nvme_delete_ns, which violates the OpenStack Hacking/pep8 guidance against overly broad exception handling. The specific expected exception from nvme-cli operations is processutils.ProcessExecutionError.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: Swallowing all exceptions during namespace deletion can mask programming errors and leave the device in an inconsistent namespace state before creating a new namespace, potentially causing the subsequent create-ns to fail or the write-zeroes to target the wrong namespace.\n\n**Suggestion**:\nCatch processutils.ProcessExecutionError specifically instead of bare Exception, since nvme_delete_ns wraps nvme-cli via oslo.concurrency processutils.execute which raises ProcessExecutionError on non-zero exit.","commit_id":"c44643b594233cd41e5fbaeb3a6a8cd6322c8f66"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"b8b7819650e3e4dfb089cf9600ccfaf0e8ae56f0","unresolved":false,"context_lines":[{"line_number":361,"context_line":"                except Exception:"},{"line_number":362,"context_line":"                    LOG.warning(\u0027Failed to delete ns %d on %s\u0027, nsid, nvme_dev)"},{"line_number":363,"context_line":"            tnvmcap \u003d id_ctrl.get(\u0027tnvmcap\u0027, 0)"},{"line_number":364,"context_line":"            nvme_cli.nvme_create_ns(nvme_dev, tnvmcap, tnvmcap)"},{"line_number":365,"context_line":"            nvme_cli.nvme_ns_rescan(nvme_dev)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5c01820b_c02e606e","line":364,"updated":"2026-08-06 15:24:59.000000000","message":"In _consolidate_namespaces, the tnvmcap value from id-ctrl (total NVM capacity in bytes) is passed directly as both nsze and ncap to nvme_create_ns. The NVMe Create Namespace command expects nsze and ncap in logical blocks, not bytes, so the resulting namespace will be oversized by a factor of th...\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: On real NVMe hardware, creating a namespace with an nsze orders of magnitude larger than the physical capacity will either fail with an error or create an oversized namespace that may cause I/O errors or undefined behavior when the write-zeroes operation targets blocks beyond the physical medium.\n\n**Suggestion**:\nConvert tnvmcap from bytes to blocks by dividing by the logical block size from id-ns (typically obtained from lba format data). For example: nsze \u003d tnvmcap // lba_data_block_size. Alternatively, query the namespace capacity from the controller after consolidation.","commit_id":"c44643b594233cd41e5fbaeb3a6a8cd6322c8f66"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"79321cc9afabcbd235831a51d61863c8db46a93d","unresolved":false,"context_lines":[{"line_number":328,"context_line":""},{"line_number":329,"context_line":"            if sprog \u003d\u003d 0xFFFF:"},{"line_number":330,"context_line":"                status_bits \u003d self._parse_sstat(sstat)"},{"line_number":331,"context_line":"                if status_bits \u003d\u003d 0x1:"},{"line_number":332,"context_line":"                    return"},{"line_number":333,"context_line":"                if status_bits \u003d\u003d 0x3:"},{"line_number":334,"context_line":"                    raise exception.DeviceCleanupFailed("}],"source_content_type":"text/x-python","patch_set":5,"id":"b4c30d1c_97038682","line":331,"updated":"2026-08-07 07:26:06.000000000","message":"The _poll_sanitize method treats SSTAT status_bits \u003d\u003d 0x1 as sanitize completion, but the NVMe specification defines SSTAT.SSTAT value 001b as \u0027Sanitize In Progress\u0027. The correct completion values are 010b (2, Completed Successfully) and possibly 000b (0, never sanitized/already clean) and 101b (...\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: If SSTAT value 1 (in progress) is interpreted as completion, the poll may return before data is actually erased, leaving sensitive data on the device. Alternatively, when the sanitize truly completes (SSTAT\u003d2), the code will not recognize it and will continue polling until timeout, causing spurio...\n\n**Priority**: Before merge\n**Why This Matters**: If SSTAT value 1 (in progress) is interpreted as completion, the poll may return before data is actually erased, leaving sensitive data on the device. Alternatively, when the sanitize truly completes (SSTAT\u003d2), the code will not recognize it and will continue polling until timeout, causing spurio...\n\n**Recommendation**:\nChange the completion check to match NVMe spec values: treat status_bits in (0x0, 0x2, 0x5) as success (completed or already clean) and status_bits \u003d\u003d 0x3 as failure. Update the test mock data to use sstat\u003d0x2 for the success case.","commit_id":"b6c11c7dabee155d17bc2a0fd10bd4984ca61747"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"79321cc9afabcbd235831a51d61863c8db46a93d","unresolved":false,"context_lines":[{"line_number":345,"context_line":"            self._consolidate_namespaces(nvme_dev)"},{"line_number":346,"context_line":"        ns_dev \u003d nvme_dev + \u0027n1\u0027"},{"line_number":347,"context_line":"        id_ns \u003d nvme_cli.nvme_id_ns(ns_dev)"},{"line_number":348,"context_line":"        nsze \u003d id_ns.get(\u0027nsze\u0027, 0)"},{"line_number":349,"context_line":"        nvme_cli.nvme_write_zeroes(ns_dev, 1, 0, nsze - 1)"},{"line_number":350,"context_line":""},{"line_number":351,"context_line":"    def _do_shred(self, nvme_dev, ns_mgmt):"}],"source_content_type":"text/x-python","patch_set":5,"id":"98f62e1a_12eda317","line":348,"updated":"2026-08-07 07:26:06.000000000","message":"The _do_write_zeroes method computes block_count as nsze - 1, where nsze defaults to 0 via id_ns.get(\u0027nsze\u0027, 0). If the namespace reports nsze\u003d0 or the key is absent from id-ns JSON output, block_count becomes -1, which is passed to the nvme write-zeroes command as a negative count.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: A negative block_count will cause the nvme write-zeroes command to fail or produce undefined behavior. The error propagates as a raw ProcessExecutionError rather than a typed DeviceCleanupFailed exception.\n\n**Suggestion**:\nAdd a guard: if nsze \u003c\u003d 0, raise exception.DeviceCleanupFailed with a descriptive reason. Alternatively, skip write-zeroes and fall back to shred if the namespace size is invalid.","commit_id":"b6c11c7dabee155d17bc2a0fd10bd4984ca61747"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"79321cc9afabcbd235831a51d61863c8db46a93d","unresolved":false,"context_lines":[{"line_number":346,"context_line":"        ns_dev \u003d nvme_dev + \u0027n1\u0027"},{"line_number":347,"context_line":"        id_ns \u003d nvme_cli.nvme_id_ns(ns_dev)"},{"line_number":348,"context_line":"        nsze \u003d id_ns.get(\u0027nsze\u0027, 0)"},{"line_number":349,"context_line":"        nvme_cli.nvme_write_zeroes(ns_dev, 1, 0, nsze - 1)"},{"line_number":350,"context_line":""},{"line_number":351,"context_line":"    def _do_shred(self, nvme_dev, ns_mgmt):"},{"line_number":352,"context_line":"        if ns_mgmt:"}],"source_content_type":"text/x-python","patch_set":5,"id":"e2f8df62_af78233d","line":349,"updated":"2026-08-07 07:26:06.000000000","message":"The _do_write_zeroes method issues a single nvme write-zeroes command covering nsze-1 blocks. The NVMe Write Zeroes command\u0027s NLB (Number of Logical Blocks) field is 16-bit, limiting each command to at most 65536 blocks. Real-world NVMe namespaces have millions of blocks, so a single call cannot...\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: For any real-world NVMe namespace, the write-zeroes path will either fail with an error from the controller/driver (causing cleanup failure with an unhelpful ProcessExecutionError rather than DeviceCleanupFailed) or silently truncate, leaving data un-erased on a device that is supposed to be secu...\n\n**Priority**: Before merge\n**Why This Matters**: For any real-world NVMe namespace, the write-zeroes path will either fail with an error from the controller/driver (causing cleanup failure with an unhelpful ProcessExecutionError rather than DeviceCleanupFailed) or silently truncate, leaving data un-erased on a device that is supposed to be secu...\n\n**Recommendation**:\nLoop over the namespace in chunks of at most 65536 blocks, issuing a separate write-zeroes command per chunk. Track the current LBA offset and remaining block count across iterations.","commit_id":"b6c11c7dabee155d17bc2a0fd10bd4984ca61747"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ee6dc4b448a5767d16f47dd4b0896bf8493b40fc","unresolved":false,"context_lines":[{"line_number":419,"context_line":"            ns_dev \u003d \u0027%sn%d\u0027 % (nvme_dev, nsid)"},{"line_number":420,"context_line":"        id_ns \u003d nvme_cli.nvme_id_ns(ns_dev)"},{"line_number":421,"context_line":"        namespace_size \u003d id_ns.get(\u0027nsze\u0027, 0)"},{"line_number":422,"context_line":"        nvme_cli.nvme_write_zeroes(ns_dev, 1, 0, namespace_size - 1)"},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"    def _do_shred(self, nvme_dev, ns_mgmt):"},{"line_number":425,"context_line":"        if ns_mgmt:"}],"source_content_type":"text/x-python","patch_set":7,"id":"cf32aa1b_bd9ce043","line":422,"updated":"2026-08-09 05:33:45.000000000","message":"_do_write_zeroes always passes 1 as the namespace_id argument to nvme_write_zeroes, regardless of which namespace was actually resolved. In the ns_mgmt\u003dFalse path the correct nsid is already available from nvme_list_ns but is not used. In the ns_mgmt\u003dTrue path _consolidate_namespaces returns a de...\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Risk**: On devices whose first active namespace has an NSID other than 1, the write-zeroes command targets the wrong namespace or fails. This results in incomplete or incorrect device sanitization during cleanup, leaving data on the wrong namespace.\n\n**Priority**: Before merge\n**Why This Matters**: On devices whose first active namespace has an NSID other than 1, the write-zeroes command targets the wrong namespace or fails. This results in incomplete or incorrect device sanitization during cleanup, leaving data on the wrong namespace.\n\n**Recommendation**:\nPass the actual NSID to nvme_write_zeroes. In the ns_mgmt\u003dFalse path use the already-computed nsid. In the ns_mgmt\u003dTrue path, have _consolidate_namespaces return both the device path and the NSID, or extract the NSID from the returned path.","commit_id":"e5a7877ab9432515f4b22721a94b5af374abf44f"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ee6dc4b448a5767d16f47dd4b0896bf8493b40fc","unresolved":false,"context_lines":[{"line_number":458,"context_line":"            except Exception:"},{"line_number":459,"context_line":"                LOG.warning(\u0027Failed to delete ns %d on %s\u0027, nsid, nvme_dev)"},{"line_number":460,"context_line":""},{"line_number":461,"context_line":"        nvme_cli.nvme_create_ns("},{"line_number":462,"context_line":"            nvme_dev, lba_count, lba_count, active_lba_format \u0026 0xF"},{"line_number":463,"context_line":"        )"},{"line_number":464,"context_line":"        nvme_cli.nvme_ns_rescan(nvme_dev)"}],"source_content_type":"text/x-python","patch_set":7,"id":"e99f77bf_54398f02","line":461,"updated":"2026-08-09 05:33:45.000000000","message":"_consolidate_namespaces calls nvme_create_ns (which invokes \u0027nvme create-ns\u0027) but never calls \u0027nvme attach-ns\u0027 to attach the newly created namespace to a controller. In the NVMe specification, a created namespace must be attached before it is active and usable. nvme_list_ns (nvme list-ns) returns...\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: On any controller that does not auto-attach newly created namespaces (the standard behavior per NVMe spec), _consolidate_namespaces will create a namespace that cannot be found by nvme_list_ns, raising DeviceNotFound and aborting the write-zeroes or shred cleanup path. The cleanup operation fails...\n\n**Priority**: Before merge\n**Why This Matters**: On any controller that does not auto-attach newly created namespaces (the standard behavior per NVMe spec), _consolidate_namespaces will create a namespace that cannot be found by nvme_list_ns, raising DeviceNotFound and aborting the write-zeroes or shred cleanup path. The cleanup operation fails...\n\n**Recommendation**:\nAdd an nvme_attach_ns wrapper in nvme_cli.py (nvme attach-ns \u003cdev\u003e -n \u003cnsid\u003e -c \u003ccntid\u003e) and call it after nvme_create_ns in _consolidate_namespaces before rescanning. Use the NSID returned by create-ns or re-query to attach the correct namespace.","commit_id":"e5a7877ab9432515f4b22721a94b5af374abf44f"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"33baf50389841fb61216ccafd6cc3e6bfe3ac717","unresolved":false,"context_lines":[{"line_number":423,"context_line":"        if ns_mgmt:"},{"line_number":424,"context_line":"            ns_dev, nsid \u003d self._consolidate_namespaces(nvme_dev)"},{"line_number":425,"context_line":"        else:"},{"line_number":426,"context_line":"            nsid \u003d nvme_cli.nvme_list_ns(nvme_dev)"},{"line_number":427,"context_line":"            ns_dev \u003d \u0027%sn%d\u0027 % (nvme_dev, nsid)"},{"line_number":428,"context_line":"        id_ns \u003d nvme_cli.nvme_id_ns(ns_dev)"},{"line_number":429,"context_line":"        namespace_size \u003d id_ns.get(\u0027nsze\u0027, 0)"}],"source_content_type":"text/x-python","patch_set":8,"id":"f5dbea0f_be76048a","line":426,"updated":"2026-08-11 09:54:26.000000000","message":"The new cleanup helper methods (_do_write_zeroes, _do_shred, _consolidate_namespaces) call nvme_cli.nvme_list_ns() and use the return value as an integer NSID in string formatting like \u0027%sn%d\u0027. However, nvme_list_ns returns the raw first element of the JSON list, which for nvme-cli 1.x format is...\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Risk**: On any system running nvme-cli 1.x, device cleanup via write-zeroes or shred will fail because the namespace device path is constructed incorrectly. Sanitize-based cleanup is unaffected since it operates on the controller, not a namespace.\n\n**Priority**: Before merge\n**Why This Matters**: On any system running nvme-cli 1.x, device cleanup via write-zeroes or shred will fail because the namespace device path is constructed incorrectly. Sanitize-based cleanup is unaffected since it operates on the controller, not a namespace.\n\n**Recommendation**:\nEither fix nvme_list_ns to always return an integer NSID (e.g., extract nsid from the dict if the element is a dict), or handle both dict and int return types in the callers. The docstring already says \u0027:returns: integer NSID\u0027, so fixing nvme_list_ns to honor that contract is the cleaner approach.","commit_id":"cdc8f96862eb3088ec45dd164cf0d5edc8e7f617"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"33baf50389841fb61216ccafd6cc3e6bfe3ac717","unresolved":false,"context_lines":[{"line_number":461,"context_line":"        lba_size \u003d 1 \u003c\u003c lba_data_shift"},{"line_number":462,"context_line":"        lba_count \u003d total_capacity_bytes // lba_size if lba_size else 0"},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"        for nsid in range(1, num_namespaces + 1):"},{"line_number":465,"context_line":"            try:"},{"line_number":466,"context_line":"                nvme_cli.nvme_delete_ns(nvme_dev, nsid)"},{"line_number":467,"context_line":"            except Exception:"}],"source_content_type":"text/x-python","patch_set":8,"id":"bb18fb60_0165cdcf","line":464,"updated":"2026-08-11 09:54:26.000000000","message":"The namespace deletion loop in _consolidate_namespaces uses id_ctrl[\u0027nn\u0027] as the upper bound. Per the NVMe spec, nn is the maximum number of namespaces the controller supports (commonly 256 or more), not the count of active namespaces. The code issues nvme delete-ns for every NSID from 1 to nn, w...\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: Device cleanup involving namespace consolidation (zero_wz or zero_shred with ns_mgmt\u003dTrue) will take significantly longer than necessary due to hundreds of failed nvme delete-ns process spawns, each going through privsep escalation.\n\n**Suggestion**:\nUse nvme list-ns to enumerate only active/allocated namespace IDs and delete those, instead of iterating 1..nn. Alternatively, read the active namespace list once and iterate over that.","commit_id":"cdc8f96862eb3088ec45dd164cf0d5edc8e7f617"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"cb2d7e0f4947989cb23d86b39249696ed4a0b7a7","unresolved":false,"context_lines":[{"line_number":410,"context_line":"                if status_bits \u003d\u003d 0x1:"},{"line_number":411,"context_line":"                    return"},{"line_number":412,"context_line":"                if status_bits \u003d\u003d 0x3:"},{"line_number":413,"context_line":"                    raise exception.DeviceCleanupFailed("},{"line_number":414,"context_line":"                        reason\u003d\u0027Sanitize failed: sstat\u003d%r\u0027 % sanitize_status"},{"line_number":415,"context_line":"                    )"},{"line_number":416,"context_line":"            time.sleep(5)"}],"source_content_type":"text/x-python","patch_set":9,"id":"51d88365_d88d60f7","line":413,"updated":"2026-08-11 15:58:00.000000000","message":"The cleanup code references exception.DeviceCleanupFailed in _poll_sanitize (two raise sites), but this exception class was never added to cyborg/common/exception.py. The most recent exception.py diff only added DeviceNotFound and InvalidConfiguration. This will cause AttributeError at runtime wh...\n\n**Severity**: CRITICAL | **Confidence**: 1.0\n\n**Risk**: When an NVMe sanitize operation fails (sstat reports failure bits 0x3) or times out, the code will raise AttributeError instead of DeviceCleanupFailed. This means cleanup errors are silently masked by a different exception type, the caller cannot catch the intended exception, and the error messag...\n\n**Priority**: Immediate\n**Why This Matters**: When an NVMe sanitize operation fails (sstat reports failure bits 0x3) or times out, the code will raise AttributeError instead of DeviceCleanupFailed. This means cleanup errors are silently masked by a different exception type, the caller cannot catch the intended exception, and the error messag...\n\n**Recommendation**:\nAdd a DeviceCleanupFailed exception class to cyborg/common/exception.py, following the existing pattern (e.g., subclass CyborgException with _msg_fmt \u003d _(\u0027Device cleanup failed: %(reason)s.\u0027)).","commit_id":"67434638d27723891802e584b1dc816bb94570b5"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"cb2d7e0f4947989cb23d86b39249696ed4a0b7a7","unresolved":false,"context_lines":[{"line_number":423,"context_line":"        if ns_mgmt:"},{"line_number":424,"context_line":"            ns_dev, nsid \u003d self._consolidate_namespaces(nvme_dev)"},{"line_number":425,"context_line":"        else:"},{"line_number":426,"context_line":"            nsid \u003d nvme_cli.nvme_list_ns(nvme_dev)"},{"line_number":427,"context_line":"            ns_dev \u003d \u0027%sn%d\u0027 % (nvme_dev, nsid)"},{"line_number":428,"context_line":"        id_ns \u003d nvme_cli.nvme_id_ns(ns_dev)"},{"line_number":429,"context_line":"        namespace_size \u003d id_ns.get(\u0027nsze\u0027, 0)"}],"source_content_type":"text/x-python","patch_set":9,"id":"b2b16430_28710e25","line":426,"updated":"2026-08-11 15:58:00.000000000","message":"nvme_list_ns returns {\u0027id\u0027: 1} (a dict) for nvme-cli 1.x bare-array output, but returns an integer for 2.x format. The new cleanup code does ns_dev \u003d \u0027%sn%d\u0027 % (nvme_dev, nsid) which raises TypeError when nsid is a dict.\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Risk**: On systems with nvme-cli 1.x installed, all write-zeroes and shred cleanup operations will crash with TypeError. This affects the zero_wz and zero_shred cleanup paths entirely on 1.x deployments.\n\n**Priority**: Before merge\n**Why This Matters**: On systems with nvme-cli 1.x installed, all write-zeroes and shred cleanup operations will crash with TypeError. This affects the zero_wz and zero_shred cleanup paths entirely on 1.x deployments.\n\n**Recommendation**:\nFix nvme_list_ns to always return an integer NSID regardless of output format. For 1.x bare-array format, extract the \u0027nsid\u0027 or \u0027id\u0027 field: ns_list[0].get(\u0027nsid\u0027, ns_list[0].get(\u0027id\u0027)) if isinstance(ns_list[0], dict) else ns_list[0].","commit_id":"67434638d27723891802e584b1dc816bb94570b5"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"f58ae2b38f30486662c6c821f019c359cb39d6c5","unresolved":false,"context_lines":[{"line_number":424,"context_line":"            sanitize_progress \u003d slog.get(\u0027sprog\u0027, 0xFFFF)"},{"line_number":425,"context_line":"            sanitize_status \u003d slog.get(\u0027sstat\u0027, 0)"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"            if sanitize_progress \u003d\u003d 0xFFFF:"},{"line_number":428,"context_line":"                status_bits \u003d self._parse_sanitize_status(sanitize_status)"},{"line_number":429,"context_line":"                if status_bits \u003d\u003d 0x1:"},{"line_number":430,"context_line":"                    return"}],"source_content_type":"text/x-python","patch_set":10,"id":"77b240b1_e4062fda","line":427,"updated":"2026-08-12 09:35:49.000000000","message":"In _poll_sanitize, the success and failure checks are only evaluated when sprog \u003d\u003d 0xFFFF. If the sanitize status transitions to success (sstat bits 0x1) while sprog is still non-zero or zero (but not 0xFFFF), the method never recognizes the completed state and loops until timeout. The NVMe spec...\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: On devices that report sprog\u003d0 (or any non-0xFFFF value) at completion, sanitize cleanup will always time out after the full cleanup_timeout period (default 900 s), wasting time and then raising DeviceCleanupFailed even though the sanitize actually succeeded.\n\n**Priority**: Before merge\n**Why This Matters**: On devices that report sprog\u003d0 (or any non-0xFFFF value) at completion, sanitize cleanup will always time out after the full cleanup_timeout period (default 900 s), wasting time and then raising DeviceCleanupFailed even though the sanitize actually succeeded.\n\n**Recommendation**:\nEvaluate success/failure status bits regardless of sprog value, or at minimum also check status bits when sprog is 0. Restructure so that sstat is checked on every poll iteration, not only when sprog \u003d\u003d 0xFFFF.","commit_id":"31220ba801bcd4bfbc750c931745d43bacfe71f5"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ee45d4c69ec9e35dc559c3d3fb62e0b31dd336df","unresolved":false,"context_lines":[{"line_number":476,"context_line":"        cntlid \u003d id_ctrl.get(\u0027cntlid\u0027, 0)"},{"line_number":477,"context_line":""},{"line_number":478,"context_line":"        # Read LBA format from namespace 1 before deleting anything."},{"line_number":479,"context_line":"        first_ns_dev \u003d \u0027%sn1\u0027 % nvme_dev"},{"line_number":480,"context_line":"        id_ns \u003d nvme_cli.nvme_id_ns(first_ns_dev)"},{"line_number":481,"context_line":"        active_lba_format \u003d id_ns.get(\u0027flbas\u0027, 0)"},{"line_number":482,"context_line":"        lba_formats \u003d id_ns.get(\u0027lbaf\u0027, [{\u0027ds\u0027: 9}])"}],"source_content_type":"text/x-python","patch_set":11,"id":"1431fdf8_d7b8b39d","line":479,"updated":"2026-08-13 05:21:57.000000000","message":"The method unconditionally reads id-ns for \u0027/dev/nvmeXn1\u0027 to extract the LBA format, but nsid 1 may not be an active namespace on the controller. If it does not exist, nvme_id_ns raises a ProcessExecutionError that is not caught, resulting in an unhandled exception rather than a meaningful Device...\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: On NVMe controllers where nsid 1 is not an active namespace, namespace consolidation will fail with an opaque ProcessExecutionError instead of a clear DeviceCleanupFailed error, making debugging difficult.\n\n**Priority**: Before merge\n**Why This Matters**: On NVMe controllers where nsid 1 is not an active namespace, namespace consolidation will fail with an opaque ProcessExecutionError instead of a clear DeviceCleanupFailed error, making debugging difficult.\n\n**Recommendation**:\nWrap the nvme_id_ns call in a try/except and either use a fallback LBA format or list active namespaces first to find one whose id-ns can be read. Alternatively, catch the exception and raise DeviceCleanupFailed with a descriptive message.","commit_id":"c0628056e9c79512c970ed75974c9208c621c31a"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ee45d4c69ec9e35dc559c3d3fb62e0b31dd336df","unresolved":false,"context_lines":[{"line_number":489,"context_line":"        lba_size \u003d 1 \u003c\u003c lba_data_shift"},{"line_number":490,"context_line":"        lba_count \u003d total_capacity_bytes // lba_size if lba_size else 0"},{"line_number":491,"context_line":""},{"line_number":492,"context_line":"        for nsid in range(1, num_namespaces + 1):"},{"line_number":493,"context_line":"            try:"},{"line_number":494,"context_line":"                nvme_cli.nvme_delete_ns(nvme_dev, nsid)"},{"line_number":495,"context_line":"            except Exception:"}],"source_content_type":"text/x-python","patch_set":11,"id":"ab9785c3_f9c24347","line":492,"updated":"2026-08-13 05:21:57.000000000","message":"The method loops nsid from 1 to num_namespaces (nn from id-ctrl) and calls nvme_delete_ns for each. The NVMe nn field is the maximum number of namespace IDs the controller supports, not the count of currently active namespaces. Deleting non-existent namespace IDs may produce errors on some contro...\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: On controllers with nn \u003e number of active namespaces (common), deleting non-existent NSIDs may error and abort cleanup prematurely. The behavior depends on the controller firmware and nvme-cli version.\n\n**Priority**: Before merge\n**Why This Matters**: On controllers with nn \u003e number of active namespaces (common), deleting non-existent NSIDs may error and abort cleanup prematurely. The behavior depends on the controller firmware and nvme-cli version.\n\n**Recommendation**:\nUse nvme_list_ns to get the list of active namespace IDs and delete only those, rather than iterating all possible NSIDs from 1 to nn. Alternatively, only delete namespaces that exist by querying active namespaces first.","commit_id":"c0628056e9c79512c970ed75974c9208c621c31a"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"f08492db70ccad92b81a752214af6618b497b824","unresolved":false,"context_lines":[{"line_number":489,"context_line":"        lba_size \u003d 1 \u003c\u003c lba_data_shift"},{"line_number":490,"context_line":"        lba_count \u003d total_capacity_bytes // lba_size if lba_size else 0"},{"line_number":491,"context_line":""},{"line_number":492,"context_line":"        for nsid in range(1, num_namespaces + 1):"},{"line_number":493,"context_line":"            try:"},{"line_number":494,"context_line":"                nvme_cli.nvme_delete_ns(nvme_dev, nsid)"},{"line_number":495,"context_line":"            except Exception:"}],"source_content_type":"text/x-python","patch_set":12,"id":"eed26fc9_66212424","line":492,"updated":"2026-08-13 14:21:41.000000000","message":"When zero_wz or zero_shred runs with ns_mgmt\u003dtrue, _consolidate_namespaces() calls nvme delete-ns for every NSID 1..nn before creating the replacement namespace, and reads the LBA format from a hard-coded \u0027%sn1\u0027 device. This destroys data on namespaces the tenant never touched and fails outright...\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: A cleanup of one released accelerator wipes every namespace on the drive, including namespaces belonging to other consumers; on drives with no nsid-1 namespace or with the first active namespace at a higher NSID, id-ns on /dev/nvme0n1 raises and cleanup aborts after potentially already deleting n...\n\n**Priority**: Before merge\n**Why This Matters**: A cleanup of one released accelerator wipes every namespace on the drive, including namespaces belonging to other consumers; on drives with no nsid-1 namespace or with the first active namespace at a higher NSID, id-ns on /dev/nvme0n1 raises and cleanup aborts after potentially already deleting n...\n\n**Recommendation**:\nEnumerate active namespaces via nvme_list_ns / list-ns -a instead of range(1, nn+1), derive the LBA format from an active namespace (or id-ns of the namespace being zeroed) rather than the hard-coded \u0027%sn1\u0027, and make deletion failure of a non-existent namespace non-fatal. Consider whether consolidation is needed at all when only one namespace exists.","commit_id":"5a43f887d0f0dff019290d6a6852101b0cd89bb8"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"cae37a88b4d39e4ee1f5c8d9becd8be01688ec12","unresolved":false,"context_lines":[{"line_number":379,"context_line":"    def _do_sanitize(self, nvme_dev, action):"},{"line_number":380,"context_line":"        slog \u003d nvme_cli.nvme_sanitize_log(nvme_dev)"},{"line_number":381,"context_line":"        if self._should_start_sanitize(slog):"},{"line_number":382,"context_line":"            action_code \u003d 4 if action \u003d\u003d CLEANUP_SANITIZE_CES else 2"},{"line_number":383,"context_line":"            nvme_cli.nvme_sanitize(nvme_dev, action_code)"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"        self._poll_sanitize(nvme_dev)"}],"source_content_type":"text/x-python","patch_set":13,"id":"b6f63f34_8384bf51","line":382,"updated":"2026-08-14 16:03:37.000000000","message":"_do_sanitize maps sanitize_ces to action code 4 and sanitize_bes to code 2, but per NVMe 2.x the SANACT field value 100b (4) is Overwrite and 011b (3) is Crypto Erase; Block Erase is 010b (2). The 4 for CES silently executes the wrong erase method.\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Risk**: Drives whose config only enables crypto erase (SANICAP.CES\u003d1, BES\u003d0) will reject the command or, on drives that also support overwrite, run overwrite with the default pattern instead of the intended key-based crypto erase. Cleanup raises DeviceCleanupFailed or performs the wrong sanitization oper...\n\n**Priority**: Before merge\n**Why This Matters**: Drives whose config only enables crypto erase (SANICAP.CES\u003d1, BES\u003d0) will reject the command or, on drives that also support overwrite, run overwrite with the default pattern instead of the intended key-based crypto erase. Cleanup raises DeviceCleanupFailed or performs the wrong sanitization oper...\n\n**Recommendation**:\nUse action code 3 for CLEANUP_SANITIZE_CES (and keep 2 for BES). Update the commit message, unit-test assertions (mock_san.assert_called_once_with(\u0027/dev/nvme0\u0027, 4)) and any capability-resolution comments that reference crypto erase.","commit_id":"950ef9b636d768545b84c2e5a674a3ede6011f6f"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"cae37a88b4d39e4ee1f5c8d9becd8be01688ec12","unresolved":false,"context_lines":[{"line_number":476,"context_line":"        cntlid \u003d id_ctrl.get(\u0027cntlid\u0027, 0)"},{"line_number":477,"context_line":""},{"line_number":478,"context_line":"        # Read LBA format from namespace 1 before deleting anything."},{"line_number":479,"context_line":"        first_ns_dev \u003d \u0027%sn1\u0027 % nvme_dev"},{"line_number":480,"context_line":"        id_ns \u003d nvme_cli.nvme_id_ns(first_ns_dev)"},{"line_number":481,"context_line":"        active_lba_format \u003d id_ns.get(\u0027flbas\u0027, 0)"},{"line_number":482,"context_line":"        lba_formats \u003d id_ns.get(\u0027lbaf\u0027, [{\u0027ds\u0027: 9}])"}],"source_content_type":"text/x-python","patch_set":13,"id":"a53ee252_1b4c5c1b","line":479,"updated":"2026-08-14 16:03:37.000000000","message":"Consolidation reads id-ns from \u0027%sn1\u0027 before deleting namespaces. The patch itself fixed exactly this assumption in the write-zeroes path (nvme_write_zeroes now uses the NSID from nvme_list_ns instead of hardcoded 1, per the commit message), but the flbas/lbaf discovery still hardcodes namespace 1.\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: On drives whose lowest active NSID is not 1 (previously deleted-and-recreated topologies, or drives where NSID 1 is inactive), id-ns fails and the entire ns_mgmt cleanup path aborts before any consolidation runs.\n\n**Priority**: Before merge\n**Why This Matters**: On drives whose lowest active NSID is not 1 (previously deleted-and-recreated topologies, or drives where NSID 1 is inactive), id-ns fails and the entire ns_mgmt cleanup path aborts before any consolidation runs.\n\n**Recommendation**:\nResolve the actual first active NSID via nvme_list_ns(nvme_dev) (already available and used at the end of this same function) and read id-ns from that namespace device, consistent with the fix already applied in _do_write_zeroes.","commit_id":"950ef9b636d768545b84c2e5a674a3ede6011f6f"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"cae37a88b4d39e4ee1f5c8d9becd8be01688ec12","unresolved":false,"context_lines":[{"line_number":489,"context_line":"        lba_size \u003d 1 \u003c\u003c lba_data_shift"},{"line_number":490,"context_line":"        lba_count \u003d total_capacity_bytes // lba_size if lba_size else 0"},{"line_number":491,"context_line":""},{"line_number":492,"context_line":"        for nsid in range(1, num_namespaces + 1):"},{"line_number":493,"context_line":"            try:"},{"line_number":494,"context_line":"                nvme_cli.nvme_delete_ns(nvme_dev, nsid)"},{"line_number":495,"context_line":"            except Exception:"}],"source_content_type":"text/x-python","patch_set":13,"id":"a29d2da6_dc31415c","line":492,"updated":"2026-08-14 16:03:37.000000000","message":"_consolidate_namespaces deletes NSIDs 1..nn in a fixed range loop. The controller\u0027s nn field is the maximum number of namespaces supported, and valid NSIDs can be sparse and non-contiguous; inactive NSIDs inside the range are legal and cause nvme delete-ns to fail.\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Risk**: On drives where active namespaces are sparse or where the lowest NSID exceeds 1, the loop aborts the whole cleanup with DeviceCleanupFailed (leaving a partially deleted, unusable drive with prior namespaces already deleted) or misses namespaces that were never deleted. Either outcome strands the...\n\n**Priority**: Before merge\n**Why This Matters**: On drives where active namespaces are sparse or where the lowest NSID exceeds 1, the loop aborts the whole cleanup with DeviceCleanupFailed (leaving a partially deleted, unusable drive with prior namespaces already deleted) or misses namespaces that were never deleted. Either outcome strands the...\n\n**Recommendation**:\nEnumerate actual namespaces via nvme list-ns (optionally --all) and delete exactly those NSIDs, treating \u0027namespace does not exist\u0027/inactive-NSID errors from delete-ns as success instead of a hard DeviceCleanupFailed failure.","commit_id":"950ef9b636d768545b84c2e5a674a3ede6011f6f"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"2a5ebcb116d924114639ff1fe8c83fb9b6914874","unresolved":false,"context_lines":[{"line_number":390,"context_line":"            return sanitize_state.get(\u0027sanitize_state\u0027, \u0027\u0027)"},{"line_number":391,"context_line":"        return \u0027\u0027"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def _should_start_sanitize(self, slog):"},{"line_number":394,"context_line":"        sanitize_progress \u003d slog.get(\u0027sprog\u0027, 0xFFFF)"},{"line_number":395,"context_line":"        status_bits \u003d self._parse_sanitize_status(slog.get(\u0027sstat\u0027, 0))"},{"line_number":396,"context_line":"        sanitize_state \u003d self._sanitize_state_text(slog)"}],"source_content_type":"text/x-python","patch_set":14,"id":"51013d12_1639ba7d","line":393,"updated":"2026-08-15 16:53:52.000000000","message":"For nvme-cli 1.x (integer sstat), an idle log with sstat\u003d0 and sprog\u003d0 falls through every branch and returns False, so cleanup never issues the sanitize command and merely polls until timeout. The dict-sstat path handles this device shape but the integer path does not, contradicting the commit\u0027s...\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: On drives whose sanitize log reports sprog\u003d0 with integer sstat (nvme-cli 1.x) when never sanitized, cleanup never issues the erase command, holds the per-device lock for the full cleanup_timeout (900 s default), and then raises DeviceCleanupFailed even though the device was never wiped.\n\n**Priority**: Before merge\n**Why This Matters**: On drives whose sanitize log reports sprog\u003d0 with integer sstat (nvme-cli 1.x) when never sanitized, cleanup never issues the erase command, holds the per-device lock for the full cleanup_timeout (900 s default), and then raises DeviceCleanupFailed even though the device was never wiped.\n\n**Recommendation**:\nIn _should_start_sanitize, also return True when sanitize_progress \u003d\u003d 0 and status_bits \u003d\u003d 0x0 (or when status_bits not in (0x1, 0x2) and sprog !\u003d 0xFFFF with no in-progress indication), and add a unit test with {\u0027sprog\u0027: 0, \u0027sstat\u0027: 0} (integer) asserting nvme_sanitize is called.","commit_id":"5990239393862c01b0805e5c30f83b6a1da60d3e"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"2a5ebcb116d924114639ff1fe8c83fb9b6914874","unresolved":false,"context_lines":[{"line_number":476,"context_line":"        cntlid \u003d id_ctrl.get(\u0027cntlid\u0027, 0)"},{"line_number":477,"context_line":""},{"line_number":478,"context_line":"        # Read LBA format from namespace 1 before deleting anything."},{"line_number":479,"context_line":"        first_ns_dev \u003d \u0027%sn1\u0027 % nvme_dev"},{"line_number":480,"context_line":"        id_ns \u003d nvme_cli.nvme_id_ns(first_ns_dev)"},{"line_number":481,"context_line":"        active_lba_format \u003d id_ns.get(\u0027flbas\u0027, 0)"},{"line_number":482,"context_line":"        lba_formats \u003d id_ns.get(\u0027lbaf\u0027, [{\u0027ds\u0027: 9}])"}],"source_content_type":"text/x-python","patch_set":14,"id":"9e80dd9f_0d67fbe5","line":479,"updated":"2026-08-15 16:53:52.000000000","message":"The LBA format is read from \u0027/dev/nvme0n1\u0027 unconditionally. On drives whose first active namespace is not NSID 1 (the exact case the commit message says it fixes elsewhere via nvme_list_ns), namespace 1 does not exist and nvme_id_ns raises, aborting cleanup before any namespace is deleted.\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: For zero_wz/zero_shred with ns_mgmt\u003dTrue on any controller without an active namespace 1, id-ns fails, DeviceCleanupFailed propagates (or the raw processutils error escapes), and no erasure happens; the drive is left unwiped and reported as failed cleanup.\n\n**Priority**: Before merge\n**Why This Matters**: For zero_wz/zero_shred with ns_mgmt\u003dTrue on any controller without an active namespace 1, id-ns fails, DeviceCleanupFailed propagates (or the raw processutils error escapes), and no erasure happens; the drive is left unwiped and reported as failed cleanup.\n\n**Recommendation**:\nResolve an existing namespace first (nvme_list_ns) and read its id-ns for the LBA format, falling back to a controller-derived format only when no namespace exists; catch the failure and skip the format read rather than aborting before deletion.","commit_id":"5990239393862c01b0805e5c30f83b6a1da60d3e"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"232f228be05e7d458343382b5836fee9978e5d89","unresolved":false,"context_lines":[{"line_number":390,"context_line":"            return sanitize_state.get(\u0027sanitize_state\u0027, \u0027\u0027)"},{"line_number":391,"context_line":"        return \u0027\u0027"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def _should_start_sanitize(self, slog):"},{"line_number":394,"context_line":"        sanitize_progress \u003d slog.get(\u0027sprog\u0027, 0xFFFF)"},{"line_number":395,"context_line":"        status_bits \u003d self._parse_sanitize_status(slog.get(\u0027sstat\u0027, 0))"},{"line_number":396,"context_line":"        sanitize_state \u003d self._sanitize_state_text(slog)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ad32b73c_9d55479b","line":393,"updated":"2026-08-17 08:28:47.000000000","message":"When the sanitize log already reports a successful prior sanitize (sstat bits 0x1 with sprog 0xFFFF), _should_start_sanitize returns False and _poll_sanitize immediately returns success, so cleanup() wipes nothing even though the device was leased and rewritten since the last sanitize.\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Risk**: On the second and every subsequent unbind of the same device, data written by the previous tenant remains on the media while the driver reports cleanup complete and the device returns to AVAILABLE. This defeats the data-sanitization purpose of the cleanup lifecycle added in the prior commit.\n\n**Priority**: Before merge\n**Why This Matters**: On the second and every subsequent unbind of the same device, data written by the previous tenant remains on the media while the driver reports cleanup complete and the device returns to AVAILABLE. This defeats the data-sanitization purpose of the cleanup lifecycle added in the prior commit.\n\n**Recommendation**:\nOnly skip when a sanitize is genuinely in progress (sprog \u003c 0xFFFF or in-progress status); always issue nvme sanitize when the last completed state is success/failure/never. Add a unit test where the initial log shows sprog 0xFFFF with sstat success and assert nvme_sanitize is still called.","commit_id":"cf324c090e28207b145bf17176af463e344af465"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"232f228be05e7d458343382b5836fee9978e5d89","unresolved":false,"context_lines":[{"line_number":490,"context_line":"        lba_count \u003d total_capacity_bytes // lba_size if lba_size else 0"},{"line_number":491,"context_line":""},{"line_number":492,"context_line":"        for nsid in range(1, num_namespaces + 1):"},{"line_number":493,"context_line":"            try:"},{"line_number":494,"context_line":"                nvme_cli.nvme_delete_ns(nvme_dev, nsid)"},{"line_number":495,"context_line":"            except Exception:"},{"line_number":496,"context_line":"                raise exception.DeviceCleanupFailed("}],"source_content_type":"text/x-python","patch_set":15,"id":"805bc7c8_150ff79e","line":493,"updated":"2026-08-17 08:28:47.000000000","message":"The delete loop catches bare Exception and re-raises DeviceCleanupFailed without logging, so the actual nvme-cli error, stderr, and exit code are lost when consolidation fails.\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Operators diagnosing failed cleanups on real hardware only see the generic \u0027Failed to delete ns\u0027 message without the nvme-cli failure reason, slowing down debugging of the ERROR-state lifecycle.\n\n**Recommendation**:\nAdd LOG.exception(\u0027Failed to delete namespace %d on %s\u0027, nsid, nvme_dev) before raising, or chain via \u0027from exc\u0027 / include the nvme-cli error text in the DeviceCleanupFailed reason.","commit_id":"cf324c090e28207b145bf17176af463e344af465"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"1de2f89f0db1c417e460280ca0f194f9279d452e","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        :param action: ``CleanupAction.SANITIZE_CES`` or ``SANITIZE_BES``."},{"line_number":214,"context_line":"        :raises DeviceCleanupFailed: if the final log reports sanitize failure."},{"line_number":215,"context_line":"        \"\"\""},{"line_number":216,"context_line":"        action_code \u003d 4 if action \u003d\u003d CleanupAction.SANITIZE_CES else 2"},{"line_number":217,"context_line":"        timeout_ms \u003d CONF.nvme.cleanup_timeout * 1000"},{"line_number":218,"context_line":"        nvme_cli.nvme_sanitize(nvme_dev, action_code, timeout_ms\u003dtimeout_ms)"},{"line_number":219,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"bd3a67d4_0e0814bb","line":216,"updated":"2026-08-21 12:09:29.000000000","message":"_do_sanitize issues `nvme sanitize` without nvme-cli\u0027s --wait and then reads the sanitize-log exactly once, immediately. NVMe sanitize is asynchronous: without --wait (or a poll loop) nvme-cli returns as soon as the admin command is accepted, and the first sanitize-log read will typically report sstat\u003d1 (in progress). The code only fails when the 3-bit status equals 0x3; an in-progress (0x1) or freshly-issued state is treated as success, so cleanup() returns and _run_cleanup_async marks the device DEVICE_STATE_AVAILABLE and clears the Placement reserved inventory.\n\n**Severity**: HIGH | **Confidence**: 0.78\n\n**Impact**: The device is returned to the available pool while the erase is still running. If the in-flight sanitize later fails (sstat\u003d3), nothing detects it: residual tenant data remains on a drive already marked available and unreserved, and it can be allocated to the next tenant. This defeats the security purpose of the whole cleanup feature.\n\n**Priority**: Before merge\n**Recommendation**:\nPass --wait to `nvme sanitize` when supported, or poll `nvme sanitize-log` (with sleep/backoff and a deadline derived from [nvme] cleanup_timeout) until sstat leaves the in-progress value, and treat any non-success terminal status and timeout expiry as DeviceCleanupFailed. Update the unit tests to exercise the in-progress path.","commit_id":"72faa1c86fee63baf9c816b1bb5529dc03647ce0"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e028be7449e99a0169356692d090d2495ab7b013","unresolved":false,"context_lines":[{"line_number":213,"context_line":""},{"line_number":214,"context_line":"        _locked_cleanup()"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"    def _do_sanitize(self, nvme_dev, action):"},{"line_number":217,"context_line":"        \"\"\"Issue ``nvme sanitize`` and record the final sanitize-log status."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        Blocks until nvme-cli returns. Uses ``[nvme] cleanup_timeout`` as the"}],"source_content_type":"text/x-python","patch_set":19,"id":"7fbf90b2_067a4325","line":216,"updated":"2026-08-24 16:00:10.000000000","message":"_do_sanitize() issues \u0027nvme sanitize\u0027 and immediately reads the sanitize-log exactly once, checking only sstat\u003d\u003d0x3 (failed). NVMe sanitize is an asynchronous operation: the admin command returns while the controller is still erasing, so a log read taken right after typically reports \u0027in progress\u0027 (sstat 0x1), which this code treats as success. The commit message explicitly states \u0027using the NVMe Sanitize command and polling sstat until completion\u0027, but the implementation contains no polling loop at all - the docstring itself says \u0027Reads sanitize-log once afterward\u0027.\n\n**Severity**: CRITICAL | **Confidence**: 0.85\n\n**Impact**: A device can be marked AVAILABLE while the sanitize operation is still running. The next tenant can be allocated the device mid-erase and read residual data, or cause the in-flight sanitize to fail outright. This defeats the stated purpose of the change (removing operator-sensitive data between allocations).\n\n**Priority**: Immediate\n**Recommendation**:\nPoll \u0027nvme sanitize-log\u0027 on an interval until sstat reports completed-with-success (or failed) with an overall deadline, e.g. loop while _parse_sanitize_status() \u003d\u003d in-progress with a time budget derived from [nvme] cleanup_timeout, and raise DeviceCleanupFailed on failure or deadline expiry. Add a unit test where the first log read reports in-progress and a later read reports success.","commit_id":"00f0eab12d2c0a3a86ffe85e26393bc76fd11c11"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e028be7449e99a0169356692d090d2495ab7b013","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            slog.get(\u0027sstat\u0027),"},{"line_number":268,"context_line":"        )"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    def _do_write_zeroes(self, nvme_dev, ns_mgmt):"},{"line_number":271,"context_line":"        \"\"\"Write zeroes to the full namespace using ``nvme write-zeroes``."},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        When ``ns_mgmt`` is true, consolidates all namespaces into one"}],"source_content_type":"text/x-python","patch_set":19,"id":"79c75de4_6872bc7d","line":270,"updated":"2026-08-24 16:00:10.000000000","message":"When the controller does not support namespace management, _do_write_zeroes() and _do_shred() call nvme_list_ns(), which returns only the first active NSID, and erase just that single namespace. Any other active namespaces on the same controller keep their tenant data, yet cleanup() reports success and the device is marked AVAILABLE.\n\n**Severity**: HIGH | **Confidence**: 0.75\n\n**Impact**: On multi-namespace controllers without ns-mgmt support, tenant data survives cleanup on every namespace other than the first and is exposed to the next allocation - a silent data-remnant failure reported as success.\n\n**Priority**: Before merge\n**Recommendation**:\nIterate over all active namespaces (nvme_list_all_ns) in the non-ns_mgmt path and write-zeroes/shred each one, or fail the cleanup with DeviceCleanupFailed when more than one active namespace exists and ns_mgmt is unsupported.","commit_id":"00f0eab12d2c0a3a86ffe85e26393bc76fd11c11"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"3195225741a163ab6883c1f34ef4092cbac729a8","unresolved":true,"context_lines":[{"line_number":168,"context_line":"        :raises DeviceCleanupFailed: if nvme-cli cleanup fails."},{"line_number":169,"context_line":"        :raises InvalidConfiguration: if ``cleanup_action`` is unknown."},{"line_number":170,"context_line":"        \"\"\""},{"line_number":171,"context_line":"        board_info \u003d jsonutils.loads(device.std_board_info)"},{"line_number":172,"context_line":"        try:"},{"line_number":173,"context_line":"            action \u003d CleanupAction(board_info[\u0027cleanup_action\u0027])"},{"line_number":174,"context_line":"        except ValueError as exc:"}],"source_content_type":"text/x-python","patch_set":24,"id":"c472f585_96205dae","line":171,"range":{"start_line":171,"start_character":21,"end_line":171,"end_character":59},"updated":"2026-09-03 14:42:43.000000000","message":"so this is somehtin gwe can refine later but really the object layer eists so that we never have to do this outside of the obejct fiels\n\nwe shoudl fix that enverywere in teh future but the\n\nstd_board_info shoudl evovle away form a json string at the obejct level to a ovo dictonay field.\n\nparsing and serisalistion shoudl happen only at the edges when we load it form the db or write it to rabbit not in our normal code paths.","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"3195225741a163ab6883c1f34ef4092cbac729a8","unresolved":true,"context_lines":[{"line_number":170,"context_line":"        \"\"\""},{"line_number":171,"context_line":"        board_info \u003d jsonutils.loads(device.std_board_info)"},{"line_number":172,"context_line":"        try:"},{"line_number":173,"context_line":"            action \u003d CleanupAction(board_info[\u0027cleanup_action\u0027])"},{"line_number":174,"context_line":"        except ValueError as exc:"},{"line_number":175,"context_line":"            raise exception.InvalidConfiguration("},{"line_number":176,"context_line":"                reason\u003d\u0027Unknown cleanup action: %s\u0027"}],"source_content_type":"text/x-python","patch_set":24,"id":"497f3df6_8cbcabe8","line":173,"range":{"start_line":173,"start_character":11,"end_line":173,"end_character":64},"updated":"2026-09-03 14:42:43.000000000","message":"\u0027cleanup_action\u0027 would ideally be a constant or CleanupAction shoudl provide a from_board_info classmothd\n\nso we can put the try excption inside that\n\n```suggestion\n            action \u003d CleanupAction.from_board_info(board_info)\n```","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"d9bcc63ec45c9a42fd0fa4348d0ddc94eb9cacf5","unresolved":false,"context_lines":[{"line_number":170,"context_line":"        \"\"\""},{"line_number":171,"context_line":"        board_info \u003d jsonutils.loads(device.std_board_info)"},{"line_number":172,"context_line":"        try:"},{"line_number":173,"context_line":"            action \u003d CleanupAction(board_info[\u0027cleanup_action\u0027])"},{"line_number":174,"context_line":"        except ValueError as exc:"},{"line_number":175,"context_line":"            raise exception.InvalidConfiguration("},{"line_number":176,"context_line":"                reason\u003d\u0027Unknown cleanup action: %s\u0027"}],"source_content_type":"text/x-python","patch_set":24,"id":"d7cafc4b_7abe0372","line":173,"range":{"start_line":173,"start_character":11,"end_line":173,"end_character":64},"in_reply_to":"497f3df6_8cbcabe8","updated":"2026-09-04 08:16:59.000000000","message":"Done","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"c1e3df3932de0734bc1c8e29e87ce4e3765679a8","unresolved":false,"context_lines":[{"line_number":224,"context_line":"        :param action: ``CleanupAction.SANITIZE_CES`` or ``SANITIZE_BES``."},{"line_number":225,"context_line":"        :raises DeviceCleanupFailed: if the final log reports sanitize failure."},{"line_number":226,"context_line":"        \"\"\""},{"line_number":227,"context_line":"        action_code \u003d 4 if action \u003d\u003d CleanupAction.SANITIZE_CES else 2"},{"line_number":228,"context_line":"        timeout_ms \u003d CONF.nvme.cleanup_timeout * 1000"},{"line_number":229,"context_line":"        nvme_cli.nvme_sanitize(nvme_dev, action_code, timeout_ms\u003dtimeout_ms)"},{"line_number":230,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"f4f786d2_7ea87d4a","line":227,"updated":"2026-08-31 11:13:37.000000000","message":"For CleanupAction.SANITIZE_BES the driver passes sanitize action code 2. In the NVMe Sanitize command the SAN field is 001b for block-erase, 010b for overwrite and 100b for crypto-erase; nvme-cli -a takes those same values. Code 2 therefore requests an overwrite sanitize, not the block-erase sanitize the capability check (SanicapFlag.BES) selected.\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Impact**: A controller that advertises block-erase but not overwrite sanitize will reject the command (Invalid Field in Command), so cleanup fails and the device goes to error. Where overwrite is supported, a much slower full-media overwrite is performed instead of block erase, and the executed operation no longer matches the advertised BES trait/capability.\n\n**Priority**: Before merge\n**Recommendation**:\nUse action code 1 for SANITIZE_BES (block erase) and keep 4 for crypto erase; update the nvme_sanitize docstring and test_sanitize_bes accordingly.","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"af27bc7492ad3378f791d9383691f39ea456ed14","unresolved":true,"context_lines":[{"line_number":224,"context_line":"        :param action: ``CleanupAction.SANITIZE_CES`` or ``SANITIZE_BES``."},{"line_number":225,"context_line":"        :raises DeviceCleanupFailed: if the final log reports sanitize failure."},{"line_number":226,"context_line":"        \"\"\""},{"line_number":227,"context_line":"        action_code \u003d 4 if action \u003d\u003d CleanupAction.SANITIZE_CES else 2"},{"line_number":228,"context_line":"        timeout_ms \u003d CONF.nvme.cleanup_timeout * 1000"},{"line_number":229,"context_line":"        nvme_cli.nvme_sanitize(nvme_dev, action_code, timeout_ms\u003dtimeout_ms)"},{"line_number":230,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"9af97a3f_2122c1d8","line":227,"in_reply_to":"4877fc4b_c4ef6945","updated":"2026-09-04 04:57:06.000000000","message":"Below is the cli output of nvme santizie\n```\nchandankumar@fedora:~/programming/cyborg$ nvme sanitize --help\nUsage: nvme sanitize \u003cdevice\u003e [OPTIONS]\n\nSend a sanitize command.\n\nOptions:\n  [  --verbose, -v ]                    --- Increase output verbosity\n  [  --output-format\u003d\u003cFMT\u003e, -o \u003cFMT\u003e ]  --- Output format: normal|json|binary\n  [  --no-dealloc, -d ]                 --- No deallocate after sanitize.\n  [  --oipbp, -i ]                      --- Overwrite invert pattern between\n                                            passes.\n  [  --owpass\u003d\u003cNUM\u003e, -n \u003cNUM\u003e ]         --- Overwrite pass count.\n  [  --ause, -u ]                       --- Allow unrestricted sanitize exit.\n  [  --sanact\u003d\u003cNUM\u003e, -a \u003cNUM\u003e ]         --- Sanitize action: 1 \u003d Exit failure\n                                            mode, 2 \u003d Start block erase,3 \u003d\n                                            Start overwrite, 4 \u003d Start\n                                            crypto erase, 5 \u003d Exit media\n                                            verification\n  [  --ovrpat\u003d\u003cNUM\u003e, -p \u003cNUM\u003e ]         --- Overwrite pattern.\n  [  --emvs, -e ]                       --- Enter media verification state.\n  [  --timeout\u003d\u003cNUM\u003e, -t \u003cNUM\u003e ]        --- timeout value, in milliseconds\n  [  --dry-run ]                        --- show command instead of sending\n  [  --no-retries ]                     --- disable retry logic on errors\n                                            \n  [  --output-format-version\u003d\u003cNUM\u003e ]    --- output format version: 1|2\n```\n\nSo, Below are the values.\n```\n  1 \u003d Exit failure mode\n  2 \u003d Start block erase \n  3 \u003d Start overwrite\n  4 \u003d Start crypto erase\n```\n\nI have fixed the code based on that.","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"077962772955a1bc8f1ae29e2f5f2692913c778b","unresolved":false,"context_lines":[{"line_number":224,"context_line":"        :param action: ``CleanupAction.SANITIZE_CES`` or ``SANITIZE_BES``."},{"line_number":225,"context_line":"        :raises DeviceCleanupFailed: if the final log reports sanitize failure."},{"line_number":226,"context_line":"        \"\"\""},{"line_number":227,"context_line":"        action_code \u003d 4 if action \u003d\u003d CleanupAction.SANITIZE_CES else 2"},{"line_number":228,"context_line":"        timeout_ms \u003d CONF.nvme.cleanup_timeout * 1000"},{"line_number":229,"context_line":"        nvme_cli.nvme_sanitize(nvme_dev, action_code, timeout_ms\u003dtimeout_ms)"},{"line_number":230,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"6902ec86_86f16c1f","line":227,"in_reply_to":"9af97a3f_2122c1d8","updated":"2026-09-04 13:19:19.000000000","message":"Acknowledged","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"3195225741a163ab6883c1f34ef4092cbac729a8","unresolved":true,"context_lines":[{"line_number":224,"context_line":"        :param action: ``CleanupAction.SANITIZE_CES`` or ``SANITIZE_BES``."},{"line_number":225,"context_line":"        :raises DeviceCleanupFailed: if the final log reports sanitize failure."},{"line_number":226,"context_line":"        \"\"\""},{"line_number":227,"context_line":"        action_code \u003d 4 if action \u003d\u003d CleanupAction.SANITIZE_CES else 2"},{"line_number":228,"context_line":"        timeout_ms \u003d CONF.nvme.cleanup_timeout * 1000"},{"line_number":229,"context_line":"        nvme_cli.nvme_sanitize(nvme_dev, action_code, timeout_ms\u003dtimeout_ms)"},{"line_number":230,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"4877fc4b_c4ef6945","line":227,"in_reply_to":"f4f786d2_7ea87d4a","updated":"2026-09-03 14:42:43.000000000","message":"chandan can you valdiate this. also lets not use ints here lets make thse values constnats \n\nwe created bit field and enums to avoid random ints in the code but that has not be applied to here so we shoudl fix that.","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"c1e3df3932de0734bc1c8e29e87ce4e3765679a8","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        \"\"\""},{"line_number":227,"context_line":"        action_code \u003d 4 if action \u003d\u003d CleanupAction.SANITIZE_CES else 2"},{"line_number":228,"context_line":"        timeout_ms \u003d CONF.nvme.cleanup_timeout * 1000"},{"line_number":229,"context_line":"        nvme_cli.nvme_sanitize(nvme_dev, action_code, timeout_ms\u003dtimeout_ms)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"        final_slog \u003d nvme_cli.nvme_sanitize_log(nvme_dev)"},{"line_number":232,"context_line":"        self._log_sanitize_status(nvme_dev, final_slog)"}],"source_content_type":"text/x-python","patch_set":24,"id":"2307c7bb_b72f7dc7","line":229,"updated":"2026-08-31 11:13:37.000000000","message":"_do_sanitize() issues the nvme sanitize command and then reads nvme sanitize-log exactly once. The completion check only rejects sstat \u003d\u003d 0x3 (failed); any other value, including \u0027sanitize in progress\u0027 (SSTAT.SAN \u003d\u003d 0x1), passes as success. NVMe sanitize runs in firmware background after the admin command returns, and can take many minutes. _parse_sanitize_status() additionally returns 0 for any value it cannot parse, which also passes the \u003d\u003d 0x3 check.\n\n**Severity**: HIGH | **Confidence**: 0.85\n\n**Impact**: The agent marks a device available and clears Placement reserved while the controller is still sanitizing. If the device is reallocated in that window, the previous tenant\u0027s data may not yet be erased, defeating the security purpose stated in the commit message.\n\n**Priority**: Before merge\n**Recommendation**:\nPoll nvme_sanitize_log until SSTAT.SAN reports \u0027completed successfully\u0027 (0x2), \u0027completed with error\u0027 (0x3) or another terminal value, bounded by [nvme] cleanup_timeout (the single -t bound on the admin command does not cover background sanitization). Fail with DeviceCleanupFailed on timeout or any non-success terminal status, and treat unparseable sstat as a failure rather than 0.","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"3195225741a163ab6883c1f34ef4092cbac729a8","unresolved":true,"context_lines":[{"line_number":226,"context_line":"        \"\"\""},{"line_number":227,"context_line":"        action_code \u003d 4 if action \u003d\u003d CleanupAction.SANITIZE_CES else 2"},{"line_number":228,"context_line":"        timeout_ms \u003d CONF.nvme.cleanup_timeout * 1000"},{"line_number":229,"context_line":"        nvme_cli.nvme_sanitize(nvme_dev, action_code, timeout_ms\u003dtimeout_ms)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"        final_slog \u003d nvme_cli.nvme_sanitize_log(nvme_dev)"},{"line_number":232,"context_line":"        self._log_sanitize_status(nvme_dev, final_slog)"}],"source_content_type":"text/x-python","patch_set":24,"id":"d51b3c3d_b081d9a2","line":229,"in_reply_to":"2307c7bb_b72f7dc7","updated":"2026-09-03 14:42:43.000000000","message":"ya this is a real issue \n\nthat cant happen under any codepath until sanatisation is complete.\n\nif nvme_cli.nvme_sanitize does not block until complete we woudl have to poll\n\nbut since we are usign the timeout we also need  to treat still in progress as an error and raise DeviceCleanupFailed","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"077962772955a1bc8f1ae29e2f5f2692913c778b","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        \"\"\""},{"line_number":227,"context_line":"        action_code \u003d 4 if action \u003d\u003d CleanupAction.SANITIZE_CES else 2"},{"line_number":228,"context_line":"        timeout_ms \u003d CONF.nvme.cleanup_timeout * 1000"},{"line_number":229,"context_line":"        nvme_cli.nvme_sanitize(nvme_dev, action_code, timeout_ms\u003dtimeout_ms)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"        final_slog \u003d nvme_cli.nvme_sanitize_log(nvme_dev)"},{"line_number":232,"context_line":"        self._log_sanitize_status(nvme_dev, final_slog)"}],"source_content_type":"text/x-python","patch_set":24,"id":"b9c8d87c_d3fd1b9c","line":229,"in_reply_to":"d51b3c3d_b081d9a2","updated":"2026-09-04 13:19:19.000000000","message":"Done","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"c1e3df3932de0734bc1c8e29e87ce4e3765679a8","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            slog.get(\u0027sstat\u0027),"},{"line_number":268,"context_line":"        )"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    def _do_write_zeroes(self, nvme_dev, ns_mgmt):"},{"line_number":271,"context_line":"        \"\"\"Write zeroes to the full namespace using ``nvme write-zeroes``."},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        When ``ns_mgmt`` is true, consolidates all namespaces into one"}],"source_content_type":"text/x-python","patch_set":24,"id":"a7092ed0_ed31c503","line":270,"updated":"2026-08-31 11:13:37.000000000","message":"When ns_mgmt is false, _do_write_zeroes() and _do_shred() take nvme_list_ns(), which returns active_nsids[0] (nvme_cli.nvme_list_ns docstring: \u0027Return the first active namespace ID\u0027), and operate only on that one namespace. Controllers that do not support namespace management can still expose multiple statically configured namespaces; every namespace other than the first is left untouched by cleanup.\n\n**Severity**: HIGH | **Confidence**: 0.85\n\n**Impact**: On a supported multi-namespace controller without ns_mgmt, previous-tenant data on all namespaces except the first remains readable after the device is marked available and unreserved, a direct cross-tenant data-remnant risk that the patch exists to prevent.\n\n**Priority**: Before merge\n**Recommendation**:\nIn the non-ns_mgmt path, iterate all namespaces returned by nvme_list_all_ns() and run write-zeroes/shred over each, instead of operating on only the first; alternatively fail cleanup when more than one namespace exists and ns_mgmt is unsupported.","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e56a009a8e70a471f11a1184758fcaba927bc6e1","unresolved":false,"context_lines":[{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        Blocks until nvme-cli returns. Uses ``[nvme] cleanup_timeout`` as the"},{"line_number":250,"context_line":"        command ``--timeout`` value. Reads sanitize-log once afterward for"},{"line_number":251,"context_line":"        logging and to detect an explicit firmware failure (``sstat`` bit 0x3)."},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        :param nvme_dev: Controller path, e.g. ``/dev/nvme0``."},{"line_number":254,"context_line":"        :param action: ``CleanupAction.SANITIZE_CES`` or ``SANITIZE_BES``."}],"source_content_type":"text/x-python","patch_set":26,"id":"3bf33183_1681c0ec","line":251,"updated":"2026-09-04 06:01:44.000000000","message":"The _do_sanitize docstring says sanitize-log is read \u0027to detect an explicit firmware failure (sstat bit 0x3)\u0027 and that the call \u0027blocks until nvme-cli returns\u0027, but the code raises DeviceCleanupFailed for any status !\u003d 0x2, including in-progress (0x1) and never-sanitized (0x0), and the nvme-cli call does not block for the operation (see CF-001).\n\n**Severity**: SUGGESTION | **Confidence**: 0.9\n\n**Impact**: Future maintainers reading the docstring will believe in-progress sanitize results are accepted, which is the opposite of the implemented (and most safety-relevant) behavior.\n\n**Recommendation**:\nReword to state that any final sstat other than 0x2 (completed successfully) - including in-progress 0x1 and failed 0x3 - raises DeviceCleanupFailed.","commit_id":"75b6565a499748677e432f6a82c4812493d8a084"}],"cyborg/accelerator/drivers/nvme/nvme_cli.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"f08492db70ccad92b81a752214af6618b497b824","unresolved":false,"context_lines":[{"line_number":129,"context_line":"        str(flbas),"},{"line_number":130,"context_line":"    )"},{"line_number":131,"context_line":"    # Output: \"create-ns: Success, created nsid:3\" (space after colon is optional)"},{"line_number":132,"context_line":"    if \u0027nsid:\u0027 in out:"},{"line_number":133,"context_line":"        return int(out.split(\u0027nsid:\u0027, 1)[1].split()[0].strip(\u0027,\u0027))"},{"line_number":134,"context_line":"    raise exception.DeviceNotFound(device\u003dnvme_dev)"},{"line_number":135,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"7952fc09_1e147d0e","line":132,"updated":"2026-08-13 14:21:41.000000000","message":"When the nvme create-ns output does not contain \u0027nsid:\u0027, nvme_create_ns raises DeviceNotFound(device\u003dnvme_dev). The namespace was actually created in that scenario; the failure is an output-parsing problem, not a missing device.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: Operators see \u0027Device /dev/nvme0 not found\u0027 for a controller that is present, misdirecting debugging; the driver also loses the chance to report the raw command output that caused the parse failure.\n\n**Suggestion**:\nRaise InvalidConfiguration (as nvme_list_ns does for unexpected output shapes, nvme_cli.py:182) or a DeviceCleanupFailed with the raw output in the reason, so the error reflects an output-format problem on an existing device.","commit_id":"5a43f887d0f0dff019290d6a6852101b0cd89bb8"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"1de2f89f0db1c417e460280ca0f194f9279d452e","unresolved":false,"context_lines":[{"line_number":250,"context_line":"def shred_device(block_dev):"},{"line_number":251,"context_line":"    \"\"\"Quick-clear a block device with ``shred -n0 -z``."},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    Block-layer zeroing is unreliable on NVMe SSDs due to FTL wear leveling;"},{"line_number":254,"context_line":"    prefer sanitize when the device supports it."},{"line_number":255,"context_line":"    \"\"\""},{"line_number":256,"context_line":"    processutils.execute(\u0027shred\u0027, \u0027-n0\u0027, \u0027-z\u0027, block_dev)"}],"source_content_type":"text/x-python","patch_set":17,"id":"f72def86_445581f3","line":253,"updated":"2026-08-21 12:09:29.000000000","message":"This commit adds nvme_cli.check_nvme_cli_installed and nvme_cli.resolve_nvme_dev_from_pci while driver.py keeps its own module-level versions of both. The two resolve_nvme_dev_from_pci implementations already diverge: driver.py\u0027s retries EBUSY via _list_nvme_controllers and takes an injectable sysfs path for tests, while nvme_cli.py\u0027s has no EBUSY handling and hardcodes /sys/bus/pci/devices. Discovery uses the old one, cleanup uses the new one, so PCI-to-nvme0 resolution now has two owners that can drift.\n\n**Severity**: SUGGESTION | **Confidence**: 0.85\n\n**Impact**: The same resolution rule now has two independent implementations; a future fix (e.g. the EBUSY retry or sysfs path handling) applied to one will not reach the other, and discovery and cleanup can resolve a PCI address to a different device path.\n\n**Recommendation**:\nKeep a single implementation: have driver.py delegate to the nvme_cli versions (or move them there and delete the driver.py copies), preserving the EBUSY retry and the injectable sysfs path used by tests.","commit_id":"72faa1c86fee63baf9c816b1bb5529dc03647ce0"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d86848678db0286b4fd2b466c43a530b3b33ee99","unresolved":false,"context_lines":[{"line_number":242,"context_line":""},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"@sys_admin_pctxt.entrypoint"},{"line_number":245,"context_line":"def nvme_list_ns(nvme_dev):"},{"line_number":246,"context_line":"    \"\"\"Return the first active namespace ID on *nvme_dev*.\"\"\""},{"line_number":247,"context_line":"    return _list_all_ns(nvme_dev)[0]"},{"line_number":248,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"1a8d24a8_79ab80c1","line":245,"updated":"2026-09-03 17:40:03.000000000","message":"The new nvme_cli.nvme_list_ns() returns the first active namespace ID, but nothing in the production tree calls it; only its own unit tests exercise it. The driver exclusively uses nvme_list_all_ns().\n\n**Severity**: SUGGESTION | **Confidence**: 0.9\n\n**Impact**: Dead @sys_admin_pctxt.entrypoint code widens the privsep RPC surface and creates a contract (output normalization, exception behavior) that must be maintained and kept compatible without any consumer benefiting from it.\n\n**Recommendation**:\nRemove nvme_list_ns() together with its tests, or, if a first-namespace convenience is genuinely needed, add it at its single call site and remove the standalone wrapper.","commit_id":"9a5fe1d071f6deafb4d12880c6fb0061479e121c"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d86848678db0286b4fd2b466c43a530b3b33ee99","unresolved":false,"context_lines":[{"line_number":257,"context_line":"    processutils.execute(\u0027shred\u0027, \u0027-n0\u0027, \u0027-z\u0027, block_dev)"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":""},{"line_number":260,"context_line":"def resolve_nvme_dev_from_pci(pci_address):"},{"line_number":261,"context_line":"    \"\"\"Map a PCI address to the first NVMe controller device path."},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"    :param pci_address: PCI address string, e.g. ``0000:01:00.0``."}],"source_content_type":"text/x-python","patch_set":25,"id":"a9406830_d3f54549","line":260,"updated":"2026-09-03 17:40:03.000000000","message":"The new nvme_cli module adds a second copy of check_nvme_cli_installed() and a second PCI-address-to-controller resolver alongside the ones already in driver.py. The two resolvers already disagree: driver.py\u0027s uses @filesystem.retry_if_busy and maps EBUSY to DeviceBusy, while nvme_cli.py\u0027s raises DeviceNotFound when the sysfs directory is absent or transiently unreadable.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: Two owners of the \u0027nvme-cli is available\u0027 and \u0027PCI address maps to controller\u0027 invariants can be edited independently and drift further; the drift has already happened, so discovery can see DeviceBusy where cleanup sees DeviceNotFound for the same transient sysfs condition, producing inconsistent failure handling for one hardware state.\n\n**Suggestion**:\nKeep a single canonical implementation in nvme_cli.py (preserving the retry_if_busy/EBUSY semantics) and have driver.py\u0027s discover()/init_host() call it, or have cleanup() reuse driver.py\u0027s resolver instead of adding a second one.","commit_id":"9a5fe1d071f6deafb4d12880c6fb0061479e121c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"077962772955a1bc8f1ae29e2f5f2692913c778b","unresolved":true,"context_lines":[{"line_number":257,"context_line":"    processutils.execute(\u0027shred\u0027, \u0027-n0\u0027, \u0027-z\u0027, block_dev)"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":""},{"line_number":260,"context_line":"def resolve_nvme_dev_from_pci(pci_address):"},{"line_number":261,"context_line":"    \"\"\"Map a PCI address to the first NVMe controller device path."},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"    :param pci_address: PCI address string, e.g. ``0000:01:00.0``."},{"line_number":264,"context_line":"    :returns: Controller path, e.g. ``/dev/nvme0``."},{"line_number":265,"context_line":"    :raises DeviceNotFound: if no NVMe controller is present in sysfs."},{"line_number":266,"context_line":"    \"\"\""},{"line_number":267,"context_line":"    sysfs_path \u003d SYSFS_PCI_DEVICES / pci_address / \u0027nvme\u0027"},{"line_number":268,"context_line":"    if not sysfs_path.is_dir():"},{"line_number":269,"context_line":"        raise exception.DeviceNotFound(device\u003dpci_address)"},{"line_number":270,"context_line":"    controllers \u003d sorted(sysfs_path.iterdir())"},{"line_number":271,"context_line":"    if not controllers:"},{"line_number":272,"context_line":"        raise exception.DeviceNotFound(device\u003dpci_address)"},{"line_number":273,"context_line":"    return \u0027/dev/\u0027 + controllers[0].name"}],"source_content_type":"text/x-python","patch_set":28,"id":"efd3e1c1_7b20146c","line":273,"range":{"start_line":260,"start_character":0,"end_line":273,"end_character":40},"updated":"2026-09-04 13:19:19.000000000","message":"this is not using the nvme-cli and you are ment to be using the filesystem module for all read form /sys and /dev\n\nhttps://github.com/openstack/cyborg/blob/master/cyborg/common/filesystem.py\n\nso this shoudl be in the driver for now and you really shoudl extend the filesystem api for /dev","commit_id":"08d35ca8ff5670f3e1bff4ba64f95f6271bca318"}],"cyborg/agent/manager.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"3d8b89bee46d9312afc04a2781c90c8453c3a735","unresolved":false,"context_lines":[{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    def _set_nvme_placement_reserved(self, context, device, reserved):"},{"line_number":139,"context_line":"        try:"},{"line_number":140,"context_line":"            deployables \u003d objects.Deployable.get_list_by_device_id("},{"line_number":141,"context_line":"                context, device.id"},{"line_number":142,"context_line":"            )"},{"line_number":143,"context_line":"            for dep in deployables:"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f9ff4c2_e98fea95","line":140,"updated":"2026-08-07 16:46:41.000000000","message":"The new code in cyborg/agent/manager.py references objects.Deployable, objects.Attribute, objects.Device, objects.AttachHandle, and cyborg_context.get_admin_context(), but neither \u0027from cyborg import objects\u0027 nor \u0027from cyborg import context as cyborg_context\u0027 is imported in the module. This cause...\n\n**Severity**: CRITICAL | **Confidence**: 1.0\n\n**Risk**: At runtime, _set_nvme_placement_reserved always fails silently (NameError caught by its except). Placement reserved state is never updated when cleanup fails, so a device with failed sanitization holding tenant data could be re-allocated. Unit tests mocking \u0027cyborg.agent.manager.objects.*\u0027 and \u0027c...\n\n**Priority**: Immediate\n**Why This Matters**: At runtime, _set_nvme_placement_reserved always fails silently (NameError caught by its except). Placement reserved state is never updated when cleanup fails, so a device with failed sanitization holding tenant data could be re-allocated. Unit tests mocking \u0027cyborg.agent.manager.objects.*\u0027 and \u0027c...\n\n**Recommendation**:\nAdd \u0027from cyborg import objects\u0027 and \u0027from cyborg import context as cyborg_context\u0027 to the import block in cyborg/agent/manager.py, following the pattern used in cyborg/cmd/status.py and other modules.","commit_id":"ecde3b63875419656f66fe6f85e3b5ce09da594f"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"425913c25bd68adef6af3c972f2c1e2f374509bc","unresolved":false,"context_lines":[{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    def _set_nvme_placement_reserved(self, context, device, reserved):"},{"line_number":139,"context_line":"        try:"},{"line_number":140,"context_line":"            deployables \u003d objects.Deployable.get_list_by_device_id("},{"line_number":141,"context_line":"                context, device.id"},{"line_number":142,"context_line":"            )"},{"line_number":143,"context_line":"            for dep in deployables:"}],"source_content_type":"text/x-python","patch_set":6,"id":"c413ff05_dc838264","line":140,"updated":"2026-08-07 17:30:10.000000000","message":"pep8: F821 Undefined name `objects`","commit_id":"ecde3b63875419656f66fe6f85e3b5ce09da594f"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"425913c25bd68adef6af3c972f2c1e2f374509bc","unresolved":false,"context_lines":[{"line_number":142,"context_line":"            )"},{"line_number":143,"context_line":"            for dep in deployables:"},{"line_number":144,"context_line":"                filters \u003d {\u0027deployable_id\u0027: dep.id, \u0027key\u0027: \u0027rc\u0027}"},{"line_number":145,"context_line":"                attrs \u003d objects.Attribute.get_by_filter(context, filters)"},{"line_number":146,"context_line":"                if not attrs:"},{"line_number":147,"context_line":"                    continue"},{"line_number":148,"context_line":"                rc \u003d attrs[0].value"}],"source_content_type":"text/x-python","patch_set":6,"id":"d92e30f3_344c18ee","line":145,"updated":"2026-08-07 17:30:10.000000000","message":"pep8: F821 Undefined name `objects`","commit_id":"ecde3b63875419656f66fe6f85e3b5ce09da594f"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"3d8b89bee46d9312afc04a2781c90c8453c3a735","unresolved":false,"context_lines":[{"line_number":156,"context_line":"                device.uuid,"},{"line_number":157,"context_line":"            )"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def _reconcile_device_states(self):"},{"line_number":160,"context_line":"        try:"},{"line_number":161,"context_line":"            self._do_reconcile_device_states()"},{"line_number":162,"context_line":"        except Exception:"}],"source_content_type":"text/x-python","patch_set":6,"id":"4201e255_95447c0f","line":159,"updated":"2026-08-07 16:46:41.000000000","message":"The _reconcile_device_states() and _do_reconcile_device_states() methods added to AgentManager are never invoked from init_host() or any periodic task. The device state reconciliation logic will never run, making it dead code.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: Devices stuck in \u0027cleaning\u0027 or \u0027pending_cleaning\u0027 state from a crashed agent will not be transitioned to \u0027error\u0027 on restart. Allocated devices with no active ARQs will not trigger cleanup. The reconciliation feature is effectively non-functional.\n\n**Suggestion**:\nAdd a call to self._reconcile_device_states() in init_host() after self._rt.check_duplicate_devices(), or wire it into a periodic task, so the reconciliation logic actually executes.","commit_id":"ecde3b63875419656f66fe6f85e3b5ce09da594f"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"425913c25bd68adef6af3c972f2c1e2f374509bc","unresolved":false,"context_lines":[{"line_number":166,"context_line":"            )"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    def _do_reconcile_device_states(self):"},{"line_number":169,"context_line":"        context \u003d cyborg_context.get_admin_context()"},{"line_number":170,"context_line":"        devices \u003d objects.Device.get_list_by_hostname("},{"line_number":171,"context_line":"            context,"},{"line_number":172,"context_line":"            self.resource_provider_name,"}],"source_content_type":"text/x-python","patch_set":6,"id":"642fe125_dad2a09b","line":169,"updated":"2026-08-07 17:30:10.000000000","message":"pep8: F821 Undefined name `cyborg_context`","commit_id":"ecde3b63875419656f66fe6f85e3b5ce09da594f"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"425913c25bd68adef6af3c972f2c1e2f374509bc","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    def _do_reconcile_device_states(self):"},{"line_number":169,"context_line":"        context \u003d cyborg_context.get_admin_context()"},{"line_number":170,"context_line":"        devices \u003d objects.Device.get_list_by_hostname("},{"line_number":171,"context_line":"            context,"},{"line_number":172,"context_line":"            self.resource_provider_name,"},{"line_number":173,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":6,"id":"aaa1006b_9b38f206","line":170,"updated":"2026-08-07 17:30:10.000000000","message":"pep8: F821 Undefined name `objects`","commit_id":"ecde3b63875419656f66fe6f85e3b5ce09da594f"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"425913c25bd68adef6af3c972f2c1e2f374509bc","unresolved":false,"context_lines":[{"line_number":197,"context_line":"                        device.save(context)"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    def _has_active_arqs(self, context, device):"},{"line_number":200,"context_line":"        deployables \u003d objects.Deployable.get_list_by_device_id("},{"line_number":201,"context_line":"            context,"},{"line_number":202,"context_line":"            device.id,"},{"line_number":203,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":6,"id":"5b489ee9_fd03f584","line":200,"updated":"2026-08-07 17:30:10.000000000","message":"pep8: F821 Undefined name `objects`","commit_id":"ecde3b63875419656f66fe6f85e3b5ce09da594f"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"425913c25bd68adef6af3c972f2c1e2f374509bc","unresolved":false,"context_lines":[{"line_number":202,"context_line":"            device.id,"},{"line_number":203,"context_line":"        )"},{"line_number":204,"context_line":"        for dep in deployables:"},{"line_number":205,"context_line":"            ahs \u003d objects.AttachHandle.get_ah_list_by_deployable_id("},{"line_number":206,"context_line":"                context,"},{"line_number":207,"context_line":"                dep.id,"},{"line_number":208,"context_line":"            )"}],"source_content_type":"text/x-python","patch_set":6,"id":"b41cedc6_d8f19472","line":205,"updated":"2026-08-07 17:30:10.000000000","message":"pep8: F821 Undefined name `objects`","commit_id":"ecde3b63875419656f66fe6f85e3b5ce09da594f"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e028be7449e99a0169356692d090d2495ab7b013","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        self._rt \u003d ResourceTracker(self.resource_provider_name, self.cond_api)"},{"line_number":104,"context_line":"        self._cleanup_executor \u003d futurist.ThreadPoolExecutor(max_workers\u003d4)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def del_host(self):"},{"line_number":107,"context_line":"        self._cleanup_executor.shutdown(wait\u003dTrue)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def init_host(self):"}],"source_content_type":"text/x-python","patch_set":19,"id":"d69226f4_8cb50bfe","line":106,"updated":"2026-08-24 16:00:10.000000000","message":"The commit renames AgentManager.shutdown() to del_host(), but the service layer still calls manager.shutdown() on stop. RPCService.stop() in cyborg/common/service.py:74 invokes self.manager.shutdown(), which now raises AttributeError; the surrounding try/except merely logs the error, so _cleanup_executor.shutdown(wait\u003dTrue) is never reached and del_host() is dead code outside its unit test.\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Impact**: Every agent stop logs an exception instead of draining the cleanup executor; in-flight cleanups may be abandoned mid-erase and threads are not joined, and the graceful-shutdown contract the method was written for is broken.\n\n**Priority**: Before merge\n**Recommendation**:\nKeep the method named shutdown() (or update cyborg/common/service.py to call del_host()) so the RPCService stop path actually drains the executor. Add a test that exercises the service stop path, not only the manager method directly.","commit_id":"00f0eab12d2c0a3a86ffe85e26393bc76fd11c11"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e028be7449e99a0169356692d090d2495ab7b013","unresolved":false,"context_lines":[{"line_number":136,"context_line":"            self._set_nvme_placement_reserved(context, device, True)"},{"line_number":137,"context_line":"            raise"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        try:"},{"line_number":140,"context_line":"            future.result(timeout\u003dCONF.nvme.cleanup_timeout)"},{"line_number":141,"context_line":"        except concurrent.futures.TimeoutError:"},{"line_number":142,"context_line":"            LOG.error("}],"source_content_type":"text/x-python","patch_set":19,"id":"f563192f_295bdd2d","line":139,"updated":"2026-08-24 16:00:10.000000000","message":"When future.result(timeout\u003d...) times out, cleanup_device() marks the device ERROR and reserves Placement inventory, but the worker thread _run_cleanup_async() keeps running. When the work eventually finishes it unconditionally sets device_state to AVAILABLE and clears the reserved count, overwriting the timeout outcome with no coordination between the two writers.\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Impact**: A device whose erase exceeded the timeout can silently transition back to AVAILABLE with reserved\u003d0 while cleanup is still executing, allowing re-allocation of a device that was deliberately fenced off - contradicting the safety guarantee stated in the commit message and the release note. Two concurrent device.save() calls also risk lost updates.\n\n**Priority**: Before merge\n**Recommendation**:\nMake the worker state-aware: have _run_cleanup_async re-read/refresh the device and skip the AVAILABLE transition if the device is already in ERROR (e.g. compare-and-set or a per-device \u0027timed_out\u0027 flag shared with the timeout handler), or cancel/fence the future before the timeout handler persists ERROR.","commit_id":"00f0eab12d2c0a3a86ffe85e26393bc76fd11c11"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"c1e3df3932de0734bc1c8e29e87ce4e3765679a8","unresolved":false,"context_lines":[{"line_number":136,"context_line":"            raise"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        try:"},{"line_number":139,"context_line":"            future.result(timeout\u003dCONF.nvme.cleanup_timeout)"},{"line_number":140,"context_line":"        except concurrent.futures.TimeoutError:"},{"line_number":141,"context_line":"            LOG.error("},{"line_number":142,"context_line":"                \u0027Cleanup for %s did not complete within %ds\u0027,"}],"source_content_type":"text/x-python","patch_set":24,"id":"70b6a99c_7837615a","line":139,"updated":"2026-08-31 11:13:37.000000000","message":"On timeout, cleanup_device() sets the device to error and reserves it in Placement, but the worker thread keeps running _run_cleanup_async(). When the sanitize/write-zeroes work eventually finishes, the worker unconditionally sets device_state \u003d available and calls set_nvme_placement_reserved(device, False), silently reverting the timeout outcome. Both threads also mutate and save the same in-memory device object concurrently.\n\n**Severity**: HIGH | **Confidence**: 0.85\n\n**Impact**: A slow-but-eventually-succeeding cleanup clears the reserved fence and flips the device back to available without operator involvement, contradicting the documented behaviour; interleaved saves from two threads can also persist a stale device state.\n\n**Priority**: Before merge\n**Recommendation**:\nMake the worker aware that the waiter gave up: capture the future (or an Event) before submit and have _run_cleanup_async skip state updates when future.done() is false-side/timeout flag is set, or set a \u0027timed out\u0027 generation on the device that the worker checks before writing AVAILABLE and unreserving.","commit_id":"e5d0b8a656b2a08ce5079ae1954fc4fcf876a865"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d86848678db0286b4fd2b466c43a530b3b33ee99","unresolved":false,"context_lines":[{"line_number":138,"context_line":"            raise"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        try:"},{"line_number":141,"context_line":"            future.result(timeout\u003dCONF.nvme.cleanup_timeout)"},{"line_number":142,"context_line":"        except concurrent.futures.TimeoutError:"},{"line_number":143,"context_line":"            LOG.error("},{"line_number":144,"context_line":"                \u0027Cleanup for %s did not complete within %ds\u0027,"}],"source_content_type":"text/x-python","patch_set":25,"id":"42f015ee_5a4bbaf1","line":141,"updated":"2026-09-03 17:40:03.000000000","message":"cleanup_device() blocks on future.result(timeout\u003dCONF.nvme.cleanup_timeout) and, on TimeoutError, sets device_state\u003dERROR and marks Placement inventory reserved. But the worker thread running _run_cleanup_async() is never cancelled and holds the same shared in-memory Device object; when the underlying cleanup finally returns it unconditionally writes its own transition (AVAILABLE + reserved\u003dFalse on success, ERROR on failure). Final state is last-writer-wins and non-deterministic.\n\n**Severity**: HIGH | **Confidence**: 0.85\n\n**Impact**: Two opposite wrong outcomes are reachable: a device that actually completed cleanup can be stranded in ERROR with reserved Placement inventory until an operator intervenes; and a device the manager declared ERROR/reserved can silently flip to AVAILABLE and unreserved while an operator is already intervening based on the error signal. Both contradict the documented behavior and can mislead allocation decisions.\n\n**Priority**: Before merge\n**Recommendation**:\nMake the worker the sole owner of post-cleanup transitions: on timeout set a per-device abort flag/event that _run_cleanup_async checks before setting AVAILABLE and clearing reserved (or have the worker re-read device_state from the DB and skip if it is already ERROR). Add a unit test where the worker finishes after future.result() times out asserting the ERROR/reserved state is preserved.","commit_id":"9a5fe1d071f6deafb4d12880c6fb0061479e121c"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"94d00ffe94d42a160041b35b1d5191b1ee8daa7c","unresolved":false,"context_lines":[{"line_number":137,"context_line":"            placement.set_nvme_placement_reserved(device, True)"},{"line_number":138,"context_line":"            raise"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        try:"},{"line_number":141,"context_line":"            future.result(timeout\u003dCONF.nvme.cleanup_timeout)"},{"line_number":142,"context_line":"        except concurrent.futures.TimeoutError:"},{"line_number":143,"context_line":"            LOG.error("}],"source_content_type":"text/x-python","patch_set":28,"id":"f4df3632_3c087065","line":140,"updated":"2026-09-04 06:59:53.000000000","message":"On future.result() timeout, cleanup_device sets device_state\u003dERROR and reserves Placement inventory, but the worker thread keeps running. _run_cleanup_async unconditionally sets AVAILABLE and clears the reservation on success (manager.py:168-170) with no check of the device\u0027s current state, so a cleanup that finishes after the timeout flips the ERROR/reserved device back to available and unreserved. The final device state is whichever writer saves last and is nondeterministic.\n\n**Severity**: HIGH | **Confidence**: 0.75\n\n**Impact**: A device whose erase was never confirmed within the bound becomes available again without operator verification, contradicting the documented safety behavior; the race also produces nondeterministic device/Placement state that operators cannot reason about.\n\n**Priority**: Before merge\n**Recommendation**:\nRecord the timeout (e.g. a per-device/event marker) and have _run_cleanup_async check it before overwriting state: if the timeout already fired, keep ERROR+reserved and log for the operator. Alternatively coordinate via a per-cleanup threading.Event shared between the handler and the worker, and add a unit test covering worker success after timeout.","commit_id":"08d35ca8ff5670f3e1bff4ba64f95f6271bca318"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"ee0b970e022ed8cea65bfa2d0241cb92eae6955b","unresolved":false,"context_lines":[{"line_number":130,"context_line":"            self.cond_api.cleanup_complete(context, device, success\u003dFalse)"},{"line_number":131,"context_line":"            raise"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"        try:"},{"line_number":134,"context_line":"            future.result(timeout\u003dCONF.nvme.cleanup_timeout)"},{"line_number":135,"context_line":"        except concurrent.futures.TimeoutError:"},{"line_number":136,"context_line":"            LOG.error("}],"source_content_type":"text/x-python","patch_set":29,"id":"600a351a_b3bbe3eb","line":133,"updated":"2026-09-05 04:46:10.000000000","message":"When cleanup_device() times out it sends cleanup_complete(success\u003dFalse), but the futurist worker thread keeps running and _run_cleanup_async() unconditionally sends its own cleanup_complete(success\u003dTrue/False) when the driver eventually returns. One dispatch can therefore produce two unordered terminal RPCs; conductor cleanup_complete() has no request id or state guard and blindly overwrites device_state and Placement reserved counts.\n\n**Severity**: HIGH | **Confidence**: 0.8\n\n**Impact**: A device the conductor already fenced in ERROR on timeout is silently flipped back to AVAILABLE (reserved reconciled to in-use) by the late success report. Worse, if the operator retries cleanup after the false failure, a stale terminal report can overwrite the new PENDING_CLEANING state and return a device to the pool while its second erase is still in flight, exposing unwiped tenant data. State transitions are no longer single-shot.\n\n**Priority**: Before merge\n**Recommendation**:\nGuarantee exactly one terminal report per dispatch: e.g. track reported state with a threading.Event (or use future.add_done_callback plus a timeout-side flag) so the timeout path and the worker path cannot both report, and/or have conductor cleanup_complete() validate the expected PENDING_CLEANING state before transitioning. Add a unit test that simulates a late worker completion after a timeout and asserts only one cleanup_complete RPC is sent.","commit_id":"c753ada1d9bbbf5f05d72d958c1a2126c14f77d2"}],"cyborg/tests/unit/accelerator/drivers/nvme/test_driver.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"7c72e40a0dd488eca5935d2881741dacdcd6d28a","unresolved":false,"context_lines":[{"line_number":390,"context_line":"    return device"},{"line_number":391,"context_line":""},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"class TestNVMeDriverCleanup(base.TestCase):"},{"line_number":394,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_sanitize\u0027)"},{"line_number":395,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_sanitize_log\u0027)"},{"line_number":396,"context_line":"    def test_sanitize_ces(self, mock_log, mock_san):"}],"source_content_type":"text/x-python","patch_set":4,"id":"69238278_c7db3ba0","line":393,"updated":"2026-08-06 17:07:49.000000000","message":"The _poll_sanitize method has a timeout code path that raises DeviceCleanupFailed when the polling deadline is exceeded. None of the new tests exercise this path. All sanitize tests resolve within two sanitize-log mock calls (one for _do_sanitize, one for _poll_sanitize), so the timeout branch at...\n\n**Severity**: SUGGESTION | **Confidence**: 0.9\n\n**Benefit**: The timeout error handling code (lines 336-339) is untested. A regression in the timeout calculation (e.g., wrong deadline arithmetic) or the exception construction could go undetected. The timeout path is important because it prevents cleanup from hanging indefinitely on a stuck device.\n\n**Recommendation**:\nAdd a test that mocks nvme_sanitize_log to always return an in-progress status (e.g., sprog\u003d0x1000, sstat\u003d0x2) so the while loop exhausts the deadline, and assert that DeviceCleanupFailed is raised. Mock time.monotonic and time.sleep to avoid real delays.","commit_id":"06c54c9ca00f6ea76abb6f7c0529d021511af6ad"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"077962772955a1bc8f1ae29e2f5f2692913c778b","unresolved":true,"context_lines":[{"line_number":334,"context_line":""},{"line_number":335,"context_line":""},{"line_number":336,"context_line":"def _make_device(cleanup_action, ns_mgmt\u003dFalse):"},{"line_number":337,"context_line":"    device \u003d mock.Mock()"},{"line_number":338,"context_line":"    device.std_board_info \u003d jsonutils.dumps("},{"line_number":339,"context_line":"        {"},{"line_number":340,"context_line":"            \u0027cleanup_action\u0027: cleanup_action,"}],"source_content_type":"text/x-python","patch_set":28,"id":"b3901ac5_a743f5f6","line":337,"range":{"start_line":337,"start_character":12,"end_line":337,"end_character":24},"updated":"2026-09-04 13:19:19.000000000","message":"as i said else wehre this is almost alwasy not corect\n\nyou shoudl be at elast using create_autospec here but really we shoudl be using reas device obejct where possible.","commit_id":"08d35ca8ff5670f3e1bff4ba64f95f6271bca318"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"077962772955a1bc8f1ae29e2f5f2692913c778b","unresolved":true,"context_lines":[{"line_number":355,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_sanitize_log\u0027)"},{"line_number":356,"context_line":"    def test_sanitize_ces(self, mock_log, mock_san):"},{"line_number":357,"context_line":"        mock_log.return_value \u003d {\u0027sprog\u0027: 0xFFFF, \u0027sstat\u0027: 0x2}"},{"line_number":358,"context_line":"        self.driver.cleanup(_make_device(\u0027sanitize_ces\u0027))"},{"line_number":359,"context_line":"        mock_san.assert_called_once_with("},{"line_number":360,"context_line":"            \u0027/dev/nvme0\u0027,"},{"line_number":361,"context_line":"            nvme_driver.SanitizeAction.CRYPTO_ERASE,"}],"source_content_type":"text/x-python","patch_set":28,"id":"3ea62ac9_098d53fa","line":358,"range":{"start_line":358,"start_character":20,"end_line":358,"end_character":27},"updated":"2026-09-04 13:19:19.000000000","message":"i mention this later but calling clean form test_sanitize_ces is incorect\n\nyou ether need to rename this to somethign liek test_cleanup_sanitize_ces\n\nand still test each of the do_satntize modes serpeately or rewirte this.\n\nyou shoudl not be unit testing across multiple levels fo fucntion calls like this.\n\nthis applies to most of these tests. they are ment to be unit test not functioal tests and you kind of in a middelground between teh too right now.","commit_id":"08d35ca8ff5670f3e1bff4ba64f95f6271bca318"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"077962772955a1bc8f1ae29e2f5f2692913c778b","unresolved":true,"context_lines":[{"line_number":559,"context_line":"            mock_shred.call_args_list,"},{"line_number":560,"context_line":"        )"},{"line_number":561,"context_line":""},{"line_number":562,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_attach_ns\u0027)"},{"line_number":563,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_list_all_ns\u0027)"},{"line_number":564,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_ns_rescan\u0027)"},{"line_number":565,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_create_ns\u0027)"},{"line_number":566,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_delete_ns\u0027)"},{"line_number":567,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_write_zeroes\u0027)"},{"line_number":568,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_id_ns\u0027)"},{"line_number":569,"context_line":"    @mock.patch.object(nvme_cli, \u0027nvme_id_ctrl\u0027)"},{"line_number":570,"context_line":"    def test_consolidates_namespaces("},{"line_number":571,"context_line":"        self,"},{"line_number":572,"context_line":"        mock_id_ctrl,"}],"source_content_type":"text/x-python","patch_set":28,"id":"65eff29d_9ca14b58","line":569,"range":{"start_line":562,"start_character":3,"end_line":569,"end_character":48},"updated":"2026-09-04 13:19:19.000000000","message":"why didnt you autospec theses\n\n\ni also think instead of doing this you shoudl be condierign a fixture or fake instead.\n\n\nbut beyond that you are not actully tsting properly\n\n\nthis is test_consolidates_namespaces\n\nbut you are not calling driver._consolidates_namespaces\n\nyou are calling driver.clenup\n\nthis function shoudl be testing _consolidates_namespaces not cleanup\n\neach unit test shoudl try to test on fucntion in isolation wehre reasonable to do so.\n\ntesting test_consolidates_namespaces shjoudl nto as a reasult exersie the enclsuing logic in cleanup espelcily when its only called indirectly via cleanup-\u003e_do_write_zeroes-\u003e_consolidate_namespaces","commit_id":"08d35ca8ff5670f3e1bff4ba64f95f6271bca318"}],"releasenotes/notes/nvme-cleanup-999940a1b2c3.yaml":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"1de2f89f0db1c417e460280ca0f194f9279d452e","unresolved":false,"context_lines":[{"line_number":6,"context_line":"upgrade:"},{"line_number":7,"context_line":"  - |"},{"line_number":8,"context_line":"    Operators using ``nvme_driver`` can tune ``[nvme] cleanup_timeout`` for"},{"line_number":9,"context_line":"    their environment. If cleanup exceeds that timeout, the device stays"},{"line_number":10,"context_line":"    unavailable until the device is cleaned."}],"source_content_type":"text/x-yaml","patch_set":17,"id":"c59d715a_ad565c17","line":9,"updated":"2026-08-21 12:09:29.000000000","message":"The upgrade note reads \u0027If cleanup exceeds that timeout, the device stays unavailable until the device is cleaned.\u0027 The clause is circular (\u0027until the device is cleaned\u0027 says nothing about who acts) and omits what actually happens: the device is set to error state and its Placement inventory stays reserved until an operator intervenes.\n\n**Severity**: SUGGESTION | **Confidence**: 0.9\n\n**Impact**: Operators reading the release note get a confusing, near-tautological description of the timeout behavior and are not told the device requires manual intervention (error state + reserved inventory).\n\n**Recommendation**:\nReword, e.g.: \u0027If cleanup exceeds that timeout, the device is put into error state and its Placement inventory remains reserved so it is not reallocated until an operator cleans it and returns it to available.\u0027","commit_id":"72faa1c86fee63baf9c816b1bb5529dc03647ce0"}]}
