Browse Source

Fix FC multipath cleanup

Cleanup order for multipath should be:
- Flush multipath (multipath -f device)
- Flush blockdev devices (blockdev --flushbufs device)
- Remove paths

But now we have:
- Flush blockdev devices (blockdev --flushbufs device)
- Flush multipath (multipath -f device)
- Remove paths

This patch sets the right order and adds a test to avoid regression.

Closes-Bug: #1502979
Change-Id: I065a79514e0fcaf722f57e2edd6f18f31878c711
Gorka Eguileor 3 years ago
parent
commit
d937f64af2

+ 3
- 3
os_brick/initiator/connectors/fibre_channel.py View File

@@ -268,15 +268,15 @@ class FibreChannelConnector(base.BaseLinuxConnector):
268 268
             device_info = self._linuxscsi.get_device_info(real_path)
269 269
             devices.append(device_info)
270 270
 
271
-        LOG.debug("devices to remove = %s", devices)
272
-        self._remove_devices(connection_properties, devices)
273
-
274 271
         if self.use_multipath:
275 272
             # There is a bug in multipath where the flushing
276 273
             # doesn't remove the entry if friendly names are on
277 274
             # we'll try anyway.
278 275
             self._linuxscsi.flush_multipath_device(wwn)
279 276
 
277
+        LOG.debug("devices to remove = %s", devices)
278
+        self._remove_devices(connection_properties, devices)
279
+
280 280
     def _remove_devices(self, connection_properties, devices):
281 281
         # There may have been more than 1 device mounted
282 282
         # by the kernel for this volume.  We have to remove

+ 19
- 17
os_brick/tests/initiator/connectors/test_fibre_channel.py View File

@@ -195,7 +195,6 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
195 195
 
196 196
     def _test_connect_volume_multipath(self, get_device_info_mock,
197 197
                                        get_scsi_wwn_mock,
198
-                                       remove_device_mock,
199 198
                                        get_fc_hbas_info_mock,
200 199
                                        get_fc_hbas_mock,
201 200
                                        realpath_mock,
@@ -215,8 +214,12 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
215 214
                    "devices": [{'device': '/dev/sdb',
216 215
                                 'address': '1:0:0:1',
217 216
                                 'host': 1, 'channel': 0,
217
+                                'id': 0, 'lun': 1},
218
+                               {'device': '/dev/sdc',
219
+                                'address': '1:0:0:2',
220
+                                'host': 1, 'channel': 0,
218 221
                                 'id': 0, 'lun': 1}]}
219
-        get_device_info_mock.return_value = devices['devices'][0]
222
+        get_device_info_mock.side_effect = devices['devices']
220 223
         get_scsi_wwn_mock.return_value = wwn
221 224
 
222 225
         location = '10.0.2.15:3260'
@@ -233,6 +236,17 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
233 236
         self.connector.connect_volume(connection_info['data'])
234 237
 
235 238
         self.assertEqual(should_wait_for_rw, wait_for_rw_mock.called)
239
+
240
+        self.connector.disconnect_volume(connection_info['data'],
241
+                                         devices['devices'][0])
242
+        expected_commands = [
243
+            'multipath -f ' + wwn,
244
+            'blockdev --flushbufs /dev/sdb',
245
+            'tee -a /sys/block/sdb/device/delete',
246
+            'blockdev --flushbufs /dev/sdc',
247
+            'tee -a /sys/block/sdc/device/delete',
248
+        ]
249
+        self.assertEqual(expected_commands, self.cmds)
236 250
         return connection_info
237 251
 
238 252
     @mock.patch.object(linuxscsi.LinuxSCSI, 'find_multipath_device')
@@ -241,12 +255,10 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
241 255
     @mock.patch.object(os.path, 'realpath', return_value='/dev/sdb')
242 256
     @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas')
243 257
     @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info')
244
-    @mock.patch.object(linuxscsi.LinuxSCSI, 'remove_scsi_device')
245 258
     @mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
246 259
     @mock.patch.object(linuxscsi.LinuxSCSI, 'get_device_info')
247 260
     def test_connect_volume_multipath_rw(self, get_device_info_mock,
248 261
                                          get_scsi_wwn_mock,
249
-                                         remove_device_mock,
250 262
                                          get_fc_hbas_info_mock,
251 263
                                          get_fc_hbas_mock,
252 264
                                          realpath_mock,
@@ -256,7 +268,6 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
256 268
 
257 269
         self._test_connect_volume_multipath(get_device_info_mock,
258 270
                                             get_scsi_wwn_mock,
259
-                                            remove_device_mock,
260 271
                                             get_fc_hbas_info_mock,
261 272
                                             get_fc_hbas_mock,
262 273
                                             realpath_mock,
@@ -272,13 +283,11 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
272 283
     @mock.patch.object(os.path, 'realpath', return_value='/dev/sdb')
273 284
     @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas')
274 285
     @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info')
275
-    @mock.patch.object(linuxscsi.LinuxSCSI, 'remove_scsi_device')
276 286
     @mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
277 287
     @mock.patch.object(linuxscsi.LinuxSCSI, 'get_device_info')
278 288
     def test_connect_volume_multipath_no_access_mode(self,
279 289
                                                      get_device_info_mock,
280 290
                                                      get_scsi_wwn_mock,
281
-                                                     remove_device_mock,
282 291
                                                      get_fc_hbas_info_mock,
283 292
                                                      get_fc_hbas_mock,
284 293
                                                      realpath_mock,
@@ -288,7 +297,6 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
288 297
 
289 298
         self._test_connect_volume_multipath(get_device_info_mock,
290 299
                                             get_scsi_wwn_mock,
291
-                                            remove_device_mock,
292 300
                                             get_fc_hbas_info_mock,
293 301
                                             get_fc_hbas_mock,
294 302
                                             realpath_mock,
@@ -304,12 +312,10 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
304 312
     @mock.patch.object(os.path, 'realpath', return_value='/dev/sdb')
305 313
     @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas')
306 314
     @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info')
307
-    @mock.patch.object(linuxscsi.LinuxSCSI, 'remove_scsi_device')
308 315
     @mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
309 316
     @mock.patch.object(linuxscsi.LinuxSCSI, 'get_device_info')
310 317
     def test_connect_volume_multipath_ro(self, get_device_info_mock,
311 318
                                          get_scsi_wwn_mock,
312
-                                         remove_device_mock,
313 319
                                          get_fc_hbas_info_mock,
314 320
                                          get_fc_hbas_mock,
315 321
                                          realpath_mock,
@@ -319,7 +325,6 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
319 325
 
320 326
         self._test_connect_volume_multipath(get_device_info_mock,
321 327
                                             get_scsi_wwn_mock,
322
-                                            remove_device_mock,
323 328
                                             get_fc_hbas_info_mock,
324 329
                                             get_fc_hbas_mock,
325 330
                                             realpath_mock,
@@ -336,13 +341,11 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
336 341
     @mock.patch.object(os.path, 'realpath', return_value='/dev/sdb')
337 342
     @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas')
338 343
     @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info')
339
-    @mock.patch.object(linuxscsi.LinuxSCSI, 'remove_scsi_device')
340 344
     @mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
341 345
     @mock.patch.object(linuxscsi.LinuxSCSI, 'get_device_info')
342 346
     def test_connect_volume_multipath_not_found(self,
343 347
                                                 get_device_info_mock,
344 348
                                                 get_scsi_wwn_mock,
345
-                                                remove_device_mock,
346 349
                                                 get_fc_hbas_info_mock,
347 350
                                                 get_fc_hbas_mock,
348 351
                                                 realpath_mock,
@@ -354,10 +357,9 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
354 357
                                              None)
355 358
 
356 359
         connection_info = self._test_connect_volume_multipath(
357
-            get_device_info_mock, get_scsi_wwn_mock, remove_device_mock,
358
-            get_fc_hbas_info_mock, get_fc_hbas_mock, realpath_mock,
359
-            exists_mock, wait_for_rw_mock, find_mp_dev_mock,
360
-            'rw', False)
360
+            get_device_info_mock, get_scsi_wwn_mock, get_fc_hbas_info_mock,
361
+            get_fc_hbas_mock, realpath_mock, exists_mock, wait_for_rw_mock,
362
+            find_mp_dev_mock, 'rw', False)
361 363
 
362 364
         self.assertNotIn('multipathd_id', connection_info['data'])
363 365
 

Loading…
Cancel
Save