Introduction to the

Storage virtualization technology is a technology for secondary storage allocation on physical storage media. LVM and common partitions are also a simple form of storage virtualization. A physical disk is divided into two disks, or 10 disks are aggregated into one storage disk. Used to meet the different needs of different users.

The characteristics of

Different from CPU and memory, the current (2021) nic speed is between 100m and 1000G /s, so CPU and memory cannot carry out cross-node virtualization, even if forcibly implemented, the performance is very low. However, the speed of common disks is much lower than that of network cards. Take the relatively new NVMe as an example, 2-4g/s. In addition, a host may have dozens of storage disks. Therefore, the virtualization of storage media can be aggregated over the network. Combined with metadata lookup optimization, and the use of in-memory cache hotspot data. Both are very promising.

What is the cinder

As a storage plug-in of openstack, Cinder does not implement all storage capabilities by itself. Instead, cinder uses different interfaces to implement its own storage capabilities. For example, LVM is used to store vm disks locally to make use of the local disk storage capability. Or call RBD for storage relying on CEPh.

Cinder Service Composition

API, Scheduler, Volume, backup, service composition. You can run the systemctl status command to view the service status. Configuration file /etc/cinder data directory /var/lib/cinder log directory /var/log/Cinder Cinder can be invoked in 8776 request mode. You can also invoke the CINDER CLI tool provided by the CinderClient project.

The following uses creating a volume as an example to analyze cinder code

Command line -> API -> api-server can directly command line or API

Creating a general process

  1. v2/volume/api create
  2. cinder/volume/api create
  3. scheduler_rpcapi

Order of function calls

  1. Context The Web UI or CINDERClint submits a request for volume_create
  2. Requests are mapped by the URL-to-API to the following functions

/root/cinder/cinder/volume/api.py:218 def create def create(self, context, size, name, description, snapshot=None, image_id=None, volume_type=None, metadata=None, availability_zone=None, source_volume=None, scheduler_hints=None, source_replica=None, consistencygroup=None, cgsnapshot=None, multiattach=False, source_cg=None):

  1. Parameter check Checks the validity of the parameter format and whether the resource stock is sufficient.
# check parameters
if size and (not strutils.is_int_like(size) or int(size) <= 0):
    msg = _('Invalid volume size provided for create request: %s '
            '(size argument must be an integer (or string '
            'representation of an integer) and greater '
            'than zero).') % size
    raise exception.InvalidInput(reason=msg)

Copy the code
  1. After that, create the sched_rpcapi volume_rpcapi flow_engine

The/root/cinder cinder/volume/rpcapi py: 35 volume_rpcapi more detailed creation process

sched_rpcapi = (self.scheduler_rpcapi if (not cgsnapshot and
                not source_cg) else None)
volume_rpcapi = (self.volume_rpcapi if (not cgsnapshot and
                  not source_cg) else None)
flow_engine = create_volume.get_flow(self.db,
                                      self.image_service,
                                      availability_zones,
                                      create_what,
                                      sched_rpcapi,
                                      volume_rpcapi)
Copy the code
  1. Run flow_engine to create a volume
# Attaching this listener will capture all of the notifications that
# taskflow sends out and redirect them to a more useful log for
# cinders debugging (or error reporting) usage.
with flow_utils.DynamicLogListener(flow_engine, logger=LOG):
    flow_engine.run()
    vref = flow_engine.storage.fetch('volume')
    LOG.info(_LI("Volume created successfully."), resource=vref)
    return vref
Copy the code
  1. Returns the ref of the vref, volume object (reference object)

Volume_rpc_api Process for creating a volume


def create_volume(self, ctxt, volume, host, request_spec,
                  filter_properties, allow_reschedule=True):
    request_spec_p = jsonutils.to_primitive(request_spec)
    msg_args = {'volume_id': volume.id, 'request_spec': request_spec_p,
                'filter_properties': filter_properties,
                'allow_reschedule': allow_reschedule}
    if self.client.can_send_version('2.0'):
        version = '2.0'
        msg_args['volume'] = volume
    elif self.client.can_send_version('1.32'):
        version = '1.32'
        msg_args['volume'] = volume
    else:
        version = '1.24'

    cctxt = self._get_cctxt(host, version)
    request_spec_p = jsonutils.to_primitive(request_spec)
    """Invoke a method and return immediately. See RPCClient.cast()."""
    cctxt.cast(ctxt, 'create_volume', **msg_args)

This is where CCTXT provides a task to the message queue
-->
self.transport._send(self.target, ctxt, msg, retry=self.retry)


Copy the code

Determine if there are any key names in the list or map

# Check that the required keys are present, return an error if they
# are not.
required_keys = set(['ref'.'host'])
missing_keys = list(required_keys - set(volume.keys()))

if missing_keys:
    # indicates that not all of these key names exist
    msg = _("The following elements are required: %s") % \
        ', '.join(missing_keys)
    raise exc.HTTPBadRequest(explanation=msg)

Copy the code

Limengkai. Work: 50000 / it/l…