]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume: batch ensure device lists are disjoint 29690/head
authorJan Fajerski <jfajerski@suse.com>
Thu, 11 Apr 2019 14:58:32 +0000 (16:58 +0200)
committerJan Fajerski <jfajerski@suse.com>
Thu, 15 Aug 2019 13:58:52 +0000 (15:58 +0200)
Fixes: https://tracker.ceph.com/issues/41018
Signed-off-by: Jan Fajerski <jfajerski@suse.com>
(cherry picked from commit 8fcdb4d628f3a55e4783f0a3df7ac7c0a36eaa43)

src/ceph-volume/ceph_volume/devices/lvm/batch.py
src/ceph-volume/ceph_volume/tests/devices/lvm/test_batch.py

index e5bbe40d7df8d2452fd20589f714af25dff767e8..223aa4ac99ccb337d8b04b4929ea2364dce27d45 100644 (file)
@@ -254,7 +254,7 @@ class Batch(object):
         self.args = parser.parse_args(argv)
         self.parser = parser
         for dev_list in ['', 'db_', 'wal_', 'journal_']:
-            setattr(self, '{}usable'.format(dev_list), [])
+            setattr(self, '{}usable'.format(dev_list), set())
 
     def get_devices(self):
         # remove devices with partitions
@@ -327,6 +327,7 @@ class Batch(object):
     def _get_explicit_strategy(self):
         # TODO assert that none of the device lists overlap?
         self._filter_devices()
+        self._ensure_disjoint_device_lists()
         if self.args.bluestore:
             if self.db_usable or self.wal_usable:
                 self.strategy = strategies.bluestore.MixedType(
@@ -360,8 +361,17 @@ class Batch(object):
             dev_list_prop = '{}devices'.format(dev_list)
             if hasattr(self.args, dev_list_prop):
                 usable_dev_list_prop = '{}usable'.format(dev_list)
-                usable = [d for d in getattr(self.args, dev_list_prop) if d.available]
+                usable = set([d for d in getattr(self.args, dev_list_prop) if
+                              d.available])
                 setattr(self, usable_dev_list_prop, usable)
                 self.filtered_devices.update({d: used_reason for d in
                                               getattr(self.args, dev_list_prop)
                                               if d.used_by_ceph})
+
+    def _ensure_disjoint_device_lists(self):
+        # check that all device lists are disjoint with each other
+        if not(self.usable.isdisjoint(self.db_usable) and
+               self.usable.isdisjoint(self.wal_usable) and
+               self.usable.isdisjoint(self.journal_usable) and
+               self.db_usable.isdisjoint(self.wal_usable)):
+            raise Exception('Device lists are not disjoint')
index 7ad77ab1ef096209df59bbc114f8403ee2d2e52d..f03110289844e9ab6281f740f7a5d7c8c8eb4c55 100644 (file)
@@ -1,3 +1,4 @@
+import pytest
 from ceph_volume.devices.lvm import batch
 
 
@@ -55,6 +56,16 @@ class TestBatch(object):
         result = b.get_devices().strip()
         assert result == '* /dev/vdf                  20.00 GB   rotational'
 
+    def test_disjoint_device_lists(self, factory):
+        device1 = factory(used_by_ceph=False, available=True, abspath="/dev/sda")
+        device2 = factory(used_by_ceph=False, available=True, abspath="/dev/sdb")
+        b = batch.Batch([])
+        b.args.devices = [device1, device2]
+        b.args.db_devices = [device2]
+        b._filter_devices()
+        with pytest.raises(Exception):
+            b._ensure_disjoint_device_lists()
+
 
 class TestFilterDevices(object):