summaryrefslogtreecommitdiffstats
path: root/nova/virt
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2012-02-09 15:05:21 -0800
committerRenuka Apte <renuka.apte@citrix.com>2012-02-16 16:45:15 -0800
commit509e5ad9ef6ed38caa69d2c76b1adccedcdd315e (patch)
tree982eabc1e080a1d0825fe871ecf418c5f182e6c8 /nova/virt
parent844035b6c0f725c685cdff56a7bb77efe7825a5f (diff)
downloadnova-509e5ad9ef6ed38caa69d2c76b1adccedcdd315e.tar.gz
nova-509e5ad9ef6ed38caa69d2c76b1adccedcdd315e.tar.xz
nova-509e5ad9ef6ed38caa69d2c76b1adccedcdd315e.zip
Fixes nova-volume support for multiple luns
* stores lun in provider_location if specified * passes lun in iscsi_properties instead of hard coding * adds call to libvirt to list all used block devices * make sure to synchronize connect and disconnect commands * only disconnect from target if no luns are in use * allow double logins to targets * fixes typo in get_volume_connector in xenapi_connection * fixes bug 929790 Change-Id: I2466dc750a6fa5e0b07f94314d38873740aa6b29
Diffstat (limited to 'nova/virt')
-rw-r--r--nova/virt/libvirt/connection.py20
-rw-r--r--nova/virt/libvirt/volume.py42
-rw-r--r--nova/virt/xenapi_conn.py2
3 files changed, 47 insertions, 17 deletions
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index c3bfdedda..349faa157 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -1388,6 +1388,26 @@ class LibvirtConnection(driver.ComputeDriver):
return domain
+ def get_all_block_devices(self):
+ """
+ Return all block devices in use on this node.
+ """
+ devices = []
+ for dom_id in self._conn.listDomainsID():
+ domain = self._conn.lookupByID(dom_id)
+ try:
+ doc = ElementTree.fromstring(domain.XMLDesc(0))
+ except Exception:
+ continue
+ ret = doc.findall('./devices/disk')
+ for node in ret:
+ if node.get('type') != 'block':
+ continue
+ for child in node.getchildren():
+ if child.tag == 'source':
+ devices.append(child.get('dev'))
+ return devices
+
def get_disks(self, instance_name):
"""
Note that this function takes an instance name.
diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py
index 75fa0e5a9..055e34abc 100644
--- a/nova/virt/libvirt/volume.py
+++ b/nova/virt/libvirt/volume.py
@@ -103,14 +103,16 @@ class LibvirtISCSIVolumeDriver(LibvirtVolumeDriver):
'-v', property_value)
return self._run_iscsiadm(iscsi_properties, iscsi_command)
+ @utils.synchronized('connect_volume')
def connect_volume(self, connection_info, mount_device):
"""Attach the volume to instance_name"""
iscsi_properties = connection_info['data']
- # NOTE(vish): if we are on the same host as nova volume, the
+ # NOTE(vish): If we are on the same host as nova volume, the
# discovery makes the target so we don't need to
# run --op new. Therefore, we check to see if the
# target exists, and if we get 255 (Not Found), then
- # we run --op new
+ # we run --op new. This will also happen if another
+ # volume is using the same target.
try:
self._run_iscsiadm(iscsi_properties, ())
except exception.ProcessExecutionError as exc:
@@ -131,18 +133,17 @@ class LibvirtISCSIVolumeDriver(LibvirtVolumeDriver):
"node.session.auth.password",
iscsi_properties['auth_password'])
- self._run_iscsiadm(iscsi_properties, ("--login",))
+ # NOTE(vish): If we have another lun on the same target, we may
+ # have a duplicate login
+ self._run_iscsiadm(iscsi_properties, ("--login",),
+ check_exit_code=[0, 255])
self._iscsiadm_update(iscsi_properties, "node.startup", "automatic")
- if FLAGS.iscsi_helper == 'tgtadm':
- host_device = ("/dev/disk/by-path/ip-%s-iscsi-%s-lun-1" %
- (iscsi_properties['target_portal'],
- iscsi_properties['target_iqn']))
- else:
- host_device = ("/dev/disk/by-path/ip-%s-iscsi-%s-lun-0" %
- (iscsi_properties['target_portal'],
- iscsi_properties['target_iqn']))
+ host_device = ("/dev/disk/by-path/ip-%s-iscsi-%s-lun-%s" %
+ (iscsi_properties['target_portal'],
+ iscsi_properties['target_iqn'],
+ iscsi_properties.get('target_lun', 0)))
# The /dev/disk/by-path/... node is not always present immediately
# TODO(justinsb): This retry-with-delay is a pattern, move to utils?
@@ -172,13 +173,22 @@ class LibvirtISCSIVolumeDriver(LibvirtVolumeDriver):
sup = super(LibvirtISCSIVolumeDriver, self)
return sup.connect_volume(connection_info, mount_device)
+ @utils.synchronized('connect_volume')
def disconnect_volume(self, connection_info, mount_device):
"""Detach the volume from instance_name"""
sup = super(LibvirtISCSIVolumeDriver, self)
sup.disconnect_volume(connection_info, mount_device)
iscsi_properties = connection_info['data']
- self._iscsiadm_update(iscsi_properties, "node.startup", "manual")
- self._run_iscsiadm(iscsi_properties, ("--logout",),
- check_exit_code=[0, 255])
- self._run_iscsiadm(iscsi_properties, ('--op', 'delete'),
- check_exit_code=[0, 255])
+ # NOTE(vish): Only disconnect from the target if no luns from the
+ # target are in use.
+ device_prefix = ("/dev/disk/by-path/ip-%s-iscsi-%s-lun-" %
+ (iscsi_properties['target_portal'],
+ iscsi_properties['target_iqn']))
+ devices = self.connection.get_all_block_devices()
+ devices = [dev for dev in devices if dev.startswith(device_prefix)]
+ if not devices:
+ self._iscsiadm_update(iscsi_properties, "node.startup", "manual")
+ self._run_iscsiadm(iscsi_properties, ("--logout",),
+ check_exit_code=[0, 255])
+ self._run_iscsiadm(iscsi_properties, ('--op', 'delete'),
+ check_exit_code=[0, 255])
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index 1e2d11bb0..08542268c 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -346,7 +346,7 @@ class XenAPIConnection(driver.ComputeDriver):
def get_volume_connector(self, _instance):
"""Return volume connector information"""
if not self._initiator:
- stats = self.get_host_stats(update=True)
+ stats = self.get_host_stats(refresh=True)
try:
self._initiator = stats['host_other-config']['iscsi_iqn']
except (TypeError, KeyError):