[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH] Add a parted.Device attribute to all existing StorageDevices.



This provides a handy way to obtain sizes of devices.
---
 storage/devices.py |  132 +++++++++++++++++++++++++--------------------------
 1 files changed, 65 insertions(+), 67 deletions(-)

diff --git a/storage/devices.py b/storage/devices.py
index f75463f..d0b00b8 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -200,7 +200,7 @@ class Device(object):
         """
         new = self.__class__.__new__(self.__class__)
         memo[id(self)] = new
-        shallow_copy_attrs = ('partedDisk', 'partedDevice',
+        shallow_copy_attrs = ('partedDisk', '_partedDevice',
                              '_partedPartition', '_origPartedDisk',
                              '_raidSet')
         for (attr, value) in self.__dict__.items():
@@ -411,6 +411,24 @@ class StorageDevice(Device):
         self.fstabComment = ""
         self._targetSize = self._size
 
+        self._partedDevice = None
+
+    @property
+    def partedDevice(self):
+        if self.exists and self.status and not self._partedDevice:
+            log.debug("looking up parted Device: %s" % self.path)
+
+            # We aren't guaranteed to be able to get a device.  In
+            # particular, built-in USB flash readers show up as devices but
+            # do not always have any media present, so parted won't be able
+            # to find a device.
+            try:
+                self._partedDevice = parted.Device(path=self.path)
+            except _ped.DeviceException:
+                pass
+
+        return self._partedDevice
+
     def _getTargetSize(self):
         return self._targetSize
 
@@ -440,10 +458,6 @@ class StorageDevice(Device):
         """ Device node representing this device. """
         return "%s/%s" % (self._devDir, self.name)
 
-    def probe(self):
-        """ Probe for any missing information about this device. """
-        raise NotImplementedError("probe method not defined for StorageDevice")
-
     def updateSysfsPath(self):
         """ Update this device's sysfs path. """
         log_method_call(self, self.name, status=self.status)
@@ -515,10 +529,17 @@ class StorageDevice(Device):
             self.teardownParents(recursive=recursive)
 
     def _getSize(self):
-        """ Get the device's size, accounting for pending changes. """
+        """ Get the device's size in MB, accounting for pending changes. """
+        if self.exists and not self.mediaPresent:
+            return 0
+
+        if self.exists and self.partedDevice:
+            self._size = self.currentSize
+
         size = self._size
-        if self.resizable and self.targetSize != size:
+        if self.exists and self.resizable and self.targetSize != size:
             size = self.targetSize
+
         return size
 
     def _setSize(self, newsize):
@@ -530,13 +551,15 @@ class StorageDevice(Device):
 
     size = property(lambda x: x._getSize(),
                     lambda x, y: x._setSize(y),
-                    doc="The device's size, accounting for pending changes")
+                    doc="The device's size in MB, accounting for pending changes")
 
     @property
     def currentSize(self):
         """ The device's actual size. """
         size = 0
-        if self.exists:
+        if self.exists and self.partedDevice:
+            size = self.partedDevice.getSize()
+        elif self.exists:
             size = self._size
         return size
 
@@ -656,19 +679,10 @@ class DiskDevice(StorageDevice):
                                major=major, minor=minor, exists=True,
                                sysfsPath=sysfsPath, parents=parents)
 
-        self.partedDevice = None
         self.partedDisk = None
 
         log.debug("looking up parted Device: %s" % self.path)
 
-        # We aren't guaranteed to be able to get a device.  In particular,
-        # built-in USB flash readers show up as devices but do not always
-        # have any media present, so parted won't be able to find a device.
-        try:
-            self.partedDevice = parted.Device(path=self.path)
-        except _ped.DeviceException:
-            pass
-
         if self.partedDevice:
             log.debug("creating parted Disk: %s" % self.path)
             if initlabel:
@@ -693,8 +707,6 @@ class DiskDevice(StorageDevice):
         else:
             self._origPartedDisk = None
 
-        self.probe()
-
     def __str__(self):
         s = StorageDevice.__str__(self)
         s += ("  removable = %(removable)s  partedDevice = %(partedDevice)r\n"
@@ -719,12 +731,8 @@ class DiskDevice(StorageDevice):
     @property
     def size(self):
         """ The disk's size in MB """
-        if not self.mediaPresent:
-            return 0
-
-        if not self._size:
-            self._size = self.partedDisk.device.getSize()
-        return self._size
+        return super(DiskDevice, self).size
+    #size = property(StorageDevice._getSize)
 
     def resetPartedDisk(self):
         """ Reset parted.Disk to reflect the actual layout of the disk. """
@@ -764,12 +772,7 @@ class DiskDevice(StorageDevice):
             pyparted should be able to tell us anything we want to know.
             size, disklabel type, maybe even partition layout
         """
-        if not self.mediaPresent or not 'parted' in globals().keys():
-            return
-
         log_method_call(self, self.name, size=self.size, partedDevice=self.partedDevice)
-        if not self.size:
-            self._size = self.partedDevice.getSize()
         if not self.diskLabel:
             log.debug("setting %s diskLabel to %s" % (self.name,
                                                       self.partedDisk.type))
@@ -1312,13 +1315,6 @@ class DMDevice(StorageDevice):
               {"target": self.target, "dmUuid": self.dmUuid})
         return s
 
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            target type, parents?
-        """
-        raise NotImplementedError("probe method not defined for DMDevice")
-
     @property
     def fstabSpec(self):
         """ Return the device specifier for use in /etc/fstab. """
@@ -1412,8 +1408,11 @@ class LUKSDevice(DMCryptDevice):
 
     @property
     def size(self):
-        # break off 2KB for the LUKS header
-        return float(self.slave.size) - (2.0 / 1024)
+        size = super(LUKSDevice, self).size
+        if not size:
+            # break off 2KB for the LUKS header
+            size = float(self.slave.size) - (2.0 / 1024)
+        return size
 
     def create(self, intf=None):
         """ Create the device. """
@@ -1439,6 +1438,10 @@ class LUKSDevice(DMCryptDevice):
         self.slave.setup()
         self.slave.format.setup()
 
+        # we always probe since the device may not be set up when we want
+        # information about it
+        self._size = self.currentSize
+
     def teardown(self, recursive=False):
         """ Close, or tear down, a device. """
         log_method_call(self, self.name, status=self.status)
@@ -1896,13 +1899,6 @@ class LVMLogicalVolumeDevice(DMDevice):
               {"vgdev": self.vg, "percent": self.req_percent})
         return s
 
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            size
-        """
-        raise NotImplementedError("probe method not defined for StorageDevice")
-
     def _setSize(self, size):
         size = self.vg.align(numeric_type(size))
         log.debug("trying to set lv %s size to %dMB" % (self.name, size))
@@ -1913,7 +1909,7 @@ class LVMLogicalVolumeDevice(DMDevice):
             log.debug("failed to set size: %dMB short" % (size - (self.vg.freeSpace + self._size),))
             raise ValueError("not enough free space in volume group")
 
-    size = property(lambda d: d._size, _setSize)
+    size = property(StorageDevice._getSize, _setSize)
 
     @property
     def vg(self):
@@ -1947,6 +1943,10 @@ class LVMLogicalVolumeDevice(DMDevice):
         self.vg.setup()
         lvm.lvactivate(self.vg.name, self._name)
 
+        # we always probe since the device may not be set up when we want
+        # information about it
+        self._size = self.currentSize
+
     def teardown(self, recursive=None):
         """ Close, or tear down, a device. """
         log_method_call(self, self.name, status=self.status)
@@ -2053,8 +2053,9 @@ class MDRaidArrayDevice(StorageDevice):
         if not self.formatClass:
             raise DeviceError("cannot find class for 'mdmember'")
 
-        #self.probe()
         if self.exists and self.uuid:
+            # this is a hack to work around mdadm's insistence on giving
+            # really high minors to arrays it has no config entry for
             open("/etc/mdadm.conf", "a").write("ARRAY %s UUID=%s\n"
                                                 % (self.path, self.uuid))
 
@@ -2064,6 +2065,7 @@ class MDRaidArrayDevice(StorageDevice):
         for device in self.devices:
             if size is None or device.size < size:
                 size = device.size
+
         return size
 
     def __str__(self):
@@ -2199,6 +2201,11 @@ class MDRaidArrayDevice(StorageDevice):
             log.warning("failed to add member %s to md array %s: %s"
                         % (device.path, self.path, e))
 
+        if self.status:
+            # we always probe since the device may not be set up when we want
+            # information about it
+            self._size = self.currentSize
+
     def _removeDevice(self, device):
         """ Remove a component device from the array.
 
@@ -2276,6 +2283,10 @@ class MDRaidArrayDevice(StorageDevice):
 
         udev_settle()
 
+        # we always probe since the device may not be set up when we want
+        # information about it
+        self._size = self.currentSize
+
     def teardown(self, recursive=None):
         """ Close, or tear down, a device. """
         log_method_call(self, self.name, status=self.status)
@@ -2449,6 +2460,10 @@ class DMRaidArrayDevice(DiskDevice):
 
         udev_settle()
 
+        # we always probe since the device may not be set up when we want
+        # information about it
+        self._size = self.currentSize
+
 
 class MultipathDevice(DMDevice):
     """ A multipath device """
@@ -2475,13 +2490,6 @@ class MultipathDevice(DMDevice):
                           parents=parents, sysfsPath=sysfsPath,
                           exists=exists)
 
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            size
-        """
-        raise NotImplementedError("probe method not defined for MultipathDevice")
-
 
 class NoDevice(StorageDevice):
     """ A nodev device for nodev filesystems like tmpfs. """
@@ -2672,6 +2680,7 @@ class iScsiDiskDevice(DiskDevice, NetworkStorageDevice):
         NetworkStorageDevice.__init__(self, self.iscsi_address)
         log.debug("created new iscsi disk %s %s:%d" % (self.iscsi_name, self.iscsi_address, self.iscsi_port))
 
+
 class OpticalDevice(StorageDevice):
     """ An optical drive, eg: cdrom, dvd+r, &c.
 
@@ -2747,13 +2756,6 @@ class ZFCPDiskDevice(DiskDevice):
               {"devnum": self.devnum, "wwpn": self.wwpn, "fcplun": self.fcplun})
         return s
 
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            devnum, wwpn, fcplun
-        """
-        raise NotImplementedError("probe method not defined for StorageDevice")
-
 
 class DASDDevice(DiskDevice):
     """ A mainframe DASD. """
@@ -2765,10 +2767,6 @@ class DASDDevice(DiskDevice):
                             major=major, minor=minor,
                             parents=parents, sysfsPath=sysfsPath)
 
-    def probe(self):
-        """ Probe for any missing information about this device. """
-        raise NotImplementedError("probe method not defined for StorageDevice")
-
 
 class NFSDevice(StorageDevice, NetworkStorageDevice):
     """ An NFS device """
-- 
1.6.0.6


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]