)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"2ac6cd77a20241172d2c2d4ad1a74133d14518c3","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Rajat Dhasmana \u003crajatdhasmana@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-10-12 12:40:47 +0530"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add df-hmac-chap support in lvm driver"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: I3c1ead92e3c3c258197432ca82846ce3158f1b61"},{"line_number":10,"context_line":"Signed-off-by: Rajat Dhasmana \u003crajatdhasmana@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"21b6e2c0_6529f12d","line":7,"range":{"start_line":7,"start_character":0,"end_line":7,"end_character":38},"updated":"2026-10-12 13:55:59.000000000","message":"typo - df / dh","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"5963df91_316d6a03","updated":"2026-10-12 13:44:59.000000000","message":"Early design feedback, since the patch adds options and helpers but does not yet wire anything into `initialize_connection` or nvmet:\n\n  1. In nvmet the key lives on the host entry (hosts/\u003chostnqn\u003e/dhchap_key and dhchap_ctrl_key), one key per host NQN, not per volume. A per-volume key in provider_auth breaks as soon as a host attaches two volumes. The key needs to be keyed by connector NQN.\n  2. Authentication requires allow_any_host\u003d0 and per-host entries linked into allowed_hosts; the target currently sets allow_any_host\u003d1 and the privsep nvmet wrapper has no Host class, so most of the work is still ahead.\n  3. Please generate the secret in Cinder rather than importing the os-brick initiator connector (inline). nvme-cli 3.0 deprecated the command the os-brick helper wraps.\n  4. A spec or at least a blueprint would help: this adds a new connection-properties contract, three config options and a new provider_auth format. Commit message typo: \"df-hmac-chap\".","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"}],"cinder/volume/driver.py":[{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":327,"context_line":"               help\u003d\u0027Namespace id for the subsystem for the LVM volume when \u0027"},{"line_number":328,"context_line":"                    \u0027not sharing targets.  The minimum id value when sharing.\u0027"},{"line_number":329,"context_line":"                    \u0027Maximum supported value in Linux is 8192\u0027),"},{"line_number":330,"context_line":"    cfg.BoolOpt(\u0027nvmet_dhchap_enabled\u0027,"},{"line_number":331,"context_line":"                default\u003dFalse,"},{"line_number":332,"context_line":"                help\u003d\u0027Enable DH-HMAC-CHAP authentication for NVMe-oF \u0027"},{"line_number":333,"context_line":"                     \u0027connections. When enabled, host and controller \u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"45f08c51_7f3e60c4","line":330,"updated":"2026-10-12 13:44:59.000000000","message":"Naming: nvme-cli 3.0 calls the protocol KX-HMAC-CHAP and treats \"dhchap\" as the legacy spelling. Config option names are forever, so something neutral like `nvmet_auth_enabled` / `nvmet_auth_hmac` / `nvmet_auth_bidirectional` would age better.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":332,"context_line":"                help\u003d\u0027Enable DH-HMAC-CHAP authentication for NVMe-oF \u0027"},{"line_number":333,"context_line":"                     \u0027connections. When enabled, host and controller \u0027"},{"line_number":334,"context_line":"                     \u0027authentication keys will be generated and configured \u0027"},{"line_number":335,"context_line":"                     \u0027for each volume. Requires kernel 6.0+ with \u0027"},{"line_number":336,"context_line":"                     \u0027CONFIG_NVME_TARGET_AUTH enabled.\u0027),"},{"line_number":337,"context_line":"    cfg.StrOpt(\u0027nvmet_dhchap_key_hmac\u0027,"},{"line_number":338,"context_line":"               choices\u003d[\u00270\u0027, \u00271\u0027, \u00272\u0027, \u00273\u0027],"}],"source_content_type":"text/x-python","patch_set":1,"id":"ea6e495a_5e32a619","line":335,"updated":"2026-10-12 13:44:59.000000000","message":"Wrong granularity. nvmet stores `dhchap_key` and `dhchap_ctrl_key` on the host entry under `/sys/kernel/config/nvmet/hosts/\u003chostnqn\u003e/`, one per host NQN. A per-volume key would overwrite the host\u0027s key on the second attach and break the first connection on reconnect. The key must be per connector NQN, generated on first attach and reused.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":334,"context_line":"                     \u0027authentication keys will be generated and configured \u0027"},{"line_number":335,"context_line":"                     \u0027for each volume. Requires kernel 6.0+ with \u0027"},{"line_number":336,"context_line":"                     \u0027CONFIG_NVME_TARGET_AUTH enabled.\u0027),"},{"line_number":337,"context_line":"    cfg.StrOpt(\u0027nvmet_dhchap_key_hmac\u0027,"},{"line_number":338,"context_line":"               choices\u003d[\u00270\u0027, \u00271\u0027, \u00272\u0027, \u00273\u0027],"},{"line_number":339,"context_line":"               default\u003d\u00271\u0027,"},{"line_number":340,"context_line":"               help\u003d\u0027HMAC algorithm for DH-CHAP key generation: \u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"ee06e7a8_e33e7266","line":337,"updated":"2026-10-12 13:44:59.000000000","message":"Should be an `IntOpt` with min\u003d0, max\u003d3 rather than digit strings.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":340,"context_line":"               help\u003d\u0027HMAC algorithm for DH-CHAP key generation: \u0027"},{"line_number":341,"context_line":"                    \u00270\u003dnone, 1\u003dSHA-256, 2\u003dSHA-384, 3\u003dSHA-512. \u0027"},{"line_number":342,"context_line":"                    \u0027Default is SHA-256 (1).\u0027),"},{"line_number":343,"context_line":"    cfg.BoolOpt(\u0027nvmet_dhchap_bidirectional\u0027,"},{"line_number":344,"context_line":"                default\u003dTrue,"},{"line_number":345,"context_line":"                help\u003d\u0027Enable bidirectional DH-CHAP authentication. When true, \u0027"},{"line_number":346,"context_line":"                     \u0027both host and controller keys are generated for mutual \u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"f86689e4_2696099d","line":343,"updated":"2026-10-12 13:44:59.000000000","message":"Fine as a default, but the help should say the controller key is also set on the nvmet host entry (`dhchap_ctrl_key`) and passed to the initiator, with the same kernel/nvme-cli requirements.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"}],"cinder/volume/targets/nvmet.py":[{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":21,"context_line":"from cinder.volume.targets import nvmeof"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"try:"},{"line_number":24,"context_line":"    from os_brick.initiator.connectors import nvmeof as nvmeof_connector"},{"line_number":25,"context_line":"except ImportError:"},{"line_number":26,"context_line":"    nvmeof_connector \u003d None"},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"efc188cc_778ba0a6","line":24,"updated":"2026-10-12 13:44:59.000000000","message":"I\u0027d rather not import the initiator connector into the target layer:\n\n  * os-brick is a hard requirement of Cinder, so the try/except ImportError only hides a real breakage.\n  * It couples this change to a new os-brick API (Depends-On, release, requirements bump) for roughly ten lines of Python.\n  * The os-brick helper wraps \u0027nvme gen-dhchap-key\u0027, which nvme-cli 3.0 deprecated (warns, removed in 4.0), and on 2.x with hmac !\u003d 0 it derives from the local `/etc/nvme/hostnqn`, which a cinder-volume node usually lacks.\nSuggest a small helper here: secret \u003d secrets.token_bytes(32|48|64); data \u003d secret + struct.pack(\u0027\u003cI\u0027, zlib.crc32(secret)); return \u0027DHHC-1:%02x:%s:\u0027 % (hmac, base64.b64encode(data).decode()).","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    # #######  DH-CHAP authentication methods ########"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def _generate_dhchap_keys(self):"},{"line_number":50,"context_line":"        \"\"\"Generate DH-HMAC-CHAP authentication keys."},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"        Uses os-brick\u0027s nvme-cli wrapper to generate cryptographically"}],"source_content_type":"text/x-python","patch_set":1,"id":"58a0bac7_e33d2992","line":49,"updated":"2026-10-12 13:44:59.000000000","message":"See `driver.py` L335: this needs to take the connector\u0027s host NQN and persist the key for that host, not for the volume.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":77,"context_line":"                raise exception.CinderException("},{"line_number":78,"context_line":"                    \"Failed to generate DH-CHAP controller key\")"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"        LOG.debug(\u0027Generated DH-CHAP keys: host_key\u003d%s... ctrl_key\u003d%s\u0027,"},{"line_number":81,"context_line":"                  host_key[:20] if host_key else None,"},{"line_number":82,"context_line":"                  \u0027present\u0027 if ctrl_key else \u0027None\u0027)"},{"line_number":83,"context_line":"        return (host_key, ctrl_key)"}],"source_content_type":"text/x-python","patch_set":1,"id":"968fc1cb_2adf0697","line":80,"updated":"2026-10-12 13:44:59.000000000","message":"The first 20 characters are the 10-character \"DHHC-1:01:\" header plus 10 characters of the secret. Please log nothing of the key, not even a prefix. A \"present\" marker is enough.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":82,"context_line":"                  \u0027present\u0027 if ctrl_key else \u0027None\u0027)"},{"line_number":83,"context_line":"        return (host_key, ctrl_key)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    def _get_target_dhchap_auth(self, context, volume):"},{"line_number":86,"context_line":"        \"\"\"Get the current DH-CHAP auth keys from database."},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        Retrieves authentication credentials stored in provider_auth field."}],"source_content_type":"text/x-python","patch_set":1,"id":"3c3edcfa_a6890fed","line":85,"updated":"2026-10-12 13:44:59.000000000","message":"`provider_auth` is per volume, so it cannot hold a per-host key (see above). If it is kept for something, this also adds a DB round trip per call for the non-auth case.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":117,"context_line":"        \"\"\""},{"line_number":118,"context_line":"        if ctrl_key:"},{"line_number":119,"context_line":"            return \"DHCHAP %s %s\" % (host_key, ctrl_key)"},{"line_number":120,"context_line":"        return \"DHCHAP %s\" % host_key"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"    # #######  Connection initiation methods ########"},{"line_number":123,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"78d0f3e6_5a7981d3","line":120,"updated":"2026-10-12 13:44:59.000000000","message":"Same naming point as the config options: this tag is persisted in the DB. \"NVME-CHAP\" or \"KXCHAP\" would not carry the legacy name.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"},{"author":{"_account_id":13425,"name":"Simon Dodsley","email":"simon@everpuredata.com","username":"sdodsley"},"change_message_id":"93293f58bf2751cc89df0d14927d42c77c06d262","unresolved":true,"context_lines":[{"line_number":199,"context_line":"        subsystem_section \u003d {"},{"line_number":200,"context_line":"            \"allowed_hosts\": [],"},{"line_number":201,"context_line":"            \"attr\": {"},{"line_number":202,"context_line":"                \"allow_any_host\": \"1\""},{"line_number":203,"context_line":"            },"},{"line_number":204,"context_line":"            \"namespaces\": [self._namespace_dict(uuid, volume_path, ns_id)],"},{"line_number":205,"context_line":"            \"nqn\": nqn}"}],"source_content_type":"text/x-python","patch_set":1,"id":"7c71ee6b_374b20d8","line":202,"updated":"2026-10-12 13:44:59.000000000","message":"Not changed by this patch, but it is the crux: with authentication enabled the subsystem needs `allow_any_host\u003d0`, a hosts/\u003cnqn\u003e entry with `dhchap_key` / `dhchap_ctrl_key` / `dhchap_hash`, and the host linked into allowed_hosts. That also means `cinder/privsep/targets/nvmet.py` needs a `Host` wrapper. Worth outlining the plan in the commit message or a spec.","commit_id":"568ababe5ff2282c4b729feb2c07746ea55f9a00"}]}
