On Fri, 2009-03-13 at 18:09 -1000, David Cantrell wrote: > 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. Looks okay to me. This is kind of scary stuff, but I think that's just how it is when you have to parse output like this. Dave > --- > 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 > _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list