)]}'
{"cinder/volume/manager.py":[{"author":{"_account_id":36171,"name":"jayaanand borra","display_name":"jayaanand borra","email":"jayaanand.borra@netapp.com","username":"jayaanan","status":"netapp"},"change_message_id":"41a3ce33086e24f1da7d9b9db9d9aab0ae5a25e9","unresolved":true,"context_lines":[{"line_number":266,"context_line":"            ctxt, constants.VOLUME_BINARY)"},{"line_number":267,"context_line":"        suffix \u003d \u0027@%s\u0027 % backend_id"},{"line_number":268,"context_line":"        for service in services:"},{"line_number":269,"context_line":"            if service.host.endswith(suffix):"},{"line_number":270,"context_line":"                return service"},{"line_number":271,"context_line":"        raise exception.ServiceNotFound(service_id\u003dbackend_id)"},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"8eb165db_646db46c","line":269,"updated":"2026-09-27 16:41:59.000000000","message":"service.host.endswith(\u0027@\u0027 + backend_id) is true for a longer backend name. \u0027host@myceph\u0027.endswith(\u0027@ceph\u0027) is true. \u0027host@ceph-secondary\u0027.endswith(\u0027@secondary\u0027) is true. The loop returns the first row from ServiceList.get_all_by_binary (cinder/objects/service.py:240-244).\n\nService.host is nullable (cinder/objects/service.py:55). A None host raises AttributeError on endswith. The handler at manager.py:4549 catches only ServiceNotFound, so that AttributeError aborts failover too.\n\n_get_service already resolves a backend with extract_host(host, \u0027backend\u0027) and Service.get_by_args (lines 255-256). Compare that backend name for equality, or remove this helper. A suffix match is wrong for both the host rewrite and the volume query below.","commit_id":"9d5cf4b8d8887ed69102d9a3bbcdef44a666edbf"},{"author":{"_account_id":36171,"name":"jayaanand borra","display_name":"jayaanand borra","email":"jayaanand.borra@netapp.com","username":"jayaanan","status":"netapp"},"change_message_id":"41a3ce33086e24f1da7d9b9db9d9aab0ae5a25e9","unresolved":true,"context_lines":[{"line_number":4553,"context_line":"                    filters \u003d {\u0027cluster_name\u0027: active_service.cluster_name}"},{"line_number":4554,"context_line":"                else:"},{"line_number":4555,"context_line":"                    filters \u003d {\u0027host\u0027: active_service.host}"},{"line_number":4556,"context_line":"                volumes \u003d objects.VolumeList.get_all(context, filters\u003dfilters)"},{"line_number":4557,"context_line":"        else:"},{"line_number":4558,"context_line":"            volumes \u003d self._get_my_volumes(context)"},{"line_number":4559,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3c8558b2_112fc371","line":4556,"updated":"2026-09-27 16:41:59.000000000","message":"This block runs for every driver once service.active_backend_id is set (line 4545), not only for RBD. On ServiceNotFound it keeps _get_my_volumes() (lines 4549-4550). On a match it replaces filters (lines 4552-4555) and loads that service\u0027s volumes.\n\nThose filters are then passed to GroupList.get_all_replicated at line 4591. The volumes in replicated_vols are passed to the driver at line 4593. If this call is not failback, non-replicated volumes from that other service are set to error and their snapshots to error (lines 4565-4573).\n\nReplicated volumes of the service that is executing failover are still selected by _get_my_volumes() / _get_cluster_or_host_filters() (line 4544). Please keep that selection.","commit_id":"9d5cf4b8d8887ed69102d9a3bbcdef44a666edbf"},{"author":{"_account_id":36171,"name":"jayaanand borra","display_name":"jayaanand borra","email":"jayaanand.borra@netapp.com","username":"jayaanan","status":"netapp"},"change_message_id":"41a3ce33086e24f1da7d9b9db9d9aab0ae5a25e9","unresolved":true,"context_lines":[{"line_number":4654,"context_line":"        if any(update.get(\u0027pool\u0027) is not None"},{"line_number":4655,"context_line":"               for update in update_data.values()):"},{"line_number":4656,"context_line":"            target_service \u003d self._get_target_service("},{"line_number":4657,"context_line":"                context, active_backend_id)"},{"line_number":4658,"context_line":""},{"line_number":4659,"context_line":"        self.finish_failover(context, service, updates)"},{"line_number":4660,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ad872733_1d687bc3","line":4657,"updated":"2026-09-27 16:41:59.000000000","message":"This call is outside the try that starts at line 4577. The handler at line 4610 is what calls finish_failover (line 4639) and returns. ServiceNotFound from line 271 skips that handler, skips finish_failover at line 4659, and skips the volume loop at line 4661.\n\nRBD has already promoted images before this line. RBDDriver.failover demotes and calls _failover_volume at rbd.py:1795-1801, then returns. For a non-clustered service the manager calls failover_host (manager.py:4581-4583), and RBDDriver.failover_host calls failover_completed at rbd.py:1840 before returning, which replaces _active_config (rbd.py:1821-1822). For a clustered service the manager calls RBDDriver.failover directly, so _active_config is not switched yet, but the promote has still happened and finish_failover is what would broadcast failover_completed.","commit_id":"9d5cf4b8d8887ed69102d9a3bbcdef44a666edbf"},{"author":{"_account_id":36171,"name":"jayaanand borra","display_name":"jayaanand borra","email":"jayaanand.borra@netapp.com","username":"jayaanan","status":"netapp"},"change_message_id":"41a3ce33086e24f1da7d9b9db9d9aab0ae5a25e9","unresolved":true,"context_lines":[{"line_number":4662,"context_line":"            update \u003d update_data.get(volume.id, {})"},{"line_number":4663,"context_line":"            pool \u003d update.pop(\u0027pool\u0027, None)"},{"line_number":4664,"context_line":"            if pool is not None:"},{"line_number":4665,"context_line":"                update[\u0027host\u0027] \u003d volume_utils.append_host("},{"line_number":4666,"context_line":"                    target_service.host, pool)"},{"line_number":4667,"context_line":"                update[\u0027availability_zone\u0027] \u003d target_service.availability_zone"},{"line_number":4668,"context_line":"            if update.get(\u0027status\u0027, \u0027\u0027) \u003d\u003d \u0027error\u0027:"}],"source_content_type":"text/x-python","patch_set":1,"id":"b1d7c072_0609689c","line":4665,"updated":"2026-09-27 16:41:59.000000000","message":"append_host returns host + \u0027#\u0027 + pool (cinder/volume/volume_utils.py:811-818). The pool value RBD sets is secondary_id on failover and volume_backend_name or config_group on failback (rbd.py:1802-1805). rbd_pool is unchanged across clusters (rbd.py:468). initialize_connection uses _active_config and configuration.rbd_pool (rbd.py:1866-1870 and rbd.py:482-483), not the pool encoded in volume.host.\n\nvolume.host is the RPC target for attach, extend, delete, snapshot, backup, migrate, and retype. Writing target_service.host moves those calls to a service that did not run failover_completed. This assignment also does not set volume.cluster_name (cinder/objects/volume.py:95). The group loop at lines 4685-4696 does not set group host either, while GroupList.get_all_replicated at line 4591 uses the same filters.\n\nOn failback, active_backend_id is default, so target_service is this service. Every successful volume still gets a new host: append_host(this_service.host, volume_backend_name or config_group). RBD does not report scheduler pools, so an unset volume_backend_name means the existing pool component is _pool0 (cinder/scheduler/host_manager.py:257-260). Failback then stores #\u003cconfig_group\u003e instead.\n\nPlease leave host and availability_zone unchanged.","commit_id":"9d5cf4b8d8887ed69102d9a3bbcdef44a666edbf"}]}
