Add iscsi_target_flags configuration option
Newly introduced `iscsi_target_flags' allows to specify `tgtd' backing storage flags. This can be used to instruct `tgtd' to open backing device file using `O_DIRECT' flag ensuring direct access without cache. DocImpact Closes-Bug: #1441935 Change-Id: I9c7c88a7ae75096042104849c1b00aa47728e0d4
This commit is contained in:
parent
66dfe800f3
commit
132d1af5c3
|
@ -28,6 +28,8 @@ class TestTgtAdmDriver(tf.TargetDriverFixture):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestTgtAdmDriver, self).setUp()
|
super(TestTgtAdmDriver, self).setUp()
|
||||||
|
self.configuration.get = mock.Mock(side_effect=self.fake_get)
|
||||||
|
|
||||||
self.target = tgt.TgtAdm(root_helper=utils.get_root_helper(),
|
self.target = tgt.TgtAdm(root_helper=utils.get_root_helper(),
|
||||||
configuration=self.configuration)
|
configuration=self.configuration)
|
||||||
self.testvol_path = \
|
self.testvol_path = \
|
||||||
|
@ -74,6 +76,10 @@ class TestTgtAdmDriver(tf.TargetDriverFixture):
|
||||||
' ALL"\n' % {'test_vol': self.test_vol,
|
' ALL"\n' % {'test_vol': self.test_vol,
|
||||||
'bspath': self.testvol_path})
|
'bspath': self.testvol_path})
|
||||||
|
|
||||||
|
def fake_get(self, value, default):
|
||||||
|
if value in ('iscsi_target_flags', 'iscsi_write_cache'):
|
||||||
|
return getattr(self, value, default)
|
||||||
|
|
||||||
def test_iscsi_protocol(self):
|
def test_iscsi_protocol(self):
|
||||||
self.assertEqual(self.target.iscsi_protocol, 'iscsi')
|
self.assertEqual(self.target.iscsi_protocol, 'iscsi')
|
||||||
|
|
||||||
|
@ -183,6 +189,42 @@ class TestTgtAdmDriver(tf.TargetDriverFixture):
|
||||||
0,
|
0,
|
||||||
self.fake_volumes_dir))
|
self.fake_volumes_dir))
|
||||||
|
|
||||||
|
def test_create_iscsi_target_content(self):
|
||||||
|
|
||||||
|
self.iscsi_target_flags = 'foo'
|
||||||
|
self.iscsi_write_cache = 'bar'
|
||||||
|
|
||||||
|
mock_open = mock.mock_open()
|
||||||
|
with mock.patch('cinder.utils.execute', return_value=('', '')),\
|
||||||
|
mock.patch.object(self.target, '_get_target',
|
||||||
|
side_effect=lambda x: 1),\
|
||||||
|
mock.patch.object(self.target, '_verify_backing_lun',
|
||||||
|
side_effect=lambda x, y: True),\
|
||||||
|
mock.patch('cinder.volume.targets.tgt.open',
|
||||||
|
mock_open, create=True):
|
||||||
|
self.assertEqual(
|
||||||
|
1,
|
||||||
|
self.target.create_iscsi_target(
|
||||||
|
self.test_vol,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
self.testvol_path,
|
||||||
|
chap_auth=('chap_foo', 'chap_bar')))
|
||||||
|
|
||||||
|
mock_open.assert_called_once_with(
|
||||||
|
os.path.join(self.fake_volumes_dir, self.test_vol.split(':')[1]),
|
||||||
|
'w+')
|
||||||
|
expected = ('\n<target iqn.2010-10.org.openstack:volume-%(id)s>\n'
|
||||||
|
' backing-store %(bspath)s\n'
|
||||||
|
' driver iscsi\n'
|
||||||
|
' incominguser chap_foo chap_bar\n'
|
||||||
|
' bsoflags foo\n'
|
||||||
|
' write-cache bar\n'
|
||||||
|
'</target>\n' % {'id': self.VOLUME_ID,
|
||||||
|
'bspath': self.testvol_path})
|
||||||
|
self.assertEqual(expected,
|
||||||
|
mock_open.return_value.write.call_args[0][0])
|
||||||
|
|
||||||
def test_create_iscsi_target_already_exists(self):
|
def test_create_iscsi_target_already_exists(self):
|
||||||
def _fake_execute(*args, **kwargs):
|
def _fake_execute(*args, **kwargs):
|
||||||
if 'update' in args:
|
if 'update' in args:
|
||||||
|
|
|
@ -143,6 +143,12 @@ volume_opts = [
|
||||||
'perform write-back(on) or write-through(off). '
|
'perform write-back(on) or write-through(off). '
|
||||||
'This parameter is valid if iscsi_helper is set '
|
'This parameter is valid if iscsi_helper is set '
|
||||||
'to tgtadm or iseradm.'),
|
'to tgtadm or iseradm.'),
|
||||||
|
cfg.StrOpt('iscsi_target_flags',
|
||||||
|
default='',
|
||||||
|
help='Sets the target-specific flags for the iSCSI target. '
|
||||||
|
'Only used for tgtadm to specify backing device flags '
|
||||||
|
'using bsoflags option. The specified string is passed '
|
||||||
|
'as is to the underlying tool.'),
|
||||||
cfg.StrOpt('iscsi_protocol',
|
cfg.StrOpt('iscsi_protocol',
|
||||||
default='iscsi',
|
default='iscsi',
|
||||||
choices=['iscsi', 'iser'],
|
choices=['iscsi', 'iser'],
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import textwrap
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from oslo_concurrency import processutils as putils
|
from oslo_concurrency import processutils as putils
|
||||||
|
@ -35,21 +36,15 @@ class TgtAdm(iscsi.ISCSITarget):
|
||||||
etc.
|
etc.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VOLUME_CONF = """
|
VOLUME_CONF = textwrap.dedent("""
|
||||||
<target %s>
|
<target %(name)s>
|
||||||
backing-store %s
|
backing-store %(path)s
|
||||||
driver %s
|
driver %(driver)s
|
||||||
write-cache %s
|
%(chap_auth)s
|
||||||
|
%(target_flags)s
|
||||||
|
write-cache %(write_cache)s
|
||||||
</target>
|
</target>
|
||||||
"""
|
""")
|
||||||
VOLUME_CONF_WITH_CHAP_AUTH = """
|
|
||||||
<target %s>
|
|
||||||
backing-store %s
|
|
||||||
driver %s
|
|
||||||
%s
|
|
||||||
write-cache %s
|
|
||||||
</target>
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(TgtAdm, self).__init__(*args, **kwargs)
|
super(TgtAdm, self).__init__(*args, **kwargs)
|
||||||
|
@ -178,14 +173,20 @@ class TgtAdm(iscsi.ISCSITarget):
|
||||||
vol_id = name.split(':')[1]
|
vol_id = name.split(':')[1]
|
||||||
write_cache = self.configuration.get('iscsi_write_cache', 'on')
|
write_cache = self.configuration.get('iscsi_write_cache', 'on')
|
||||||
driver = self.iscsi_protocol
|
driver = self.iscsi_protocol
|
||||||
|
chap_str = ''
|
||||||
|
|
||||||
if chap_auth is None:
|
if chap_auth is not None:
|
||||||
volume_conf = self.VOLUME_CONF % (name, path, driver, write_cache)
|
|
||||||
else:
|
|
||||||
chap_str = 'incominguser %s %s' % chap_auth
|
chap_str = 'incominguser %s %s' % chap_auth
|
||||||
volume_conf = self.VOLUME_CONF_WITH_CHAP_AUTH % (name, path,
|
|
||||||
driver, chap_str,
|
target_flags = self.configuration.get('iscsi_target_flags', '')
|
||||||
write_cache)
|
if target_flags:
|
||||||
|
target_flags = 'bsoflags ' + target_flags
|
||||||
|
|
||||||
|
volume_conf = self.VOLUME_CONF % {
|
||||||
|
'name': name, 'path': path, 'driver': driver,
|
||||||
|
'chap_auth': chap_str, 'target_flags': target_flags,
|
||||||
|
'write_cache': write_cache}
|
||||||
|
|
||||||
LOG.debug('Creating iscsi_target for Volume ID: %s', vol_id)
|
LOG.debug('Creating iscsi_target for Volume ID: %s', vol_id)
|
||||||
volumes_dir = self.volumes_dir
|
volumes_dir = self.volumes_dir
|
||||||
volume_path = os.path.join(volumes_dir, vol_id)
|
volume_path = os.path.join(volumes_dir, vol_id)
|
||||||
|
|
Loading…
Reference in New Issue