Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get filesystem size from udev database #1321

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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