Created
November 16, 2012 06:02
-
-
Save takekawa/4084670 to your computer and use it in GitHub Desktop.
openstack nova essex-4でのvolume attachに関連するコード nova/nova/compute/manager.py 1656 def attach_volume(self, context, instance_uuid, volume_id, mountpoint): 1657 """Attach a volume to an instance.""" 1658 volume = self.volume_api.get(conte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
nova/nova/compute/manager.py | |
1656 def attach_volume(self, context, instance_uuid, volume_id, mountpoint): | |
1657 """Attach a volume to an instance.""" | |
1658 volume = self.volume_api.get(context, volume_id) | |
1659 context = context.elevated() | |
1660 instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) | |
1661 instance_id = instance_ref['id'] | |
1662 msg = _("instance %(instance_uuid)s: attaching volume %(volume_id)s" | |
1663 " to %(mountpoint)s") | |
1664 LOG.audit(_('Attaching volume %(volume_id)s to %(mountpoint)s'), | |
1665 locals(), context=context, instance=instance_ref) | |
1666 try: | |
1667 connector = self.driver.get_volume_connector(instance_ref) | |
1668 connection_info = self.volume_api.initialize_connection(context, | |
1669 volume, | |
1670 connector) | |
1671 except Exception: # pylint: disable=W0702 | |
1672 with utils.save_and_reraise_exception(): | |
1673 msg = _("instance %(instance_uuid)s: attach failed" | |
1674 " %(mountpoint)s, removing") | |
1675 LOG.exception(msg % locals(), context=context) | |
1676 self.volume_api.unreserve_volume(context, volume) | |
1677 try: | |
1678 self.driver.attach_volume(connection_info, #<-----ここでatttachしている | |
1679 instance_ref['name'], | |
1680 mountpoint) | |
1681 except Exception: # pylint: disable=W0702 | |
1682 with utils.save_and_reraise_exception(): | |
1683 LOG.exception(_('Attach failed %(mountpoint)s, removing'), | |
1684 locals(), context=context, | |
1685 instance=instance_ref) | |
1686 self.volume_api.terminate_connection(context, | |
1687 volume, | |
1688 connector) | |
1689 | |
1690 self.volume_api.attach(context, volume, instance_id, mountpoint) | |
1691 values = { | |
1692 'instance_id': instance_id, | |
1693 'connection_info': utils.dumps(connection_info), | |
1694 'device_name': mountpoint, | |
1695 'delete_on_termination': False, | |
1696 'virtual_name': None, | |
1697 'snapshot_id': None, | |
1698 'volume_id': volume_id, | |
1699 'volume_size': None, | |
1700 'no_device': None} | |
1701 self.db.block_device_mapping_create(context, values) | |
1702 return True | |
nova/nova/virt/libvirt/connection.py | |
463 @exception.wrap_exception() | |
464 def attach_volume(self, connection_info, instance_name, mountpoint): | |
465 virt_dom = self._lookup_by_name(instance_name) | |
466 mount_device = mountpoint.rpartition("/")[2] | |
467 xml = self.volume_driver_method('connect_volume', #<----connect_volume でvolume情報を取得 | |
468 connection_info, | |
469 mount_device) | |
470 | |
471 if FLAGS.libvirt_type == 'lxc': | |
472 self._attach_lxc_volume(xml, virt_dom, instance_name) | |
473 else: | |
474 try: | |
475 virt_dom.attachDevice(xml) #<----ここでlibvirt経由でdeviceを追加している | |
476 except Exception, ex: | |
477 self.volume_driver_method('disconnect_volume', | |
478 connection_info, | |
479 mount_device) | |
480 | |
481 if isinstance(ex, libvirt.libvirtError): | |
482 errcode = ex.get_error_code() | |
483 if errcode == libvirt.VIR_ERR_OPERATION_FAILED: | |
484 raise exception.DeviceIsBusy(device=mount_device) | |
485 raise | |
nova/nova/virt/libvirt/volume.py | |
106 @utils.synchronized('connect_volume') | |
107 def connect_volume(self, connection_info, mount_device): | |
108 """Attach the volume to instance_name""" | |
109 iscsi_properties = connection_info['data'] | |
110 # NOTE(vish): If we are on the same host as nova volume, the | |
111 # discovery makes the target so we don't need to | |
112 # run --op new. Therefore, we check to see if the | |
113 # target exists, and if we get 255 (Not Found), then | |
114 # we run --op new. This will also happen if another | |
115 # volume is using the same target. | |
116 try: | |
117 self._run_iscsiadm(iscsi_properties, ()) | |
118 except exception.ProcessExecutionError as exc: | |
119 # iscsiadm returns 21 for "No records found" after version 2.0-871 | |
120 if exc.exit_code in [21, 255]: | |
121 self._run_iscsiadm(iscsi_properties, ('--op', 'new')) | |
122 else: | |
123 raise | |
124 | |
125 if iscsi_properties.get('auth_method'): | |
126 self._iscsiadm_update(iscsi_properties, | |
127 "node.session.auth.authmethod", | |
128 iscsi_properties['auth_method']) | |
129 self._iscsiadm_update(iscsi_properties, | |
130 "node.session.auth.username", | |
131 iscsi_properties['auth_username']) | |
132 self._iscsiadm_update(iscsi_properties, | |
133 "node.session.auth.password", | |
134 iscsi_properties['auth_password']) | |
135 | |
136 # NOTE(vish): If we have another lun on the same target, we may | |
137 # have a duplicate login | |
138 self._run_iscsiadm(iscsi_properties, ("--login",), | |
139 check_exit_code=[0, 255]) | |
140 | |
141 self._iscsiadm_update(iscsi_properties, "node.startup", "automatic") | |
142 | |
143 host_device = ("/dev/disk/by-path/ip-%s-iscsi-%s-lun-%s" % | |
144 (iscsi_properties['target_portal'], | |
145 iscsi_properties['target_iqn'], | |
146 iscsi_properties.get('target_lun', 0))) | |
147 | |
148 # The /dev/disk/by-path/... node is not always present immediately | |
149 # TODO(justinsb): This retry-with-delay is a pattern, move to utils? | |
150 tries = 0 | |
151 while not os.path.exists(host_device): | |
152 if tries >= FLAGS.num_iscsi_scan_tries: | |
153 raise exception.Error(_("iSCSI device not found at %s") % | |
154 (host_device)) | |
155 | |
156 LOG.warn(_("ISCSI volume not yet found at: %(mount_device)s. " | |
157 "Will rescan & retry. Try number: %(tries)s") % | |
158 locals()) | |
159 | |
160 # The rescan isn't documented as being necessary(?), but it helps | |
161 self._run_iscsiadm(iscsi_properties, ("--rescan",)) | |
162 | |
163 tries = tries + 1 | |
164 if not os.path.exists(host_device): | |
165 time.sleep(tries ** 2) | |
166 | |
167 if tries != 0: | |
168 LOG.debug(_("Found iSCSI node %(mount_device)s " | |
169 "(after %(tries)s rescans)") % | |
170 locals()) | |
171 | |
172 connection_info['data']['device_path'] = host_device | |
173 sup = super(LibvirtISCSIVolumeDriver, self) | |
174 return sup.connect_volume(connection_info, mount_device) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment