public inbox for cip-dev@lists.cip-project.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add data-reset to initramfs
@ 2025-04-24  9:22 Quirin Gylstorff
  2025-04-24  9:22 ` [PATCH 1/2] initramfs: add hook for data-reset Quirin Gylstorff
  2025-04-24  9:22 ` [PATCH 2/2] add data-reset hook to cip-core-initramfs Quirin Gylstorff
  0 siblings, 2 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2025-04-24  9:22 UTC (permalink / raw)
  To: cip-dev, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

This adds an initramfs hook to delete all data from the persistent
partitions.

This will reset the device identity `/etc/machine-id` and all
other information stored in the overlay.


I didn't call it factory-reset as it does not clean the encrypted
data partition. This would require:
- deleting all TPM data
- reformatting the encrypted partitions

Also it does not delete snapshots from btrfs or similar devices.


Quirin Gylstorff (2):
  initramfs: add hook for data-reset
  add data-reset hook to cip-core-initramfs

 .../cip-core-initramfs/cip-core-initramfs.bb  |  1 +
 .../files/local-bottom-complete.tmpl          | 76 +++++++++++++++++++
 .../initramfs-data-reset-hook_0.1.bb          | 36 +++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
 create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb

-- 
2.47.0



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] initramfs: add hook for data-reset
  2025-04-24  9:22 [PATCH 0/2] Add data-reset to initramfs Quirin Gylstorff
@ 2025-04-24  9:22 ` Quirin Gylstorff
  2025-04-28  6:35   ` Jan Kiszka
  2025-04-24  9:22 ` [PATCH 2/2] add data-reset hook to cip-core-initramfs Quirin Gylstorff
  1 sibling, 1 reply; 8+ messages in thread
From: Quirin Gylstorff @ 2025-04-24  9:22 UTC (permalink / raw)
  To: cip-dev, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

This allows to reset the device data by deleting
all files in the persistent partitions.

The reset occurs if a file defined by the variable
INITRAMFS_DATA_RESET_MARKER
exists in the device INITRAMFS_DATA_RESET_MARKER_DEVICE.

This feature allows to add device specific trigger to restore
the persistent file system to the first-boot state.

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 .../files/local-bottom-complete.tmpl          | 76 +++++++++++++++++++
 .../initramfs-data-reset-hook_0.1.bb          | 36 +++++++++
 2 files changed, 112 insertions(+)
 create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
 create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb

diff --git a/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl b/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
new file mode 100644
index 0000000..f02f95c
--- /dev/null
+++ b/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
@@ -0,0 +1,76 @@
+#!/bin/sh
+#
+# CIP Core, generic profile
+#
+# Copyright (c) Siemens AG, 2025
+#
+# Authors:
+#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
+#
+prereqs()
+{
+	# Make sure that this script is run last in local-top
+	# but before overlay
+	local req
+	for req in "${0%/*}"/*; do
+		script="${req##*/}"
+		if [ "$script" != "${0##*/}" ] &&
+			[ "$script" != "overlay" ] ; then
+			printf '%s\n' "$script"
+		fi
+	done
+}
+case $1 in
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /scripts/functions
+
+marker="${INITRAMFS_DATA_RESET_MARKER}"
+marker_storage_device="${INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE}"
+target_devices="${INITRAMFS_DATA_RESET_DEVICES}"
+
+storage_mnt="$(findmnt "${marker_storage_device}")"
+factory_reset=false
+tmp_mount=$(mktemp -d)
+# check for marker
+if [ -z "${storage_mnt}" ]; then
+	if ! mount -t "$(get_fstype "${marker_storage_device}")" \
+		 "${marker_storage_device}" \
+		 "${tmp_mount}"; then
+		panic "Can't mount ${marker_storage_device}!"
+	fi
+	storage_mnt="$tmp_mount"
+fi
+if [ -e "${storage_mnt}${marker}" ]; then
+	factory_reset=true
+fi
+if mountpoint -q "$tmp_mount"; then
+	umount "$tmp_mount"
+fi
+if [ "${factory_reset}" = "true" ]; then
+	log_begin_msg "Factory Reset"
+	for target in ${target_devices}; do
+		target_mnt="$(findmnt "${target}")"
+		if [ -z "$target_mnt" ]; then
+			if ! mount -t "$(get_fstype "${target}")" \
+		 		"${marker_storage_device}" \
+		 		"${tmp_mount}"; then
+				panic "Can't mount ${target}!"
+			fi
+			target_mnt="$tmp_mount"
+		fi
+
+		# delete all files in the target mount point
+		find "${target_mnt}" ! -wholename "${target_mnt}" \
+			! -name "lost+found" -exec rm -rf {} +
+
+		if mountpoint -q "$tmp_mount"; then
+			umount "$tmp_mount"
+		fi
+	done
+	log_end_msg "Factory Reset"
+fi
diff --git a/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb b/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb
new file mode 100644
index 0000000..6dfd896
--- /dev/null
+++ b/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb
@@ -0,0 +1,36 @@
+#
+# CIP Core, generic profile
+#
+# Copyright (c) Siemens AG, 2025
+#
+# Authors:
+#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+
+require recipes-initramfs/initramfs-hook/hook.inc
+SRC_URI += " \
+    file://local-bottom-complete.tmpl"
+
+DESCRIPTION = "Delete the content of the given Devices"
+
+# if this file exists execute a factory reset for the given
+# list of factory-reset targets.
+INITRAMFS_DATA_RESET_MARKER ?= "/.data-reset"
+
+# use labels as crypt setup replaces the label links if
+# an partition is encrypted
+INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE ??= "/dev/disk/by-label/var"
+
+# list of partitions by label
+INITRAMFS_DATA_RESET_DEVICES ??= "/dev/disk/by-label/var"
+
+TEMPLATE_FILES += "local-bottom-complete.tmpl"
+TEMPLATE_VARS += " INITRAMFS_DATA_RESET_MARKER \
+                   INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE \
+                   INITRAMFS_DATA_RESET_DEVICES"
+
+DEBIAN_DEPENDS .= ", coreutils, util-linux"
+
+HOOK_ADD_MODULES = "factory-reset"
+HOOK_COPY_EXECS = "mountpoint findmnt mktemp rm find"
-- 
2.47.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] add data-reset hook to cip-core-initramfs
  2025-04-24  9:22 [PATCH 0/2] Add data-reset to initramfs Quirin Gylstorff
  2025-04-24  9:22 ` [PATCH 1/2] initramfs: add hook for data-reset Quirin Gylstorff
@ 2025-04-24  9:22 ` Quirin Gylstorff
  1 sibling, 0 replies; 8+ messages in thread
From: Quirin Gylstorff @ 2025-04-24  9:22 UTC (permalink / raw)
  To: cip-dev, jan.kiszka

From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb | 1 +
 1 file changed, 1 insertion(+)

diff --git a/recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb b/recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb
index 0e4cf74..d4b1e5e 100644
--- a/recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb
+++ b/recipes-initramfs/cip-core-initramfs/cip-core-initramfs.bb
@@ -12,6 +12,7 @@
 inherit initramfs
 
 INITRAMFS_INSTALL += " \
+    initramfs-data-reset-hook \
     initramfs-overlay-hook \
     "
 
-- 
2.47.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] initramfs: add hook for data-reset
  2025-04-24  9:22 ` [PATCH 1/2] initramfs: add hook for data-reset Quirin Gylstorff
@ 2025-04-28  6:35   ` Jan Kiszka
  2025-04-28  8:23     ` Quirin Gylstorff
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Kiszka @ 2025-04-28  6:35 UTC (permalink / raw)
  To: Quirin Gylstorff, cip-dev

On 24.04.25 11:22, Quirin Gylstorff wrote:
> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> 
> This allows to reset the device data by deleting
> all files in the persistent partitions.
> 
> The reset occurs if a file defined by the variable
> INITRAMFS_DATA_RESET_MARKER
> exists in the device INITRAMFS_DATA_RESET_MARKER_DEVICE.
> 
> This feature allows to add device specific trigger to restore
> the persistent file system to the first-boot state.
> 
> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> ---
>  .../files/local-bottom-complete.tmpl          | 76 +++++++++++++++++++
>  .../initramfs-data-reset-hook_0.1.bb          | 36 +++++++++
>  2 files changed, 112 insertions(+)
>  create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
>  create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb
> 
> diff --git a/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl b/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
> new file mode 100644
> index 0000000..f02f95c
> --- /dev/null
> +++ b/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
> @@ -0,0 +1,76 @@
> +#!/bin/sh
> +#
> +# CIP Core, generic profile
> +#
> +# Copyright (c) Siemens AG, 2025
> +#
> +# Authors:
> +#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
> +#
> +prereqs()
> +{
> +	# Make sure that this script is run last in local-top

But it is called "local-bottom-complete"...

> +	# but before overlay
> +	local req
> +	for req in "${0%/*}"/*; do
> +		script="${req##*/}"
> +		if [ "$script" != "${0##*/}" ] &&
> +			[ "$script" != "overlay" ] ; then
> +			printf '%s\n' "$script"
> +		fi

Will create undefined dependencies between this and the crypt hook.
Please sort that out.

> +	done
> +}
> +case $1 in
> +prereqs)
> +	prereqs
> +	exit 0
> +	;;
> +esac
> +
> +. /scripts/functions
> +
> +marker="${INITRAMFS_DATA_RESET_MARKER}"
> +marker_storage_device="${INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE}"
> +target_devices="${INITRAMFS_DATA_RESET_DEVICES}"
> +
> +storage_mnt="$(findmnt "${marker_storage_device}")"
> +factory_reset=false

I thought you didn't want to call it "factory reset"?

> +tmp_mount=$(mktemp -d)
> +# check for marker
> +if [ -z "${storage_mnt}" ]; then
> +	if ! mount -t "$(get_fstype "${marker_storage_device}")" \
> +		 "${marker_storage_device}" \
> +		 "${tmp_mount}"; then
> +		panic "Can't mount ${marker_storage_device}!"
> +	fi
> +	storage_mnt="$tmp_mount"
> +fi
> +if [ -e "${storage_mnt}${marker}" ]; then
> +	factory_reset=true
> +fi
> +if mountpoint -q "$tmp_mount"; then
> +	umount "$tmp_mount"
> +fi
> +if [ "${factory_reset}" = "true" ]; then
> +	log_begin_msg "Factory Reset"
> +	for target in ${target_devices}; do
> +		target_mnt="$(findmnt "${target}")"
> +		if [ -z "$target_mnt" ]; then
> +			if ! mount -t "$(get_fstype "${target}")" \
> +		 		"${marker_storage_device}" \
> +		 		"${tmp_mount}"; then
> +				panic "Can't mount ${target}!"
> +			fi
> +			target_mnt="$tmp_mount"
> +		fi
> +
> +		# delete all files in the target mount point
> +		find "${target_mnt}" ! -wholename "${target_mnt}" \
> +			! -name "lost+found" -exec rm -rf {} +

rm --one-file-system

But wouldn't reformatting be simpler?

> +
> +		if mountpoint -q "$tmp_mount"; then
> +			umount "$tmp_mount"
> +		fi
> +	done
> +	log_end_msg "Factory Reset"
> +fi
> diff --git a/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb b/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb
> new file mode 100644
> index 0000000..6dfd896
> --- /dev/null
> +++ b/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb
> @@ -0,0 +1,36 @@
> +#
> +# CIP Core, generic profile
> +#
> +# Copyright (c) Siemens AG, 2025
> +#
> +# Authors:
> +#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
> +#
> +# SPDX-License-Identifier: MIT
> +
> +require recipes-initramfs/initramfs-hook/hook.inc
> +SRC_URI += " \
> +    file://local-bottom-complete.tmpl"
> +
> +DESCRIPTION = "Delete the content of the given Devices"
> +
> +# if this file exists execute a factory reset for the given
> +# list of factory-reset targets.
> +INITRAMFS_DATA_RESET_MARKER ?= "/.data-reset"

Hmm, not really a working default if you have a read-only rootfs, no?

> +
> +# use labels as crypt setup replaces the label links if
> +# an partition is encrypted
> +INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE ??= "/dev/disk/by-label/var"
> +
> +# list of partitions by label
> +INITRAMFS_DATA_RESET_DEVICES ??= "/dev/disk/by-label/var"
> +
> +TEMPLATE_FILES += "local-bottom-complete.tmpl"
> +TEMPLATE_VARS += " INITRAMFS_DATA_RESET_MARKER \
> +                   INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE \
> +                   INITRAMFS_DATA_RESET_DEVICES"
> +
> +DEBIAN_DEPENDS .= ", coreutils, util-linux"
> +
> +HOOK_ADD_MODULES = "factory-reset"

What's that module?

> +HOOK_COPY_EXECS = "mountpoint findmnt mktemp rm find"

Should we already prepare alternative reset triggers by sticking the
file-based variant here into some callback?

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] initramfs: add hook for data-reset
  2025-04-28  6:35   ` Jan Kiszka
@ 2025-04-28  8:23     ` Quirin Gylstorff
  2025-04-28  9:03       ` Jan Kiszka
  0 siblings, 1 reply; 8+ messages in thread
From: Quirin Gylstorff @ 2025-04-28  8:23 UTC (permalink / raw)
  To: Jan Kiszka, cip-dev



On 4/28/25 08:35, Jan Kiszka wrote:
> On 24.04.25 11:22, Quirin Gylstorff wrote:
>> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>
>> This allows to reset the device data by deleting
>> all files in the persistent partitions.
>>
>> The reset occurs if a file defined by the variable
>> INITRAMFS_DATA_RESET_MARKER
>> exists in the device INITRAMFS_DATA_RESET_MARKER_DEVICE.
>>
>> This feature allows to add device specific trigger to restore
>> the persistent file system to the first-boot state.
>>
>> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>> ---
>>   .../files/local-bottom-complete.tmpl          | 76 +++++++++++++++++++
>>   .../initramfs-data-reset-hook_0.1.bb          | 36 +++++++++
>>   2 files changed, 112 insertions(+)
>>   create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
>>   create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb
>>
>> diff --git a/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl b/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
>> new file mode 100644
>> index 0000000..f02f95c
>> --- /dev/null
>> +++ b/recipes-initramfs/initramfs-factory-reset-hook/files/local-bottom-complete.tmpl
>> @@ -0,0 +1,76 @@
>> +#!/bin/sh
>> +#
>> +# CIP Core, generic profile
>> +#
>> +# Copyright (c) Siemens AG, 2025
>> +#
>> +# Authors:
>> +#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
>> +#
>> +prereqs()
>> +{
>> +	# Make sure that this script is run last in local-top
> 
> But it is called "local-bottom-complete"...
> 
>> +	# but before overlay
>> +	local req
>> +	for req in "${0%/*}"/*; do
>> +		script="${req##*/}"
>> +		if [ "$script" != "${0##*/}" ] &&
>> +			[ "$script" != "overlay" ] ; then
>> +			printf '%s\n' "$script"
>> +		fi
> 
> Will create undefined dependencies between this and the crypt hook.
> Please sort that out.

I will move this before the crypt hook for now.
  >> +	done
>> +}
>> +case $1 in
>> +prereqs)
>> +	prereqs
>> +	exit 0
>> +	;;
>> +esac
>> +
>> +. /scripts/functions
>> +
>> +marker="${INITRAMFS_DATA_RESET_MARKER}"
>> +marker_storage_device="${INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE}"
>> +target_devices="${INITRAMFS_DATA_RESET_DEVICES}"
>> +
>> +storage_mnt="$(findmnt "${marker_storage_device}")"
>> +factory_reset=false
> 
> I thought you didn't want to call it "factory reset"?
As the hook does not to a complete factory reset ( the disk encryption 
stays) I used data reset for now. If we add formatting a throw a way
  the disk keys I can rename it.


> 
>> +tmp_mount=$(mktemp -d)
>> +# check for marker
>> +if [ -z "${storage_mnt}" ]; then
>> +	if ! mount -t "$(get_fstype "${marker_storage_device}")" \
>> +		 "${marker_storage_device}" \
>> +		 "${tmp_mount}"; then
>> +		panic "Can't mount ${marker_storage_device}!"
>> +	fi
>> +	storage_mnt="$tmp_mount"
>> +fi
>> +if [ -e "${storage_mnt}${marker}" ]; then
>> +	factory_reset=true
>> +fi
>> +if mountpoint -q "$tmp_mount"; then
>> +	umount "$tmp_mount"
>> +fi
>> +if [ "${factory_reset}" = "true" ]; then
>> +	log_begin_msg "Factory Reset"
>> +	for target in ${target_devices}; do
>> +		target_mnt="$(findmnt "${target}")"
>> +		if [ -z "$target_mnt" ]; then
>> +			if ! mount -t "$(get_fstype "${target}")" \
>> +		 		"${marker_storage_device}" \
>> +		 		"${tmp_mount}"; then
>> +				panic "Can't mount ${target}!"
>> +			fi
>> +			target_mnt="$tmp_mount"
>> +		fi
>> +
>> +		# delete all files in the target mount point
>> +		find "${target_mnt}" ! -wholename "${target_mnt}" \
>> +			! -name "lost+found" -exec rm -rf {} +
> 
> rm --one-file-system
> 
> But wouldn't reformatting be simpler?
> 
That is the question - My first thought was reformatting but then we 
lose the information from snapshot based file systems (e.g. btrfs).


>> +
>> +		if mountpoint -q "$tmp_mount"; then
>> +			umount "$tmp_mount"
>> +		fi
>> +	done
>> +	log_end_msg "Factory Reset"
>> +fi
>> diff --git a/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb b/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb
>> new file mode 100644
>> index 0000000..6dfd896
>> --- /dev/null
>> +++ b/recipes-initramfs/initramfs-factory-reset-hook/initramfs-data-reset-hook_0.1.bb
>> @@ -0,0 +1,36 @@
>> +#
>> +# CIP Core, generic profile
>> +#
>> +# Copyright (c) Siemens AG, 2025
>> +#
>> +# Authors:
>> +#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
>> +#
>> +# SPDX-License-Identifier: MIT
>> +
>> +require recipes-initramfs/initramfs-hook/hook.inc
>> +SRC_URI += " \
>> +    file://local-bottom-complete.tmpl"
>> +
>> +DESCRIPTION = "Delete the content of the given Devices"
>> +
>> +# if this file exists execute a factory reset for the given
>> +# list of factory-reset targets.
>> +INITRAMFS_DATA_RESET_MARKER ?= "/.data-reset"
> 
> Hmm, not really a working default if you have a read-only rootfs, no?
> 
>> +
>> +# use labels as crypt setup replaces the label links if
>> +# an partition is encrypted
>> +INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE ??= "/dev/disk/by-label/var"
>> +
>> +# list of partitions by label
>> +INITRAMFS_DATA_RESET_DEVICES ??= "/dev/disk/by-label/var"
>> +
>> +TEMPLATE_FILES += "local-bottom-complete.tmpl"
>> +TEMPLATE_VARS += " INITRAMFS_DATA_RESET_MARKER \
>> +                   INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE \
>> +                   INITRAMFS_DATA_RESET_DEVICES"
>> +
>> +DEBIAN_DEPENDS .= ", coreutils, util-linux"
>> +
>> +HOOK_ADD_MODULES = "factory-reset"
> 
> What's that module?
> 
>> +HOOK_COPY_EXECS = "mountpoint findmnt mktemp rm find"
> 
> Should we already prepare alternative reset triggers by sticking the
> file-based variant here into some callback?

We could do that.
Qurin
> 
> Jan
> 



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] initramfs: add hook for data-reset
  2025-04-28  8:23     ` Quirin Gylstorff
@ 2025-04-28  9:03       ` Jan Kiszka
  2025-04-29 12:30         ` Quirin Gylstorff
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Kiszka @ 2025-04-28  9:03 UTC (permalink / raw)
  To: Quirin Gylstorff, cip-dev

On 28.04.25 10:23, Quirin Gylstorff wrote:
> 
> 
> On 4/28/25 08:35, Jan Kiszka wrote:
>> On 24.04.25 11:22, Quirin Gylstorff wrote:
>>> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>>
>>> This allows to reset the device data by deleting
>>> all files in the persistent partitions.
>>>
>>> The reset occurs if a file defined by the variable
>>> INITRAMFS_DATA_RESET_MARKER
>>> exists in the device INITRAMFS_DATA_RESET_MARKER_DEVICE.
>>>
>>> This feature allows to add device specific trigger to restore
>>> the persistent file system to the first-boot state.
>>>
>>> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>> ---
>>>   .../files/local-bottom-complete.tmpl          | 76 +++++++++++++++++++
>>>   .../initramfs-data-reset-hook_0.1.bb          | 36 +++++++++
>>>   2 files changed, 112 insertions(+)
>>>   create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/
>>> files/local-bottom-complete.tmpl
>>>   create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/
>>> initramfs-data-reset-hook_0.1.bb
>>>
>>> diff --git a/recipes-initramfs/initramfs-factory-reset-hook/files/
>>> local-bottom-complete.tmpl b/recipes-initramfs/initramfs-factory-
>>> reset-hook/files/local-bottom-complete.tmpl
>>> new file mode 100644
>>> index 0000000..f02f95c
>>> --- /dev/null
>>> +++ b/recipes-initramfs/initramfs-factory-reset-hook/files/local-
>>> bottom-complete.tmpl
>>> @@ -0,0 +1,76 @@
>>> +#!/bin/sh
>>> +#
>>> +# CIP Core, generic profile
>>> +#
>>> +# Copyright (c) Siemens AG, 2025
>>> +#
>>> +# Authors:
>>> +#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>> +#
>>> +prereqs()
>>> +{
>>> +    # Make sure that this script is run last in local-top
>>
>> But it is called "local-bottom-complete"...
>>
>>> +    # but before overlay
>>> +    local req
>>> +    for req in "${0%/*}"/*; do
>>> +        script="${req##*/}"
>>> +        if [ "$script" != "${0##*/}" ] &&
>>> +            [ "$script" != "overlay" ] ; then
>>> +            printf '%s\n' "$script"
>>> +        fi
>>
>> Will create undefined dependencies between this and the crypt hook.
>> Please sort that out.
> 
> I will move this before the crypt hook for now.

Don't you need crypt to run first to unlock the data partition?

>  >> +    done
>>> +}
>>> +case $1 in
>>> +prereqs)
>>> +    prereqs
>>> +    exit 0
>>> +    ;;
>>> +esac
>>> +
>>> +. /scripts/functions
>>> +
>>> +marker="${INITRAMFS_DATA_RESET_MARKER}"
>>> +marker_storage_device="${INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE}"
>>> +target_devices="${INITRAMFS_DATA_RESET_DEVICES}"
>>> +
>>> +storage_mnt="$(findmnt "${marker_storage_device}")"
>>> +factory_reset=false
>>
>> I thought you didn't want to call it "factory reset"?
> As the hook does not to a complete factory reset ( the disk encryption
> stays) I used data reset for now. If we add formatting a throw a way
>  the disk keys I can rename it.
> 
> 
>>
>>> +tmp_mount=$(mktemp -d)
>>> +# check for marker
>>> +if [ -z "${storage_mnt}" ]; then
>>> +    if ! mount -t "$(get_fstype "${marker_storage_device}")" \
>>> +         "${marker_storage_device}" \
>>> +         "${tmp_mount}"; then
>>> +        panic "Can't mount ${marker_storage_device}!"
>>> +    fi
>>> +    storage_mnt="$tmp_mount"
>>> +fi
>>> +if [ -e "${storage_mnt}${marker}" ]; then
>>> +    factory_reset=true
>>> +fi
>>> +if mountpoint -q "$tmp_mount"; then
>>> +    umount "$tmp_mount"
>>> +fi
>>> +if [ "${factory_reset}" = "true" ]; then
>>> +    log_begin_msg "Factory Reset"
>>> +    for target in ${target_devices}; do
>>> +        target_mnt="$(findmnt "${target}")"
>>> +        if [ -z "$target_mnt" ]; then
>>> +            if ! mount -t "$(get_fstype "${target}")" \
>>> +                 "${marker_storage_device}" \
>>> +                 "${tmp_mount}"; then
>>> +                panic "Can't mount ${target}!"
>>> +            fi
>>> +            target_mnt="$tmp_mount"
>>> +        fi
>>> +
>>> +        # delete all files in the target mount point
>>> +        find "${target_mnt}" ! -wholename "${target_mnt}" \
>>> +            ! -name "lost+found" -exec rm -rf {} +
>>
>> rm --one-file-system
>>
>> But wouldn't reformatting be simpler?
>>
> That is the question - My first thought was reformatting but then we
> lose the information from snapshot based file systems (e.g. btrfs).
> 

Which information? Aren't snapshot considered data here as well - which
we want to reset?

For a future solution that uses a/b btrfs plus some factory reset
snapshot state, this logic here will surely need adjustments. Or we
won't use the hook but rather embed related logic into some a/b data
partition hook.

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] initramfs: add hook for data-reset
  2025-04-28  9:03       ` Jan Kiszka
@ 2025-04-29 12:30         ` Quirin Gylstorff
  2025-04-30  5:11           ` Jan Kiszka
  0 siblings, 1 reply; 8+ messages in thread
From: Quirin Gylstorff @ 2025-04-29 12:30 UTC (permalink / raw)
  To: Jan Kiszka, cip-dev



On 4/28/25 11:03, Jan Kiszka wrote:
> On 28.04.25 10:23, Quirin Gylstorff wrote:
>>
>>
>> On 4/28/25 08:35, Jan Kiszka wrote:
>>> On 24.04.25 11:22, Quirin Gylstorff wrote:
>>>> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>>>
>>>> This allows to reset the device data by deleting
>>>> all files in the persistent partitions.
>>>>
>>>> The reset occurs if a file defined by the variable
>>>> INITRAMFS_DATA_RESET_MARKER
>>>> exists in the device INITRAMFS_DATA_RESET_MARKER_DEVICE.
>>>>
>>>> This feature allows to add device specific trigger to restore
>>>> the persistent file system to the first-boot state.
>>>>
>>>> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>>> ---
>>>>    .../files/local-bottom-complete.tmpl          | 76 +++++++++++++++++++
>>>>    .../initramfs-data-reset-hook_0.1.bb          | 36 +++++++++
>>>>    2 files changed, 112 insertions(+)
>>>>    create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/
>>>> files/local-bottom-complete.tmpl
>>>>    create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/
>>>> initramfs-data-reset-hook_0.1.bb
>>>>
>>>> diff --git a/recipes-initramfs/initramfs-factory-reset-hook/files/
>>>> local-bottom-complete.tmpl b/recipes-initramfs/initramfs-factory-
>>>> reset-hook/files/local-bottom-complete.tmpl
>>>> new file mode 100644
>>>> index 0000000..f02f95c
>>>> --- /dev/null
>>>> +++ b/recipes-initramfs/initramfs-factory-reset-hook/files/local-
>>>> bottom-complete.tmpl
>>>> @@ -0,0 +1,76 @@
>>>> +#!/bin/sh
>>>> +#
>>>> +# CIP Core, generic profile
>>>> +#
>>>> +# Copyright (c) Siemens AG, 2025
>>>> +#
>>>> +# Authors:
>>>> +#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>>> +#
>>>> +prereqs()
>>>> +{
>>>> +    # Make sure that this script is run last in local-top
>>>
>>> But it is called "local-bottom-complete"...
>>>
>>>> +    # but before overlay
>>>> +    local req
>>>> +    for req in "${0%/*}"/*; do
>>>> +        script="${req##*/}"
>>>> +        if [ "$script" != "${0##*/}" ] &&
>>>> +            [ "$script" != "overlay" ] ; then
>>>> +            printf '%s\n' "$script"
>>>> +        fi
>>>
>>> Will create undefined dependencies between this and the crypt hook.
>>> Please sort that out.
>>
>> I will move this before the crypt hook for now.
> 
> Don't you need crypt to run first to unlock the data partition?
This hook runs in local-bottom, unlock runs in local-top. So the 
partitions are already unlocked as the trigger is stored in the `/var/` 
partition. If we move the trigger file to a boot partition or the efi 
partition we could to the factory reset also for encrypted partition
and then move it to local-top.

Quirin
> 
>>   >> +    done
>>>> +}
>>>> +case $1 in
>>>> +prereqs)
>>>> +    prereqs
>>>> +    exit 0
>>>> +    ;;
>>>> +esac
>>>> +
>>>> +. /scripts/functions
>>>> +
>>>> +marker="${INITRAMFS_DATA_RESET_MARKER}"
>>>> +marker_storage_device="${INITRAMFS_DATA_RESET_MARKER_STORAGE_DEVICE}"
>>>> +target_devices="${INITRAMFS_DATA_RESET_DEVICES}"
>>>> +
>>>> +storage_mnt="$(findmnt "${marker_storage_device}")"
>>>> +factory_reset=false
>>>
>>> I thought you didn't want to call it "factory reset"?
>> As the hook does not to a complete factory reset ( the disk encryption
>> stays) I used data reset for now. If we add formatting a throw a way
>>   the disk keys I can rename it.
>>
>>
>>>
>>>> +tmp_mount=$(mktemp -d)
>>>> +# check for marker
>>>> +if [ -z "${storage_mnt}" ]; then
>>>> +    if ! mount -t "$(get_fstype "${marker_storage_device}")" \
>>>> +         "${marker_storage_device}" \
>>>> +         "${tmp_mount}"; then
>>>> +        panic "Can't mount ${marker_storage_device}!"
>>>> +    fi
>>>> +    storage_mnt="$tmp_mount"
>>>> +fi
>>>> +if [ -e "${storage_mnt}${marker}" ]; then
>>>> +    factory_reset=true
>>>> +fi
>>>> +if mountpoint -q "$tmp_mount"; then
>>>> +    umount "$tmp_mount"
>>>> +fi
>>>> +if [ "${factory_reset}" = "true" ]; then
>>>> +    log_begin_msg "Factory Reset"
>>>> +    for target in ${target_devices}; do
>>>> +        target_mnt="$(findmnt "${target}")"
>>>> +        if [ -z "$target_mnt" ]; then
>>>> +            if ! mount -t "$(get_fstype "${target}")" \
>>>> +                 "${marker_storage_device}" \
>>>> +                 "${tmp_mount}"; then
>>>> +                panic "Can't mount ${target}!"
>>>> +            fi
>>>> +            target_mnt="$tmp_mount"
>>>> +        fi
>>>> +
>>>> +        # delete all files in the target mount point
>>>> +        find "${target_mnt}" ! -wholename "${target_mnt}" \
>>>> +            ! -name "lost+found" -exec rm -rf {} +
>>>
>>> rm --one-file-system
>>>
>>> But wouldn't reformatting be simpler?
>>>
>> That is the question - My first thought was reformatting but then we
>> lose the information from snapshot based file systems (e.g. btrfs).
>>
> 
> Which information? Aren't snapshot considered data here as well - which
> we want to reset?
> 
> For a future solution that uses a/b btrfs plus some factory reset
> snapshot state, this logic here will surely need adjustments. Or we
> won't use the hook but rather embed related logic into some a/b data
> partition hook.

Currently I would like to have the factory-reset related logic in one place.

Quirin

> 
> Jan
> 



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] initramfs: add hook for data-reset
  2025-04-29 12:30         ` Quirin Gylstorff
@ 2025-04-30  5:11           ` Jan Kiszka
  0 siblings, 0 replies; 8+ messages in thread
From: Jan Kiszka @ 2025-04-30  5:11 UTC (permalink / raw)
  To: Quirin Gylstorff, cip-dev

On 29.04.25 14:30, Quirin Gylstorff wrote:
> 
> 
> On 4/28/25 11:03, Jan Kiszka wrote:
>> On 28.04.25 10:23, Quirin Gylstorff wrote:
>>>
>>>
>>> On 4/28/25 08:35, Jan Kiszka wrote:
>>>> On 24.04.25 11:22, Quirin Gylstorff wrote:
>>>>> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>>>>
>>>>> This allows to reset the device data by deleting
>>>>> all files in the persistent partitions.
>>>>>
>>>>> The reset occurs if a file defined by the variable
>>>>> INITRAMFS_DATA_RESET_MARKER
>>>>> exists in the device INITRAMFS_DATA_RESET_MARKER_DEVICE.
>>>>>
>>>>> This feature allows to add device specific trigger to restore
>>>>> the persistent file system to the first-boot state.
>>>>>
>>>>> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>>>> ---
>>>>>    .../files/local-bottom-complete.tmpl          | 76 +++++++++++++
>>>>> ++++++
>>>>>    .../initramfs-data-reset-hook_0.1.bb          | 36 +++++++++
>>>>>    2 files changed, 112 insertions(+)
>>>>>    create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/
>>>>> files/local-bottom-complete.tmpl
>>>>>    create mode 100644 recipes-initramfs/initramfs-factory-reset-hook/
>>>>> initramfs-data-reset-hook_0.1.bb
>>>>>
>>>>> diff --git a/recipes-initramfs/initramfs-factory-reset-hook/files/
>>>>> local-bottom-complete.tmpl b/recipes-initramfs/initramfs-factory-
>>>>> reset-hook/files/local-bottom-complete.tmpl
>>>>> new file mode 100644
>>>>> index 0000000..f02f95c
>>>>> --- /dev/null
>>>>> +++ b/recipes-initramfs/initramfs-factory-reset-hook/files/local-
>>>>> bottom-complete.tmpl
>>>>> @@ -0,0 +1,76 @@
>>>>> +#!/bin/sh
>>>>> +#
>>>>> +# CIP Core, generic profile
>>>>> +#
>>>>> +# Copyright (c) Siemens AG, 2025
>>>>> +#
>>>>> +# Authors:
>>>>> +#  Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>>>> +#
>>>>> +prereqs()
>>>>> +{
>>>>> +    # Make sure that this script is run last in local-top
>>>>
>>>> But it is called "local-bottom-complete"...
>>>>
>>>>> +    # but before overlay
>>>>> +    local req
>>>>> +    for req in "${0%/*}"/*; do
>>>>> +        script="${req##*/}"
>>>>> +        if [ "$script" != "${0##*/}" ] &&
>>>>> +            [ "$script" != "overlay" ] ; then
>>>>> +            printf '%s\n' "$script"
>>>>> +        fi
>>>>
>>>> Will create undefined dependencies between this and the crypt hook.
>>>> Please sort that out.
>>>
>>> I will move this before the crypt hook for now.
>>
>> Don't you need crypt to run first to unlock the data partition?
> This hook runs in local-bottom, unlock runs in local-top. So the
> partitions are already unlocked as the trigger is stored in the `/var/`
> partition. If we move the trigger file to a boot partition or the efi
> partition we could to the factory reset also for encrypted partition
> and then move it to local-top.

The crypt hook has both types of scripts. Unlocking indeed happens in
local-top, but you still need to sync its local-bottom with this one here.

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-04-30  5:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-24  9:22 [PATCH 0/2] Add data-reset to initramfs Quirin Gylstorff
2025-04-24  9:22 ` [PATCH 1/2] initramfs: add hook for data-reset Quirin Gylstorff
2025-04-28  6:35   ` Jan Kiszka
2025-04-28  8:23     ` Quirin Gylstorff
2025-04-28  9:03       ` Jan Kiszka
2025-04-29 12:30         ` Quirin Gylstorff
2025-04-30  5:11           ` Jan Kiszka
2025-04-24  9:22 ` [PATCH 2/2] add data-reset hook to cip-core-initramfs Quirin Gylstorff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox