Skip to content

Commit

Permalink
Get filesystem size from udev database
Browse files Browse the repository at this point in the history
We can now get filesystem size for all filesystems supported by
us directly from udev, no need to run the filesystem specific
tools.
  • Loading branch information
vojtechtrefny committed Nov 28, 2024
1 parent 7f15753 commit 21c5dfe
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 13 deletions.
7 changes: 1 addition & 6 deletions blivet/formats/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
47 changes: 40 additions & 7 deletions blivet/tasks/fssize.py
Original file line number Diff line number Diff line change
Expand Up @@ -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. """
Expand All @@ -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.
Expand All @@ -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)


Expand Down
10 changes: 10 additions & 0 deletions blivet/udev.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 21c5dfe

Please sign in to comment.