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
- v2/volume/api create
- cinder/volume/api create
- scheduler_rpcapi
Order of function calls
- Context The Web UI or CINDERClint submits a request for volume_create
- 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):
- 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
- 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
- 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
- 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…