[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