.. Using orphan, as document is explicitly imported and not part of the toctree

:orphan:

Drivers Locking Examples
========================

This document presents an incomplete list of locks being currently used in
driver related code (main driver code, helper classes and method, etc.), to
serve as a reference to other driver developers.

.. note:: Please keep in mind that Cinder drivers may support different
  deployment options.  Some may only support running one backend on each node.
  Others may support running multiple backends in a single node.  And some may
  even support Active-Active deployments.  Therefore these references are not
  necessarily examples of how drivers achieve Active-Active.

LIO target
  - Lock scope: Node.
  - Critical section: Calls to `cinder-rtstool` CLI.
  - Lock name: `'lioadm'`.
  - Where: `_execute` method.
  - File: `cinder/volume/targets/lio.py`

NVMET target
  - Lock scope: Node.
  - Critical section: Creating or deleting NVMeOF targets operations.
  - Lock name: `'nvmetcli'`.
  - Where: `delete_nvmeof_target` and `create_nvmeof_target` methods.
  - File: `cinder/volume/targets/nvmet.py`.

HGST driver:
  - Lock scope: Process.
  - Critical section: Create volume operation.
  - Lock name: `'hgst'devices'`.
  - Where: `create_volume` method.
  - File: `cinder/volume/drivers/hgst.py`.

Solidfire driver:
  - Lock scope: Process
  - Critical section: Creating volume from an image, cloning volume, creating
    volume from a snapshot.
  - Lock name: `solidfire-{resource_id}`.
  - Where: `locked_image_id_operation` and `locked_source_id_operation`
    decorators.
  - File: `cinder/volume/drivers/solidfire.py`.

Infinidat driver:
  - Lock scope: Global.
  - Critical section: Initialize and terminate connections operations.
  - Lock name: `infinidat-{management_address}-lock`.
  - Where: `initialize_connection` and `terminate_connection` methods.
  - File: `cinder/volume/drivers/infinidat.py`.

Kaminario FC driver:
  - Lock scope: Global.
  - Critical section: Initialize and terminate connections operations.
  - Lock name: `kaminario-{san_ip}`.
  - Where: `initialize_connection` and `terminate_connection` methods.
  - File: `cinder/volume/drivers/kaminario/kaminario_fc.py`

Kaminario iSCSI driver:
  - Lock scope: Global.
  - Critical section: Initialize and terminate connections operations.
  - Lock name: `kaminario-{san_ip}`.
  - Where: `initialize_connection` and `terminate_connection` methods.
  - File: `cinder/volume/drivers/kaminario/kaminario_iscsi.py`

Dell Unity:
  - Lock scope: Global.
  - Critical section: Create or get a host on the backend.
  - Lock name: `{self.host}-{name}`
  - Where: `create_host` method.
  - File: `cinder/volume/drivers/dell_emc/unity/client.py`

Dell Unity:
  - Lock scope: Global.
  - Critical section: Create host and attach.
  - Lock name: `{client.host}-{host_name}`
  - Where: `_create_host_and_attach` method.
  - File: `cinder/volume/drivers/dell_emc/unity/adapter.py`

Dell Unity:
  - Lock scope: Global.
  - Critical section: Create host and attach as part of the
    `initialize_connection` process, and also detach and delete host as part of
    the `terminate_connection` process.
  - Lock name: `{client.host}-{host_name}`
  - Where: `_create_host_and_attach` and `_detach_and_delete_host` methods.
  - File: `cinder/volume/drivers/dell_emc/unity/adapter.py`

Dothill:
  - Lock scope: Global
  - Critical section: Retrieving a session key from the array.  Perform HTTP
    requests on the device.
  - Lock name: `{driver_name}-{array_name}`
  - Where: `_get_session_key` and `_api_request` methods.
  - File: `cinder/volume/drivers/dothill/dothill_client.py`.

Dothill:
  - Lock scope: Global
  - Critical section: Mapping a volume as part of the `initialize_connection`
    process.
  - Lock name: `{driver_name}-{array_name}-map`
  - Where: `map_volume` method.
  - File: `cinder/volume/drivers/dothill/dothill_client.py`.


Other files
-----------

Other files that also make use of the locking mechanisms, and can be useful as
reference, are:

- `cinder/volume/drivers/dell_emc/vmax/common.py`
- `cinder/volume/drivers/dell_emc/vmax/masking.py`
- `cinder/volume/drivers/dell_emc/vmax/provision.py`
- `cinder/volume/drivers/dell_emc/vmax/rest.py`
- `cinder/volume/drivers/dell_emc/vmax/utils.py`
- `cinder/volume/drivers/fujitsu/eternus_dx_common.py`
- `cinder/volume/drivers/hpe/hpe_3par_common.py`
- `cinder/volume/drivers/hpe/hpe_lefthand_iscsi.py`
- `cinder/volume/drivers/huawei/huawei_driver.py`
- `cinder/volume/drivers/huawei/rest_client.py`
- `cinder/volume/drivers/huawei/smartx.py`
- `cinder/volume/drivers/ibm/flashsystem_common.py`
- `cinder/volume/drivers/ibm/flashsystem_fc.py`
- `cinder/volume/drivers/ibm/flashsystem_iscsi.py`
- `cinder/volume/drivers/ibm/ibm_storage/ds8k_helper.py`
- `cinder/volume/drivers/ibm/ibm_storage/ds8k_proxy.py`
- `cinder/volume/drivers/ibm/ibm_storage/ds8k_replication.py`
- `cinder/volume/drivers/ibm/ibm_storage/xiv_proxy.py`
- `cinder/volume/drivers/ibm/storwize_svc/storwize_const.py`
- `cinder/volume/drivers/ibm/storwize_svc/storwize_svc_fc.py`
- `cinder/volume/drivers/ibm/storwize_svc/storwize_svc_iscsi.py`
- `cinder/volume/drivers/inspur/instorage/instorage_const.py`
- `cinder/volume/drivers/inspur/instorage/instorage_fc.py`
- `cinder/volume/drivers/inspur/instorage/instorage_iscsi.py`
- `cinder/volume/drivers/nec/cli.py`
- `cinder/volume/drivers/nec/volume_helper.py`
- `cinder/volume/drivers/netapp/dataontap/nfs_base.py`


Notes on Driver Locking
-----------------------

From the volume manager flow, create_cloned_volume() happens to be called
with a lock that prevents concurrent calls to clone from the same volume
at the same time.

This is done by the cinder/volume/manager.py create_volume() code::

    elif source_volid is not None:
        locked_action = "%s-%s" % (source_volid, 'delete_volume')

and subsequent COORDINATOR.get_lock() call.

This seems to have been intended to prevent a volume from being deleted
while being used as the source of a volume clone, the fact that it
prevents concurrent clone operations is a side effect.

This means that a driver that cannot correctly handle concurrent clone
operations from the same volume will work for normal clone operations,
but then fail when a clone operation is performed as part of cloning
from the image-volume cache, or cloning from a Cinder backend of Glance.
(See https://bugs.launchpad.net/cinder/+bug/1851512 for an example.)

It should be assumed that, at some point, this locking behavior will be
changed to allow concurrent clone calls.
