6cf9b1cd68
Log messages are no longer being translated. This removes all use of the _LE, _LI, and _LW translation markers to simplify logging and to avoid confusion with new contributions. See: http://lists.openstack.org/pipermail/openstack-i18n/2016-November/002574.html http://lists.openstack.org/pipermail/openstack-dev/2017-March/113365.html Change-Id: I8056e32d29585605ab75aa44b85ec16befecbd20
129 lines
4.8 KiB
Python
129 lines
4.8 KiB
Python
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
|
|
import glob
|
|
import os
|
|
|
|
from oslo_concurrency import processutils as putils
|
|
from oslo_log import log as logging
|
|
|
|
from os_brick import exception
|
|
from os_brick import initiator
|
|
|
|
from os_brick.initiator import host_driver
|
|
from os_brick.initiator import initiator_connector
|
|
from os_brick.initiator import linuxscsi
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class BaseLinuxConnector(initiator_connector.InitiatorConnector):
|
|
os_type = initiator.OS_TYPE_LINUX
|
|
|
|
def __init__(self, root_helper, driver=None, execute=None,
|
|
*args, **kwargs):
|
|
self._linuxscsi = linuxscsi.LinuxSCSI(root_helper, execute=execute)
|
|
|
|
if not driver:
|
|
driver = host_driver.HostDriver()
|
|
self.set_driver(driver)
|
|
|
|
super(BaseLinuxConnector, self).__init__(root_helper, execute=execute,
|
|
*args, **kwargs)
|
|
|
|
@staticmethod
|
|
def get_connector_properties(root_helper, *args, **kwargs):
|
|
"""The generic connector properties."""
|
|
multipath = kwargs['multipath']
|
|
enforce_multipath = kwargs['enforce_multipath']
|
|
props = {}
|
|
|
|
props['multipath'] = (multipath and
|
|
linuxscsi.LinuxSCSI.is_multipath_running(
|
|
enforce_multipath, root_helper,
|
|
execute=kwargs.get('execute')))
|
|
|
|
return props
|
|
|
|
def check_valid_device(self, path, run_as_root=True):
|
|
cmd = ('dd', 'if=%(path)s' % {"path": path},
|
|
'of=/dev/null', 'count=1')
|
|
out, info = None, None
|
|
try:
|
|
out, info = self._execute(*cmd, run_as_root=run_as_root,
|
|
root_helper=self._root_helper)
|
|
except putils.ProcessExecutionError as e:
|
|
LOG.error("Failed to access the device on the path "
|
|
"%(path)s: %(error)s.",
|
|
{"path": path, "error": e.stderr})
|
|
return False
|
|
# If the info is none, the path does not exist.
|
|
if info is None:
|
|
return False
|
|
return True
|
|
|
|
def get_all_available_volumes(self, connection_properties=None):
|
|
volumes = []
|
|
path = self.get_search_path()
|
|
if path:
|
|
# now find all entries in the search path
|
|
if os.path.isdir(path):
|
|
path_items = [path, '/*']
|
|
file_filter = ''.join(path_items)
|
|
volumes = glob.glob(file_filter)
|
|
|
|
return volumes
|
|
|
|
def _discover_mpath_device(self, device_wwn, connection_properties,
|
|
device_name):
|
|
"""This method discovers a multipath device.
|
|
|
|
Discover a multipath device based on a defined connection_property
|
|
and a device_wwn and return the multipath_id and path of the multipath
|
|
enabled device if there is one.
|
|
"""
|
|
|
|
path = self._linuxscsi.find_multipath_device_path(device_wwn)
|
|
device_path = None
|
|
multipath_id = None
|
|
|
|
if path is None:
|
|
# find_multipath_device only accept realpath not symbolic path
|
|
device_realpath = os.path.realpath(device_name)
|
|
mpath_info = self._linuxscsi.find_multipath_device(
|
|
device_realpath)
|
|
if mpath_info:
|
|
device_path = mpath_info['device']
|
|
multipath_id = device_wwn
|
|
else:
|
|
# we didn't find a multipath device.
|
|
# so we assume the kernel only sees 1 device
|
|
device_path = device_name
|
|
LOG.debug("Unable to find multipath device name for "
|
|
"volume. Using path %(device)s for volume.",
|
|
{'device': device_path})
|
|
else:
|
|
device_path = path
|
|
multipath_id = device_wwn
|
|
if connection_properties.get('access_mode', '') != 'ro':
|
|
try:
|
|
# Sometimes the multipath devices will show up as read only
|
|
# initially and need additional time/rescans to get to RW.
|
|
self._linuxscsi.wait_for_rw(device_wwn, device_path)
|
|
except exception.BlockDeviceReadOnly:
|
|
LOG.warning('Block device %s is still read-only. '
|
|
'Continuing anyway.', device_path)
|
|
return device_path, multipath_id
|