[elbe-devel] [PATCH] Introduce generic filesystem tuning
Bastian Germann
bage at linutronix.de
Fri May 26 10:47:18 CEST 2023
Am 01.01.23 um 21:40 schrieb Daniel Braunwarth:
> This patch introduces a generic way for filesystem tuning with the new
> XML node "fs-finetuning".
>
> This new node can contain two different command variants:
>
> 1. "device-command", which is being executed directly after the
> filesystem has been created but before it is going to be mounted.
> This command variant provides a "{device}" placeholder which is
> replaced with the device containing the filesystem.
>
> 2. "path-command", which is being executed after the filesystem has been
> mounted but before it is going to be filled with its content.
> This command variant provides a "{path}" placeholder which is
> replaced with the path of the mounted filesystem.
>
> Those filesystem tuning commands shall replace the currently existing
> "tune2fs" node. For example:
>
> <fs>
> <type>ext4</type>
> <fs-finetuning>
> <device-command>tune2fs -i 0 {device}</device-command>
> </fs-finetuning>
> </fs>
>
> To be backward compatible the currently existing "tune2fs" nodes are
> automatically converted during the XML preprocessing.
>
> Another use case for those commands could be to create Btrfs subvolumes.
> For example:
>
> <fs>
> <type>btrfs</type>
> <fs-finetuning>
> <path-command>btrfs subvolume create {path}/home</path-command>
> <path-command>btrfs subvolume create {path}/var/log</path-command>
> </fs-finetuning>
> </fs>
>
> Signed-off-by: Daniel Braunwarth <daniel at braunwarth.dev>
Reviewed-by: Bastian Germann <bage at linutronix.de>
> ---
> elbepack/fstab.py | 13 +++---
> elbepack/hdimg.py | 32 +++++++++----
> elbepack/xmlpreprocess.py | 22 ++++++++-
> examples/arm64-qemu-virt.xml | 4 +-
> examples/armhf-ti-beaglebone-black.xml | 4 +-
> examples/powerpc.xml | 4 +-
> .../x86_32-pc-hdimg-minimal-grub-buster.xml | 4 +-
> ...6_32-pc-hdimg-with-include-development.xml | 4 +-
> ...86_32-pc-hdimg-with-include-production.xml | 4 +-
> examples/x86_64-pc-hdimg-gnome3.xml | 8 +++-
> .../x86_64-pc-hdimg-grub-hybrid-buster.xml | 4 +-
> examples/x86_64-pc-hdimg-grub-uefi-buster.xml | 4 +-
> schema/dbsfed.xsd | 45 ++++++++++++++++++-
> tests/simple-amd64-with-grub-uefi.xml | 4 +-
> 14 files changed, 129 insertions(+), 27 deletions(-)
>
> diff --git a/elbepack/fstab.py b/elbepack/fstab.py
> index aeff493e8..8102f3c88 100644
> --- a/elbepack/fstab.py
> +++ b/elbepack/fstab.py
> @@ -129,7 +129,14 @@ class fstabentry(hdpart):
> self.fstype = entry.text("fs/type")
> self.mkfsopt = entry.text("fs/mkfs", default="")
> self.passno = entry.text("fs/passno", default="0")
> - self.tune = entry.text("fs/tune2fs", default=None)
> +
> + self.fs_device_commands = []
> + self.fs_path_commands = []
> + for command in entry.node("fs/fs-finetuning") or []:
> + if command.tag == "device-command":
> + self.fs_device_commands.append(command.text("."))
> + elif command.tag == "path-command":
> + self.fs_path_commands.append(command.text("."))
>
> self.id = str(fsid)
>
> @@ -153,7 +160,3 @@ class fstabentry(hdpart):
> if self.fstype == "vfat":
> return "-n " + self.label
> return ""
> -
> - def tuning(self, loopdev):
> - if self.tune:
> - do(f'tune2fs {self.tune} {loopdev}')
> diff --git a/elbepack/hdimg.py b/elbepack/hdimg.py
> index deeedce2e..a10ef7804 100644
> --- a/elbepack/hdimg.py
> +++ b/elbepack/hdimg.py
> @@ -10,6 +10,8 @@
> import logging
> import os
>
> +from pathlib import Path
> +
> import parted
> import _ped
>
> @@ -357,23 +359,37 @@ def create_label(disk, part, ppart, fslabel, target, grub):
>
> try:
> do(
> - f'mkfs.{entry.fstype} {entry.mkfsopt} {entry.get_label_opt()} '
> - f'{loopdev}')
> - do(f'mount {loopdev} {os.path.join(target, "imagemnt")}')
> + f"mkfs.{entry.fstype} {entry.mkfsopt} {entry.get_label_opt()} "
> + f"{loopdev}")
> +
> + _execute_fs_commands(entry.fs_device_commands, dict(device=loopdev))
> +
> + mount_path = Path(target, "imagemnt")
> + do(f"mount {loopdev} {mount_path}")
> +
> + _execute_fs_commands(entry.fs_path_commands, dict(path=mount_path))
>
> try:
> do(
> f'cp -a "{os.path.join(target, "filesystems", entry.id)}/." '
> - f'"{os.path.join(target, "imagemnt")}/"',
> - allow_fail=True)
> + f'"{mount_path}/"',
> + allow_fail=True)
> finally:
> - do(f'umount {loopdev}')
> - entry.tuning(loopdev)
> + do(f"umount {loopdev}")
> finally:
> - do(f'losetup -d {loopdev}')
> + do(f"losetup -d {loopdev}")
>
> return ppart
>
> +def _execute_fs_commands(commands, replacements):
> + for command in commands:
> + try:
> + do(command.format(**replacements))
> + except KeyError as E:
> + logging.error('Filesystem finetuning command failed: invalid key "%s"', E)
> + except Exception as E:
> + logging.error('Filesystem finetuning command failed: %s', E)
> +
> def create_binary(disk, part, ppart, target):
>
> entry = hdpart()
> diff --git a/elbepack/xmlpreprocess.py b/elbepack/xmlpreprocess.py
> index 680e7a361..34d7d1468 100644
> --- a/elbepack/xmlpreprocess.py
> +++ b/elbepack/xmlpreprocess.py
> @@ -17,7 +17,7 @@ from urllib.request import urlopen
> from passlib.hash import sha512_crypt
>
> from lxml import etree
> -from lxml.etree import XMLParser, parse, Element
> +from lxml.etree import XMLParser, parse, Element, SubElement
>
> from elbepack.archivedir import ArchivedirError, combinearchivedir
> from elbepack.config import cfg
> @@ -77,6 +77,23 @@ def preprocess_bootstrap(xml):
>
> old_node.getparent().replace(old_node, bootstrap)
>
> +def preprocess_tune2fs(xml):
> + "Replaces all maybe existing tune2fs elements with fs-finetuning command"
> +
> + old_nodes = xml.findall(".//tune2fs")
> + for old_node in old_nodes:
> + print("[WARN] <tune2fs> is deprecated. Use <fs-finetuning> instead.")
> +
> + fs_node = old_node.getparent()
> + finetuning_node = fs_node.find("fs-finetuning")
> + if finetuning_node is None:
> + finetuning_node = SubElement(fs_node, "fs-finetuning")
> +
> + command = SubElement(finetuning_node, "device-command")
> + command.text = f"tune2fs {old_node.text} {{device}}"
> +
> + fs_node.remove(old_node)
> +
> def preprocess_iso_option(xml):
>
> src_opts = xml.find(".//src-cdrom/src-opts")
> @@ -349,6 +366,9 @@ def xmlpreprocess(fname, output, variants=None, proxy=None):
> # Replace old debootstrapvariant with debootstrap
> preprocess_bootstrap(xml)
>
> + # Replace old tune2fs with fs-finetuning command
> + preprocess_tune2fs(xml)
> +
> preprocess_iso_option(xml)
>
> preprocess_initvm_ports(xml)
> diff --git a/examples/arm64-qemu-virt.xml b/examples/arm64-qemu-virt.xml
> index efbfa21b0..ddccbfa2d 100644
> --- a/examples/arm64-qemu-virt.xml
> +++ b/examples/arm64-qemu-virt.xml
> @@ -63,7 +63,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext2</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> </fstab>
> diff --git a/examples/armhf-ti-beaglebone-black.xml b/examples/armhf-ti-beaglebone-black.xml
> index 8e59cb79d..5a10c2aad 100644
> --- a/examples/armhf-ti-beaglebone-black.xml
> +++ b/examples/armhf-ti-beaglebone-black.xml
> @@ -81,7 +81,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <fs>
> <!-- fs type and options -->
> <type>ext2</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> <bylabel>
> diff --git a/examples/powerpc.xml b/examples/powerpc.xml
> index f2b1d346f..8880e05de 100644
> --- a/examples/powerpc.xml
> +++ b/examples/powerpc.xml
> @@ -38,7 +38,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> <bydev>
> diff --git a/examples/x86_32-pc-hdimg-minimal-grub-buster.xml b/examples/x86_32-pc-hdimg-minimal-grub-buster.xml
> index 2ff012ab1..aa8f6bd5e 100644
> --- a/examples/x86_32-pc-hdimg-minimal-grub-buster.xml
> +++ b/examples/x86_32-pc-hdimg-minimal-grub-buster.xml
> @@ -37,7 +37,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> </fstab>
> diff --git a/examples/x86_32-pc-hdimg-with-include-development.xml b/examples/x86_32-pc-hdimg-with-include-development.xml
> index aa698c4bf..6a5371575 100644
> --- a/examples/x86_32-pc-hdimg-with-include-development.xml
> +++ b/examples/x86_32-pc-hdimg-with-include-development.xml
> @@ -33,7 +33,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> </fstab>
> diff --git a/examples/x86_32-pc-hdimg-with-include-production.xml b/examples/x86_32-pc-hdimg-with-include-production.xml
> index ab631ce81..c0a32f359 100644
> --- a/examples/x86_32-pc-hdimg-with-include-production.xml
> +++ b/examples/x86_32-pc-hdimg-with-include-production.xml
> @@ -33,7 +33,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> </fstab>
> diff --git a/examples/x86_64-pc-hdimg-gnome3.xml b/examples/x86_64-pc-hdimg-gnome3.xml
> index 6e035cea4..05782771c 100644
> --- a/examples/x86_64-pc-hdimg-gnome3.xml
> +++ b/examples/x86_64-pc-hdimg-gnome3.xml
> @@ -47,7 +47,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> <bylabel>
> @@ -55,7 +57,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/home</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> <bydev>
> diff --git a/examples/x86_64-pc-hdimg-grub-hybrid-buster.xml b/examples/x86_64-pc-hdimg-grub-hybrid-buster.xml
> index 6682d4696..486b78bb5 100644
> --- a/examples/x86_64-pc-hdimg-grub-hybrid-buster.xml
> +++ b/examples/x86_64-pc-hdimg-grub-hybrid-buster.xml
> @@ -74,7 +74,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> <!-- the EFI system partition needs to be mounted at /boot/efi -->
> diff --git a/examples/x86_64-pc-hdimg-grub-uefi-buster.xml b/examples/x86_64-pc-hdimg-grub-uefi-buster.xml
> index a1595a491..3dd73457f 100644
> --- a/examples/x86_64-pc-hdimg-grub-uefi-buster.xml
> +++ b/examples/x86_64-pc-hdimg-grub-uefi-buster.xml
> @@ -63,7 +63,9 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> <!-- the EFI system partition needs to be mounted at /boot/efi -->
> diff --git a/schema/dbsfed.xsd b/schema/dbsfed.xsd
> index 72bca5a3d..786ade1bb 100644
> --- a/schema/dbsfed.xsd
> +++ b/schema/dbsfed.xsd
> @@ -1587,10 +1587,10 @@ SPDX-FileCopyrightText: Linutronix GmbH
> </documentation>
> </annotation>
> </element>
> - <element name="tune2fs" type="rfs:string" minOccurs="0" maxOccurs="1">
> + <element name="fs-finetuning" type="rfs:fs-finetuning" minOccurs="0" maxOccurs="1">
> <annotation>
> <documentation>
> - options passed to the tune2fs command
> + apply the given commands to the filesystem
> </documentation>
> </annotation>
> </element>
> @@ -1719,6 +1719,47 @@ SPDX-FileCopyrightText: Linutronix GmbH
> <attribute ref="xml:base"/>
> </complexType>
>
> + <complexType name="fs-finetuning">
> + <annotation>
> + <documentation>
> + container for filesystem finetuning commands; these commands are executed directly after
> + the filesystem was created.
> + </documentation>
> + </annotation>
> + <sequence>
> + <group ref="rfs:fs-action" minOccurs="0" maxOccurs="unbounded" />
> + </sequence>
> + <attribute ref="xml:base"/>
> + </complexType>
> +
> + <group name="fs-action">
> + <annotation>
> + <documentation>
> + definition of filesystem finetuning commands
> + </documentation>
> + </annotation>
> + <choice>
> + <element name="device-command" type="rfs:string" minOccurs="0">
> + <annotation>
> + <documentation>
> + execute the defined command in /bin/sh. The command is being executed before the
> + filesystem is mounted. The placeholder {device} is pointing to the device containing the
> + filesystem.
> + </documentation>
> + </annotation>
> + </element>
> + <element name="path-command" type="rfs:string" minOccurs="0">
> + <annotation>
> + <documentation>
> + execute the defined command in /bin/sh. The command is being executed after the
> + filesystem is mounted. The placeholder {path} is pointing to the path where the
> + filesystem is mounted to.
> + </documentation>
> + </annotation>
> + </element>
> + </choice>
> + </group>
> +
> <complexType name="package">
> <annotation>
> <documentation>
> diff --git a/tests/simple-amd64-with-grub-uefi.xml b/tests/simple-amd64-with-grub-uefi.xml
> index cbe9b99d4..1464cec88 100644
> --- a/tests/simple-amd64-with-grub-uefi.xml
> +++ b/tests/simple-amd64-with-grub-uefi.xml
> @@ -52,7 +52,9 @@
> <mountpoint>/</mountpoint>
> <fs>
> <type>ext4</type>
> - <tune2fs>-i 0</tune2fs>
> + <fs-finetuning>
> + <device-command>tune2fs -i 0 {device}</device-command>
> + </fs-finetuning>
> </fs>
> </bylabel>
> <!-- the EFI system partition needs to be mounted at /boot/efi -->
More information about the elbe-devel
mailing list