[PATCH 03/13] Add method to get size of existing filesystems.

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

 



The _getExistingSize() method in class FS will using the filesystem
info/dump utility to figure out the size of the filesystem.  Each
filesystem must define _infofs, _defaultInfoOptions, and
_existingSizeFields.
---
 storage/formats/fs.py |   93 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 92 insertions(+), 1 deletions(-)

diff --git a/storage/formats/fs.py b/storage/formats/fs.py
index f467852..5fbe62d 100644
--- a/storage/formats/fs.py
+++ b/storage/formats/fs.py
@@ -18,6 +18,7 @@
 # Red Hat, Inc.
 #
 # Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#                    David Cantrell <dcantrell@xxxxxxxxxx>
 #
 
 """ Filesystem classes for use by anaconda.
@@ -120,12 +121,15 @@ class FS(DeviceFormat):
     _labelfs = ""                        # labeling utility
     _fsck = ""                           # fs check utility
     _migratefs = ""                      # fs migration utility
+    _infofs = ""                         # fs info utility
     _defaultFormatOptions = []           # default options passed to mkfs
     _defaultMountOptions = ["defaults"]  # default options passed to mount
     _defaultLabelOptions = []
     _defaultCheckOptions = []
     _defaultMigrateOptions = []
+    _defaultInfoOptions = []
     _migrationTarget = None
+    _existingSizeFields = []
     lostAndFoundContext = None
 
     def __init__(self, *args, **kwargs):
@@ -150,8 +154,12 @@ class FS(DeviceFormat):
         self.mountpoint = kwargs.get("mountpoint")
         self.mountopts = kwargs.get("mountopts")
         self.label = kwargs.get("label")
+
         # filesystem size does not necessarily equal device size
         self._size = kwargs.get("size")
+        if self.exists:
+            self._size = self._getExistingSize()
+
         self._targetSize = self._size
         self._mountpoint = None     # the current mountpoint when mounted
 
@@ -187,6 +195,83 @@ class FS(DeviceFormat):
     size = property(_getSize, doc="This filesystem's size, accounting "
                                   "for pending changes")
 
+    def _getExistingSize(self):
+        """ Determine the size of this filesystem.  Filesystem must
+            exist.  Each filesystem varies, but the general procedure
+            is to run the filesystem dump or info utility and read
+            the block size and number of blocks for the filesystem
+            and compute megabytes from that.
+
+            The loop that reads the output from the infofsProg is meant
+            to be simple, but take in to account variations in output.
+            The general procedure:
+                1) Capture output from infofsProg.
+                2) Iterate over each line of the output:
+                       a) Trim leading and trailing whitespace.
+                       b) Break line into fields split on ' '
+                       c) If line begins with any of the strings in
+                          _existingSizeFields, start at the end of
+                          fields and take the first one that converts
+                          to a long.  Store this in the values list.
+                       d) Repeat until the values list length equals
+                          the _existingSizeFields length.
+                3) If the length of the values list equals the length
+                   of _existingSizeFields, compute the size of this
+                   filesystem by multiplying all of the values together
+                   to get bytes, then convert to megabytes.  Return
+                   this value.
+                4) If we were unable to capture all fields, return 0.
+
+            The caller should catch exceptions from this method.  Any
+            exception raised indicates a need to change the fields we
+            are looking for, the command to run and arguments, or
+            something else.  If you catch an exception from this method,
+            assume the filesystem cannot be resized.
+        """
+        size = 0
+
+        if self.exists:
+            values = []
+            argv = self._defaultInfoOptions + [ self.device ]
+
+            buf = iutil.execWithCapture(self.infofsProg, argv,
+                                        stderr="/dev/tty5")
+
+            for line in buf.splitlines():
+                found = False
+
+                line = line.strip()
+                tmp = line.split(' ')
+                tmp.reverse()
+
+                for field in self._existingSizeFields:
+                    if line.startswith(field):
+                        for subfield in tmp:
+                            try:
+                                values.append(long(subfield))
+                                found = True
+                                break
+                            except ValueError:
+                                continue
+
+                    if found:
+                        break
+
+                if len(values) == len(self._existingSizeFields):
+                    break
+
+            if len(values) != len(self._existingSizeFields):
+                return 0
+
+            size = 1
+            for value in values:
+                size *= value
+
+            # report current size as megabytes
+            size = size / 1024.0 / 1024.0
+
+        return size
+
     @property
     def currentSize(self):
         """ The filesystem's current actual size. """
@@ -547,13 +632,19 @@ class FS(DeviceFormat):
         return self._migratefs
 
     @property
+    def infofsProg(self):
+        """ Program used to get information about this filesyste. """
+        return self._infofs
+
+    @property
     def migrationTarget(self):
         return self._migrationTarget
 
     @property
     def utilsAvailable(self):
         # we aren't checking for fsck because we shouldn't need it
-        for prog in [self.mkfsProg, self.resizefsProg, self.labelfsProg]:
+        for prog in [self.mkfsProg, self.resizefsProg, self.labelfsProg,
+                     self.infofsProg]:
             if not prog:
                 continue
 
-- 
1.6.2

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux