openstack-cinder-虚机挂载云盘cinder侧过程以及源码分析

本文基于openstack Stein 版本

上文分析nova挂载云盘过程中,提到调用cinder initialize_connection, 返回volume 的连接信息,比如rbd ceph 的connection info, 同时在 _parse_connection_options 中基于volume type 添加cinder io qos 信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cinder.volume.manager.VolumeManager.initialize_connection
def initialize_connection(self, context, volume, connector):
...............................................
try:
conn_info = self.driver.initialize_connection(volume, connector)
except Exception as err:
err_msg = (_("Driver initialize connection failed "
"(error: %(err)s).") % {'err': six.text_type(err)})
LOG.exception(err_msg, resource=volume)

self.driver.remove_export(context.elevated(), volume)

raise exception.VolumeBackendAPIException(data=err_msg)

conn_info = self._parse_connection_options(context, volume, conn_info)
LOG.info("Initialize volume connection completed successfully.",
resource=volume)
return conn_info
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def _parse_connection_options(self, context, volume, conn_info):
# Add qos_specs to connection info
typeid = volume.volume_type_id
specs = None
if typeid:
res = volume_types.get_volume_type_qos_specs(typeid)
qos = res['qos_specs']
# only pass qos_specs that is designated to be consumed by
# front-end, or both front-end and back-end.
if qos and qos.get('consumer') in ['front-end', 'both']:
specs = qos.get('specs')

# NOTE(mnaser): The following configures for per-GB QoS
if specs is not None:
volume_size = int(volume.size)
tune_opts = ('read_iops_sec', 'read_bytes_sec',
'write_iops_sec', 'write_bytes_sec',
'total_iops_sec', 'total_bytes_sec')

for option in tune_opts:
option_per_gb = '%s_per_gb' % option
option_per_gb_min = '%s_per_gb_min' % option
option_max = '%s_max' % option
option_base = '%s_base' % option
if option_per_gb in specs:
minimum_value = int(specs.pop(option_per_gb_min, 0))
value = int(specs[option_per_gb]) * volume_size
per_gb_value = max(minimum_value, value)
base_value = int(specs.pop(option_base, 0))
final_value = base_value + per_gb_value
max_value = int(specs.pop(option_max, final_value))
specs[option] = min(final_value, max_value)
specs.pop(option_per_gb)

qos_spec = dict(qos_specs=specs)
conn_info['data'].update(qos_spec)
...............................................

connection info 返回给了nova,nova侧使用即可,至于attachment 只是数据库里面变更一下记录而已。