End-to-end scenarios — cinder — branch stable/2026.2
Branch
stable/2026.2@c117f9cf08b4(29.0.0-1-gc117f9cf0) — repository https://opendev.org/openstack/cinder — analysed on 2026-10-28
Five flows that cover most of what an operator sees. Error statuses refer to 02-errors_stable-2026.2.md, and asynchronous steps to 05-async-processing_stable-2026.2.md.
1. Creating a volume (from an image)
A project member creates a 10 GiB bootable volume from a Glance image. The API only records the request; the scheduler chooses a pool and the volume service does the work, possibly through the image-volume cache.
sequenceDiagram
autonumber
actor U as User
participant API as cinder-api
participant DB as MariaDB
participant MQ as RabbitMQ
participant SCH as cinder-scheduler
participant VOL as cinder-volume (host@backend)
participant G as Glance
participant ARR as Storage array
U->>API: POST /v3/{project_id}/volumes {"volume": {"size": 10, "imageRef": "…"}}
API->>G: GET /v2/images/{id} (size, min_disk, status)
API->>DB: SELECT quota_usages … FOR UPDATE; INSERT reservations
alt quota exceeded
API-->>U: 413 overLimit VolumeSizeExceedsAvailableQuota
end
API->>DB: INSERT volumes (status=creating); commit reservations
API->>MQ: cast create_volume (topic cinder-scheduler)
API-->>U: 202 {"volume": {"status": "creating", …}}
MQ->>SCH: create_volume
SCH->>SCH: filters (AZ, capacity, capabilities) + weighers on cached pool stats
alt no valid backend
SCH->>DB: UPDATE volumes SET status='error'; INSERT messages (VOLUME_VOLUME_001_003)
else backend found
SCH->>DB: UPDATE volumes SET host='node1@lvm#pool'
SCH->>MQ: cast create_volume (topic cinder-volume.node1@lvm, server node1)
MQ->>VOL: create_volume
VOL->>VOL: create flow (notification volume.create.start)
alt image already in the image-volume cache
VOL->>ARR: clone the cached volume
else cache miss
VOL->>ARR: create volume
VOL->>G: GET /v2/images/{id}/file
VOL->>ARR: write the image (qemu-img convert through os-brick)
end
alt driver failure and attempts left
VOL->>MQ: cast create_volume to the scheduler (retry, backend excluded)
else success
VOL->>DB: UPDATE volumes SET status='available', bootable=true; INSERT volume_glance_metadata
VOL->>MQ: notify volume.create.end
end
end
U->>API: GET /v3/{project_id}/volumes/{id} (polling)
API-->>U: 200 status available | errorDiagnostics: a volume stuck in creating means no scheduler consumed the message (check cinder-scheduler is up and the queue cinder-scheduler), or the chosen volume service died during the flow (its workers row lets init_host or POST /workers/cleanup set it to error). A volume in error right away: read GET /v3/{project_id}/messages?resource_uuid=<id>; VOLUME_VOLUME_001_003 = no pool passed the filters (look at GET /scheduler-stats/get_pools?detail=true: capacity, reserved_percentage, oversubscription). Errors after the scheduler: the cinder-volume log, request ID req-….
2. Attaching a volume to a Nova instance (attachments API)
Nova uses the attachments API (3.27+): reservation, then connection with the compute host's connector, then completion. The attachment and connection info returned by Cinder are what Nova's os-brick uses to connect the host.
sequenceDiagram
autonumber
participant N as nova-compute
participant API as cinder-api
participant DB as MariaDB
participant VOL as cinder-volume
participant ARR as Storage array
N->>API: POST /v3/{project_id}/attachments {"attachment": {"volume_uuid", "instance_uuid"}} (3.44+)
API->>DB: UPDATE volumes SET status='reserved' WHERE status IN ('available','downloading') (or in-use if multiattach)
API->>DB: INSERT volume_attachment (attach_status=reserved)
API-->>N: 200 {"attachment": {"id", "status": "reserved", "connection_info": {}}}
N->>API: PUT /v3/{project_id}/attachments/{id} {"attachment": {"connector": {"host", "initiator", "ip", "multipath"…}}}
API->>API: lock cinder-attachment_update-<volume>-<host>
API->>VOL: RPC call attachment_update(connector)
VOL->>ARR: create_export + initialize_connection (map LUN to initiator)
VOL->>DB: UPDATE volume_attachment SET connection_info, connector, attach_status='attaching'
VOL-->>API: connection_info {"driver_volume_type": "iscsi", "data": {…}}
alt driver error or RPC timeout
API-->>N: 500 "Unable to update the attachment" / computeFault
end
API-->>N: 200 {"attachment": {"connection_info": {…}}}
N->>N: os-brick connect_volume on the compute host
N->>API: POST /v3/{project_id}/attachments/{id}/action {"os-complete": null}
API->>DB: attachment attached; volume in-use, attach_status attached
API-->>N: 204
Note over N,API: Detach: DELETE /v3/{project_id}/attachments/{id}, sent with a service token, then RPC call attachment_delete (terminate_connection, remove_export)Diagnostics: 409 ConflictNovaUsingAttachment on DELETE means the call did not carry Nova's service token ([service_user] in nova.conf) while the attachment is connected. 409 on PUT means another host already has a connection to a non-multiattach volume. A 500 on PUT: look in the cinder-volume log for the driver error of initialize_connection; the attachment stays reserved and Nova should delete it.
3. Extending an attached volume
From microversion 3.42, os-extend works on in-use volumes. Cinder extends the LUN, then asks Nova to make the guest see the new size.
sequenceDiagram
autonumber
actor U as User
participant API as cinder-api
participant DB as MariaDB
participant SCH as cinder-scheduler
participant VOL as cinder-volume
participant NOVA as Nova API
U->>API: POST /v3/{project_id}/volumes/{id}/action {"os-extend": {"new_size": 20}} (OpenStack-API-Version: volume 3.42)
API->>DB: UPDATE volumes SET status='extending', previous_status='in-use' WHERE status='in-use'
API->>DB: reserve quota gigabytes +10
alt over quota
API->>DB: status back to in-use
API-->>U: 413 VolumeSizeExceedsAvailableQuota
end
API->>SCH: cast extend_volume
API-->>U: 202
SCH->>SCH: backend_passes_filters (capacity of the volume's own pool)
alt not enough capacity
SCH->>DB: status back to in-use; rollback quota; user message
else
SCH->>VOL: cast extend_volume
VOL->>VOL: driver.extend_volume
alt driver failure
VOL->>DB: status error_extending; rollback quota; message VOLUME_VOLUME_007_010
else
VOL->>DB: commit quota; size=20; status in-use; notify volume.resize.end
VOL->>NOVA: POST /v2.1/os-server-external-events [{"name": "volume-extended", "server_uuid", "tag": volume_id}] (2.51, [nova] service user)
alt Nova error
VOL->>DB: user message VOLUME_VOLUME_007_009
end
end
endDiagnostics: the volume is bigger in Cinder but not in the guest → the Nova event failed (message 007_009, Nova [nova] credentials in cinder.conf, Nova API logs for volume-extended). error_extending → driver failure; an operator can os-reset_status back to in-use after checking the array.
4. Backing up and restoring a volume
sequenceDiagram
autonumber
actor U as User
participant API as cinder-api
participant DB as MariaDB
participant SCH as cinder-scheduler
participant BK as cinder-backup
participant VOL as cinder-volume
participant S as Backup store (Swift…)
U->>API: POST /v3/{project_id}/backups {"backup": {"volume_id", "incremental": false, "force": true}}
API->>DB: reserve quota backups, backup_gigabytes
API->>DB: UPDATE volumes SET status='backing-up', previous_status=<status>
API->>DB: INSERT backups (status creating)
API->>SCH: cast create_backup
API-->>U: 202 {"backup": {"id", "name"}}
SCH->>SCH: pick a live cinder-backup in the AZ
alt no backup service
SCH->>DB: backup error, volume previous status, message BACKUP_SCHEDULE_ERROR
else
SCH->>BK: cast create_backup (topic cinder-backup.<host>)
BK->>VOL: RPC call get_backup_device (temporary snapshot/clone if in-use)
BK->>BK: attach the device locally (os-brick)
loop each chunk
BK->>S: PUT object (compressed, sha256 per chunk)
BK-->>BK: notify backup.createprogress
end
BK->>DB: backup available (size, object count); volume back to previous status
end
U->>API: POST /v3/{project_id}/backups/{id}/restore {"restore": {"volume_id": …}}
API->>DB: backup restoring; volume restoring-backup
API->>BK: cast restore_backup
BK->>S: GET objects
BK->>DB: backup available; volume available (or error_restoring)Diagnostics: POST /backups returning 503 means no cinder-backup service is up (heartbeat), often because its driver never initialised (_setup_backup_driver loops every backup_driver_init_check_interval, and the service sends no heartbeat while it does). Backup in error: read fail_reason on the backup and the user messages.
5. Deleting an encrypted volume
sequenceDiagram
autonumber
actor U as User
participant API as cinder-api
participant DB as MariaDB
participant KM as Barbican
participant VOL as cinder-volume
participant ARR as Storage array
U->>API: DELETE /v3/{project_id}/volumes/{id}
API->>DB: conditional UPDATE status='deleting' (not attached, no snapshots, status in available/error/…)
alt condition not met
API-->>U: 400 InvalidVolume "Volume … must not be migrating, attached, …"
end
API->>DB: evict image-volume cache entry if any
API->>KM: DELETE secret encryption_key_id
alt key deletion fails
API->>DB: status error_deleting
API-->>U: 400 "Unable to delete encryption key for volume"
end
API->>VOL: cast delete_volume
API-->>U: 202
VOL->>VOL: lock cinder-<id>-delete_volume
VOL->>ARR: remove_export, delete_volume
alt array says busy
VOL->>DB: status available
else failure
VOL->>DB: status error_deleting
else success
VOL->>DB: release quotas; soft-delete volume; notify volume.delete.end
endDiagnostics: the key is deleted before the backend deletion: a volume left in error_deleting after this point can no longer be decrypted, so only a force delete makes sense. A volume that was never scheduled (no host) is deleted directly by the API, without RPC (cinder/volume/api.py:423-455).
Source: reverse-spec-cinder/04-scenarios_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.