diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py index 353a9ef38..dfe5eadb5 100644 --- a/blivet/formats/fs.py +++ b/blivet/formats/fs.py @@ -353,17 +353,12 @@ def update_size_info(self): if not self.exists: return - self._current_info = None self._min_instance_size = Size(0) self._resizable = self.__class__._resizable # try to gather current size info self._size = Size(0) - try: - if self._info.available: - self._current_info = self._info.do_task() - except FSError as e: - log.info("Failed to obtain info for device %s: %s", self.device, e) + udev.settle() try: self._size = self._size_info.do_task() except (FSError, NotImplementedError) as e: diff --git a/blivet/tasks/fssize.py b/blivet/tasks/fssize.py index 504a7eabb..b8045cdc6 100644 --- a/blivet/tasks/fssize.py +++ b/blivet/tasks/fssize.py @@ -22,12 +22,17 @@ import abc import os +from .. import udev from ..errors import FSError from ..size import Size from . import fstask +import logging +log = logging.getLogger("blivet") + + class FSSize(fstask.FSTask, metaclass=abc.ABCMeta): """ An abstract class that represents size information extraction. """ @@ -44,10 +49,20 @@ def depends_on(self): return [self.fs._info] @abc.abstractmethod - def _get_size(self): + def _get_size_tools(self): raise NotImplementedError - # IMPLEMENTATION methods + def _get_size_udev(self): + udev.settle() + udev_info = udev.get_device(device_node=self.fs.device) + if not udev_info: + raise FSError("Failed to obtain udev information for device %s" % self.fs.device) + + fs_size = udev.device_get_format_size(udev_info) + if not fs_size: + raise FSError("Failed to obtain filesystem size for %s from udev" % self.fs.device) + + return Size(fs_size) def do_task(self): # pylint: disable=arguments-differ """ Returns the size of the filesystem. @@ -56,33 +71,51 @@ def do_task(self): # pylint: disable=arguments-differ :rtype: :class:`~.size.Size` :raises FSError: on failure """ + + # try to get size from udev + try: + size = self._get_size_udev() + except FSError as e: + log.info("Failed to obtain filesystem size for %s from udev: %s", + self.fs.device, str(e)) + else: + return size + + # fallback to filesystem tools error_msgs = self.availability_errors if error_msgs: raise FSError("\n".join(error_msgs)) + if self.fs._current_info is None: + try: + if self.fs._info.available: + self.fs._current_info = self.fs._info.do_task() + except FSError as e: + log.info("Failed to obtain info for device %s: %s", self.fs.device, e) + if self.fs._current_info is None: raise FSError("No info available for size computation.") - return self._get_size() + return self._get_size_tools() class Ext2FSSize(FSSize): - def _get_size(self): + def _get_size_tools(self): return Size(self.fs._current_info.block_size * self.fs._current_info.block_count) class NTFSSize(FSSize): - def _get_size(self): + def _get_size_tools(self): return Size(self.fs._current_info.size) class XFSSize(FSSize): - def _get_size(self): + def _get_size_tools(self): return Size(self.fs._current_info.block_size * self.fs._current_info.block_count) class FATFSSize(FSSize): - def _get_size(self): + def _get_size_tools(self): return Size(self.fs._current_info.cluster_size * self.fs._current_info.cluster_count) diff --git a/blivet/udev.py b/blivet/udev.py index 73a79d418..7c453df88 100644 --- a/blivet/udev.py +++ b/blivet/udev.py @@ -275,6 +275,16 @@ def device_get_format_version(udev_info): return udev_info.get("ID_FS_VERSION") +def device_get_format_size(udev_info): + """ Report a device's format size as reported by udev. """ + return udev_info.get("ID_FS_SIZE") + + +def device_get_format_blocksize(udev_info): + """ Report a device's format block size as reported by udev. """ + return udev_info.get("ID_FS_BLOCKSIZE") + + def device_get_uuid(udev_info): """ Get the UUID from the device's format as reported by udev.