Skip to content

Commit

Permalink
Merge pull request #1163 from vojtechtrefny/3.9-devel_libblockdev-fs-…
Browse files Browse the repository at this point in the history
…plugin

Use libblockdev FS plugin for filesystem operations
  • Loading branch information
vojtechtrefny authored Nov 10, 2023
2 parents 357f6a0 + c2afd77 commit 43a3e42
Show file tree
Hide file tree
Showing 32 changed files with 477 additions and 882 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ To install these dependencies use following commands:
# dnf install python3-blockdev libblockdev-plugins-all python3-bytesize libbytesize python3-pyparted parted libselinux-python3
* On Debian and Ubuntu based distributions:

# apt-get install python3-blockdev python3-bytesize python3-parted python3-selinux gir1.2-blockdev-3.0 libblockdev-lvm3 libblockdev-btrfs3 libblockdev-swap3 libblockdev-loop3 libblockdev-crypto3 libblockdev-mpath3 libblockdev-dm3 libblockdev-mdraid3 libblockdev-nvdimm3
# apt-get install python3-blockdev python3-bytesize python3-parted python3-selinux gir1.2-blockdev-3.0 libblockdev-lvm3 libblockdev-btrfs3 libblockdev-swap3 libblockdev-loop3 libblockdev-crypto3 libblockdev-mpath3 libblockdev-dm3 libblockdev-mdraid3 libblockdev-nvdimm3 libblockdev-fs3

### Development

Expand Down
4 changes: 2 additions & 2 deletions blivet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ def log_bd_message(level, msg):
from gi.repository import GLib
from gi.repository import BlockDev as blockdev
if arch.is_s390():
_REQUESTED_PLUGIN_NAMES = set(("lvm", "btrfs", "swap", "crypto", "loop", "mdraid", "mpath", "dm", "s390", "nvdimm", "nvme"))
_REQUESTED_PLUGIN_NAMES = set(("lvm", "btrfs", "swap", "crypto", "loop", "mdraid", "mpath", "dm", "s390", "nvdimm", "nvme", "fs"))
else:
_REQUESTED_PLUGIN_NAMES = set(("lvm", "btrfs", "swap", "crypto", "loop", "mdraid", "mpath", "dm", "nvdimm", "nvme"))
_REQUESTED_PLUGIN_NAMES = set(("lvm", "btrfs", "swap", "crypto", "loop", "mdraid", "mpath", "dm", "nvdimm", "nvme", "fs"))

_requested_plugins = blockdev.plugin_specs_from_names(_REQUESTED_PLUGIN_NAMES)
try:
Expand Down
4 changes: 0 additions & 4 deletions blivet/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ def __init__(self):
self.noiswmd = False

self.gfs2 = True
self.jfs = True
self.reiserfs = True

# for this flag to take effect,
# blockdev.mpath.set_friendly_names(flags.multipath_friendly_names) must
Expand Down Expand Up @@ -112,8 +110,6 @@ def update_from_boot_cmdline(self):
self.multipath = "nompath" not in self.boot_cmdline
self.noiswmd = "noiswmd" in self.boot_cmdline
self.gfs2 = "gfs2" in self.boot_cmdline
self.jfs = "jfs" in self.boot_cmdline
self.reiserfs = "reiserfs" in self.boot_cmdline


flags = Flags()
20 changes: 8 additions & 12 deletions blivet/formats/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
import importlib
from six import add_metaclass

import gi
gi.require_version("BlockDev", "3.0")

from gi.repository import BlockDev as blockdev

from .. import udev
from ..util import get_sysfs_path_by_name
from ..util import run_program
Expand Down Expand Up @@ -560,19 +565,10 @@ def _pre_destroy(self, **kwargs):
raise DeviceFormatError("device path does not exist or is not writable")

def _destroy(self, **kwargs):
rc = 0
err = ""
try:
rc = run_program(["wipefs", "-f", "-a", self.device])
except OSError as e:
err = str(e)
else:
if rc:
err = str(rc)

if err:
msg = "error wiping old signatures from %s: %s" % (self.device, err)
raise FormatDestroyError(msg)
blockdev.fs.clean(self.device, force=True)
except blockdev.FSError as e:
raise FormatDestroyError("error wiping old signatures from %s: %s" % (self.device, str(e)))

def _post_destroy(self, **kwargs):
udev.settle()
Expand Down
84 changes: 18 additions & 66 deletions blivet/formats/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@

from parted import fileSystemType, PARTITION_BOOT

import gi
gi.require_version("BlockDev", "3.0")

from gi.repository import BlockDev as blockdev

from ..tasks import fsck
from ..tasks import fsinfo
from ..tasks import fslabeling
Expand Down Expand Up @@ -429,7 +434,7 @@ def _create(self, **kwargs):
" is unacceptable for this filesystem.",
self.uuid, self.type)
except FSError as e:
raise FormatCreateError(e, self.device)
raise FormatCreateError(e)

def _post_create(self, **kwargs):
super(FS, self)._post_create(**kwargs)
Expand Down Expand Up @@ -489,13 +494,13 @@ def check_module(self):

for module in self._modules:
try:
rc = util.run_program(["modprobe", "--dry-run", module])
except OSError as e:
log.error("Could not check kernel module availability %s: %s", module, e)
avail = blockdev.utils.have_kernel_module(module)
except blockdev.UtilsError as e:
log.error("Could not check kernel module availability %s: %s", module, str(e))
self._supported = False
return

if rc:
if not avail:
log.debug("Kernel module %s not available", module)
self._supported = False
return
Expand Down Expand Up @@ -670,6 +675,13 @@ def read_label(self):

if not self._readlabel.available:
raise FSReadLabelError("can not read label for filesystem %s" % self.type)

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)

return self._readlabel.do_task()

def write_label(self, dry_run=False):
Expand Down Expand Up @@ -1057,26 +1069,7 @@ class JFS(FS):

""" JFS filesystem """
_type = "jfs"
_modules = ["jfs"]
_labelfs = fslabeling.JFSLabeling()
_uuidfs = fsuuid.JFSUUID()
_max_size = Size("8 TiB")
_formattable = True
_linux_native = True
_dump = True
_check = True
_info_class = fsinfo.JFSInfo
_mkfs_class = fsmkfs.JFSMkfs
_size_info_class = fssize.JFSSize
_writelabel_class = fswritelabel.JFSWriteLabel
_writeuuid_class = fswriteuuid.JFSWriteUUID
_metadata_size_factor = 0.99 # jfs metadata may take 1% of space
parted_system = fileSystemType["jfs"]

@property
def supported(self):
""" Is this filesystem a supported type? """
return self.utils_available if flags.jfs else self._supported


register_device_format(JFS)
Expand All @@ -1086,27 +1079,7 @@ class ReiserFS(FS):

""" reiserfs filesystem """
_type = "reiserfs"
_labelfs = fslabeling.ReiserFSLabeling()
_uuidfs = fsuuid.ReiserFSUUID()
_modules = ["reiserfs"]
_max_size = Size("16 TiB")
_formattable = True
_linux_native = True
_dump = True
_check = True
_packages = ["reiserfs-utils"]
_info_class = fsinfo.ReiserFSInfo
_mkfs_class = fsmkfs.ReiserFSMkfs
_size_info_class = fssize.ReiserFSSize
_writelabel_class = fswritelabel.ReiserFSWriteLabel
_writeuuid_class = fswriteuuid.ReiserFSWriteUUID
_metadata_size_factor = 0.98 # reiserfs metadata may take 2% of space
parted_system = fileSystemType["reiserfs"]

@property
def supported(self):
""" Is this filesystem a supported type? """
return self.utils_available if flags.reiserfs else self._supported


register_device_format(ReiserFS)
Expand Down Expand Up @@ -1203,32 +1176,11 @@ def _destroy(self, **kwargs): # pylint: disable=unused-argument

class HFS(FS):
_type = "hfs"
_modules = ["hfs"]
_labelfs = fslabeling.HFSLabeling()
_formattable = True
_mkfs_class = fsmkfs.HFSMkfs
parted_system = fileSystemType["hfs"]


register_device_format(HFS)


class AppleBootstrapFS(HFS):
_type = "appleboot"
_name = N_("Apple Bootstrap")
_min_size = Size("768 KiB")
_max_size = Size("1 MiB")
_supported = True
_mount_class = fsmount.AppleBootstrapFSMount

@property
def supported(self):
return super(AppleBootstrapFS, self).supported and arch.is_pmac()


register_device_format(AppleBootstrapFS)


class HFSPlus(FS):
_type = "hfs+"
_modules = ["hfsplus"]
Expand Down Expand Up @@ -1486,7 +1438,7 @@ def _size_option(self, size):
This is not impossible, since a special option for mounting
is size=<percentage>%.
"""
return "size=%s" % (self._resize.size_fmt % size.convert_to(self._resize.unit))
return "size=%sm" % size.convert_to(self._resize.unit)

def _get_options(self):
# Returns the regular mount options with the special size option,
Expand Down
36 changes: 19 additions & 17 deletions blivet/formats/swap.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from ..fstab import FSTabOptions
from ..storage_log import log_method_call
from ..tasks import availability
from ..tasks import fsuuid
from . import DeviceFormat, register_device_format
from ..size import Size
from .. import udev
Expand Down Expand Up @@ -117,8 +116,13 @@ def relabels(self):
return True and self._plugin.available

def label_format_ok(self, label):
"""Returns True since no known restrictions on the label."""
return True
"""Check whether the given label is correct (16 characters or shorter)."""
try:
blockdev.swap.check_label(label)
except blockdev.SwapError:
return False
else:
return True

def write_label(self, dry_run=False):
""" Create a label for this format.
Expand Down Expand Up @@ -157,7 +161,12 @@ def write_label(self, dry_run=False):

def uuid_format_ok(self, uuid):
"""Check whether the given UUID is correct according to RFC 4122."""
return fsuuid.FSUUID._check_rfc4122_uuid(uuid)
try:
blockdev.swap.check_uuid(uuid)
except blockdev.SwapError:
return False
else:
return True

def _set_priority(self, priority):
# pylint: disable=attribute-defined-outside-init
Expand Down Expand Up @@ -231,19 +240,12 @@ def _teardown(self, **kwargs):
def _create(self, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
if self.uuid is None:
try:
blockdev.swap.mkswap(self.device, label=self.label)
except blockdev.SwapError as err:
raise SwapSpaceError(str(err))
else:
if not self.uuid_format_ok(self.uuid):
raise FSWriteUUIDError("bad UUID format for swap filesystem")
try:
blockdev.swap.mkswap(self.device, label=self.label,
extra={"-U": self.uuid})
except blockdev.SwapError as err:
raise SwapSpaceError(str(err))
if self.uuid and not self.uuid_format_ok(self.uuid):
raise FSWriteUUIDError("bad UUID format for swap filesystem")
try:
blockdev.swap.mkswap(self.device, label=self.label, uuid=self.uuid)
except blockdev.SwapError as err:
raise SwapSpaceError(str(err))


register_device_format(SwapSpace)
2 changes: 1 addition & 1 deletion blivet/populator/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .formatpopulator import FormatPopulator

from .btrfs import BTRFSFormatPopulator
from .boot import AppleBootFormatPopulator, EFIFormatPopulator, MacEFIFormatPopulator
from .boot import EFIFormatPopulator, MacEFIFormatPopulator
from .disk import DiskDevicePopulator, iScsiDevicePopulator, FCoEDevicePopulator, MDBiosRaidDevicePopulator, DASDDevicePopulator, ZFCPDevicePopulator, NVDIMMNamespaceDevicePopulator, NVMeNamespaceDevicePopulator, NVMeFabricsNamespaceDevicePopulator
from .disklabel import DiskLabelFormatPopulator
from .dm import DMDevicePopulator
Expand Down
6 changes: 0 additions & 6 deletions blivet/populator/helpers/boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,3 @@ def match(cls, data, device):
except AttributeError:
# just in case device.parted_partition has no name attr
return False


class AppleBootFormatPopulator(BootFormatPopulator):
_type_specifier = "appleboot"
_base_type_specifier = "hfs"
_bootable = True
Loading

0 comments on commit 43a3e42

Please sign in to comment.