]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/ceph-volume/ceph_volume/util/device.py
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / ceph-volume / ceph_volume / util / device.py
index ea478f3877d7891f3ed88189a4e061a2a8da9b34..878a584ce690bab179a54c84b8b2f3443664dc4c 100644 (file)
@@ -2,7 +2,7 @@
 
 import os
 from functools import total_ordering
-from ceph_volume import sys_info
+from ceph_volume import sys_info, process
 from ceph_volume.api import lvm
 from ceph_volume.util import disk
 from ceph_volume.util.constants import ceph_disk_guids
@@ -80,17 +80,23 @@ class Device(object):
         # LVs can have a vg/lv path, while disks will have /dev/sda
         self.abspath = path
         self.lv_api = None
+        self.vgs = []
         self.lvs = []
         self.vg_name = None
         self.lv_name = None
-        self.pvs_api = []
         self.disk_api = {}
         self.blkid_api = {}
         self.sys_api = {}
         self._exists = None
         self._is_lvm_member = None
         self._parse()
-        self.available, self.rejected_reasons = self._check_reject_reasons()
+
+        self.available_lvm, self.rejected_reasons_lvm = self._check_lvm_reject_reasons()
+        self.available_raw, self.rejected_reasons_raw = self._check_raw_reject_reasons()
+        self.available = self.available_lvm and self.available_raw
+        self.rejected_reasons = list(set(self.rejected_reasons_lvm +
+                                         self.rejected_reasons_raw))
+
         self.device_id = self._get_device_id()
 
     def __lt__(self, other):
@@ -231,23 +237,17 @@ class Device(object):
             # here, because most likely, we need to use VGs from this PV.
             self._is_lvm_member = False
             for path in self._get_pv_paths():
-                # check if there was a pv created with the
-                # name of device
-                pvs = lvm.PVolumes().filter(pv_name=path)
-                has_vgs = [pv.vg_name for pv in pvs if pv.vg_name]
-                if has_vgs:
-                    self.vgs = list(set(has_vgs))
+                vgs = lvm.get_device_vgs(path)
+                if vgs:
+                    self.vgs.extend(vgs)
                     # a pv can only be in one vg, so this should be safe
-                    self.vg_name = has_vgs[0]
+                    # FIXME: While the above assumption holds, sda1 and sda2
+                    # can each host a PV and VG. I think the vg_name property is
+                    # actually unused (not 100% sure) and can simply be removed
+                    self.vg_name = vgs[0]
                     self._is_lvm_member = True
-                    self.pvs_api = pvs
-                    for pv in pvs:
-                        if pv.vg_name and pv.lv_uuid:
-                            lv = lvm.get_lv(vg_name=pv.vg_name, lv_uuid=pv.lv_uuid)
-                            if lv:
-                                self.lvs.append(lv)
-                else:
-                    self.vgs = []
+
+                    self.lvs.extend(lvm.get_device_lvs(path))
         return self._is_lvm_member
 
     def _get_pv_paths(self):
@@ -317,6 +317,15 @@ class Device(object):
                     break
         return is_member
 
+    @property
+    def has_bluestore_label(self):
+        out, err, ret = process.call([
+            'ceph-bluestore-tool', 'show-label',
+            '--dev', self.abspath], verbose_on_failure=False)
+        if ret:
+            return False
+        return True
+
     @property
     def is_mapper(self):
         return self.path.startswith(('/dev/mapper', '/dev/dm-'))
@@ -375,13 +384,8 @@ class Device(object):
                    if lv.tags.get("ceph.type") in ["data", "block"]]
         return any(osd_ids)
 
-    def _check_reject_reasons(self):
-        """
-        This checks a number of potential reject reasons for a drive and
-        returns a tuple (boolean, list). The first element denotes whether a
-        drive is available or not, the second element lists reasons in case a
-        drive is not available.
-        """
+
+    def _check_generic_reject_reasons(self):
         reasons = [
             ('removable', 1, 'removable'),
             ('ro', 1, 'read-only'),
@@ -389,8 +393,27 @@ class Device(object):
         ]
         rejected = [reason for (k, v, reason) in reasons if
                     self.sys_api.get(k, '') == v]
+        # reject disks small than 5GB
+        if int(self.sys_api.get('size', 0)) < 5368709120:
+            rejected.append('Insufficient space (<5GB)')
         if self.is_ceph_disk_member:
             rejected.append("Used by ceph-disk")
+        if self.has_bluestore_label:
+            rejected.append('Has BlueStore device label')
+        return rejected
+
+    def _check_lvm_reject_reasons(self):
+        rejected = self._check_generic_reject_reasons()
+        available_vgs = [vg for vg in self.vgs if vg.free >= 5368709120]
+        if self.vgs and not available_vgs:
+            rejected.append('Insufficient space (<5GB) on vgs')
+
+        return len(rejected) == 0, rejected
+
+    def _check_raw_reject_reasons(self):
+        rejected = self._check_generic_reject_reasons()
+        if len(self.vgs) > 0:
+            rejected.append('LVM detected')
 
         return len(rejected) == 0, rejected