]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Configure write cache option of tgtd iscsi driver
authorMitsuhiro Tanino <mitsuhiro.tanino@hds.com>
Tue, 8 Jul 2014 19:52:11 +0000 (15:52 -0400)
committerMitsuhiro Tanino <mitsuhiro.tanino@hds.com>
Tue, 8 Jul 2014 22:10:05 +0000 (18:10 -0400)
Cinder LVMiSCSI driver is using default value of write-cache parameter
of tgtd iscsi driver. In this setting, write I/O from guest instance is
cached on dirty cache of a host.(write-back mode)

In this case, data lost may be occurred if the host crashes before
flushing dirty cache. This may cause a lot of instances to lose
their data.

In order to avoid this issue, it is better to turn off the write cache.
(write-through mode)

This patch adds "iscsi_write_cache" parameter to configure a behavior of
write cache. The default value is "iscsi_write_cache=on".(write-back mode)

Closes-Bug: 1336568
DocImpact

Change-Id: I7a495bc6118d4254576bdf1620a04ac537b3078d
Signed-off-by: Mitsuhiro Tanino <mitsuhiro.tanino@hds.com>
cinder/brick/iscsi/iscsi.py
cinder/tests/test_iscsi.py
cinder/volume/driver.py
cinder/volume/drivers/lvm.py
cinder/volume/iscsi.py
etc/cinder/cinder.conf.sample

index 4ae78fee906e400920898dd76a2824c9c220fe3d..48e4dad087591417a46188b9f1a4e519cb55c56b 100644 (file)
@@ -83,6 +83,7 @@ class TgtAdm(TargetAdmin):
                 <target %s>
                     backing-store %s
                     lld iscsi
+                    write-cache %s
                 </target>
                   """
     VOLUME_CONF_WITH_CHAP_AUTH = """
@@ -90,6 +91,7 @@ class TgtAdm(TargetAdmin):
                                     backing-store %s
                                     lld iscsi
                                     %s
+                                    write-cache %s
                                 </target>
                                  """
 
@@ -165,11 +167,13 @@ class TgtAdm(TargetAdmin):
         fileutils.ensure_tree(self.volumes_dir)
 
         vol_id = name.split(':')[1]
+        write_cache = kwargs.get('write_cache', 'on')
         if chap_auth is None:
-            volume_conf = self.VOLUME_CONF % (name, path)
+            volume_conf = self.VOLUME_CONF % (name, path, write_cache)
         else:
             volume_conf = self.VOLUME_CONF_WITH_CHAP_AUTH % (name,
-                                                             path, chap_auth)
+                                                             path, chap_auth,
+                                                             write_cache)
 
         LOG.info(_('Creating iscsi_target for: %s') % vol_id)
         volumes_dir = self.volumes_dir
@@ -600,6 +604,7 @@ class ISERTgtAdm(TgtAdm):
                 <target %s>
                     driver iser
                     backing-store %s
+                    write_cache %s
                 </target>
                   """
     VOLUME_CONF_WITH_CHAP_AUTH = """
@@ -607,6 +612,7 @@ class ISERTgtAdm(TgtAdm):
                                     driver iser
                                     backing-store %s
                                     %s
+                                    write_cache %s
                                 </target>
                                  """
 
index d24989be203f7d992c14034989b3b91fe25acbfe..74e40f13b7d139b83c10a365e31a79fa9c3a8e7c 100644 (file)
@@ -34,6 +34,7 @@ class TargetAdminTestCase(object):
         self.path = '/foo'
         self.vol_id = 'blaa'
         self.vol_name = 'volume-blaa'
+        self.write_cache = 'off'
         self.db = {}
 
         self.script_template = None
@@ -93,7 +94,8 @@ class TargetAdminTestCase(object):
         target_helper = self.driver.get_target_helper(self.db)
         target_helper.set_execute(self.fake_execute)
         target_helper.create_iscsi_target(self.target_name, self.tid,
-                                          self.lun, self.path)
+                                          self.lun, self.path,
+                                          write_cache=self.write_cache)
         target_helper.show_target(self.tid, iqn=self.target_name)
         target_helper.remove_iscsi_target(self.tid, self.lun, self.vol_id,
                                           self.vol_name)
index 87129dbfd0ee1be105cf88eab0b2695b24047f19..31a77b72ff24bd88916515ef3c96d7dcebf3ec2d 100644 (file)
@@ -111,6 +111,12 @@ volume_opts = [
                default=0,
                help='The upper limit of bandwidth of volume copy. '
                     '0 => unlimited'),
+    cfg.StrOpt('iscsi_write_cache',
+               default='on',
+               help='Sets the behavior of the iSCSI target to either '
+                    'perform write-back(on) or write-through(off). '
+                    'This parameter is valid if iscsi_helper is set '
+                    'to tgtadm or iseradm.'),
 ]
 
 # for backward compatibility
index dc98a78703ca2579501d774f42dca257a45d49b7..5ca82862c73f3090b0b40a6645a2133d3c745c61 100644 (file)
@@ -519,7 +519,8 @@ class LVMISCSIDriver(LVMVolumeDriver, driver.ISCSIDriver):
             context, volume,
             iscsi_name,
             volume_path,
-            self.configuration.volume_group)
+            self.configuration.volume_group,
+            self.configuration)
         if model_update:
             self.db.volume_update(context, volume['id'], model_update)
 
index 22649324b7d70b08ff70b6f6f16a81abe1e0fae4..f13eebea1f479dc47e6e4184d07ef35d3fe1086d 100644 (file)
@@ -52,7 +52,9 @@ class _ExportMixin(object):
                                        iscsi_target,
                                        0,
                                        volume_path,
-                                       chap_auth)
+                                       chap_auth,
+                                       write_cache=
+                                       conf.iscsi_write_cache)
         data = {}
         data['location'] = self._iscsi_location(
             conf.iscsi_ip_address, tid, iscsi_name, conf.iscsi_port, lun)
@@ -86,7 +88,7 @@ class _ExportMixin(object):
         self.remove_iscsi_target(iscsi_target, 0, volume['id'], volume['name'])
 
     def ensure_export(self, context, volume, iscsi_name, volume_path,
-                      vg_name, old_name=None):
+                      vg_name, conf, old_name=None):
         iscsi_target = self._get_target_for_ensure_export(context,
                                                           volume['id'])
         if iscsi_target is None:
@@ -106,7 +108,8 @@ class _ExportMixin(object):
                 old_name = None
         self.create_iscsi_target(iscsi_name, iscsi_target, 0, volume_path,
                                  chap_auth, check_exit_code=False,
-                                 old_name=old_name)
+                                 old_name=old_name,
+                                 write_cache=conf.iscsi_write_cache)
 
     def _ensure_iscsi_targets(self, context, host, max_targets):
         """Ensure that target ids have been created in datastore."""
@@ -223,7 +226,7 @@ class FakeIscsiHelper(_ExportMixin, iscsi.FakeIscsiHelper):
         pass
 
     def ensure_export(self, context, volume, iscsi_name, volume_path,
-                      vg_name, old_name=None):
+                      vg_name, conf, old_name=None):
         pass
 
 
@@ -241,7 +244,7 @@ class LioAdm(_ExportMixin, iscsi.LioAdm):
         self.remove_iscsi_target(iscsi_target, 0, volume['id'], volume['name'])
 
     def ensure_export(self, context, volume, iscsi_name, volume_path,
-                      vg_name, old_name=None):
+                      vg_name, conf, old_name=None):
         try:
             volume_info = self.db.volume_get(context, volume['id'])
             (auth_method,
index 887547bd45ad3d7016f830210f1249402de78169..dc56ee2ad992cf82420c3d8bf13699701eba089d 100644 (file)
 # (integer value)
 #volume_copy_bps_limit=0
 
+# Sets the behavior of the iSCSI target to either perform
+# write-back(on) or write-through(off). This parameter is
+# valid if iscsi_helper is set to tgtadm or iseradm. (string
+# value)
+#iscsi_write_cache=on
+
 
 #
 # Options defined in cinder.volume.drivers.block_device