[elbe-devel] [PATCH] Introduce generic filesystem tuning
Daniel Braunwarth
daniel at braunwarth.dev
Sun Jan 1 21:40:13 CET 2023
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>
---
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 -->
--
2.39.0
More information about the elbe-devel
mailing list