diff mbox series

overlayfs-etc: take read-only-rootfs into account

Message ID 391a7b90f3cb6a7b276904b69a2251bf0d3849c9.1707376966.git.baruch@tkos.co.il
State New
Headers show
Series overlayfs-etc: take read-only-rootfs into account | expand

Commit Message

Baruch Siach Feb. 8, 2024, 7:22 a.m. UTC
Don't remount rootfs read-write when read-only-rootfs feature is
enabled. Assume that all mount points are in place for the read-only
case.

Cc: Vyacheslav Yurkov <uvv.mail@gmail.com>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 meta/classes-recipe/overlayfs-etc.bbclass |  4 +++-
 meta/files/overlayfs-etc-preinit.sh.in    | 16 +++++++++-------
 2 files changed, 12 insertions(+), 8 deletions(-)

Comments

Vyacheslav Yurkov Feb. 8, 2024, 8:21 p.m. UTC | #1
On 08.02.2024 08:22, Baruch Siach wrote:
> Don't remount rootfs read-write when read-only-rootfs feature is
> enabled. Assume that all mount points are in place for the read-only
> case.
>
> Cc: Vyacheslav Yurkov <uvv.mail@gmail.com>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> ---
>   meta/classes-recipe/overlayfs-etc.bbclass |  4 +++-
>   meta/files/overlayfs-etc-preinit.sh.in    | 16 +++++++++-------
>   2 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/meta/classes-recipe/overlayfs-etc.bbclass b/meta/classes-recipe/overlayfs-etc.bbclass
> index 0c7834d01f43..e695ebdcf843 100644
> --- a/meta/classes-recipe/overlayfs-etc.bbclass
> +++ b/meta/classes-recipe/overlayfs-etc.bbclass
> @@ -69,7 +69,9 @@ python create_overlayfs_etc_preinit() {
>           'OVERLAYFS_ETC_FSTYPE': overlayEtcFsType,
>           'OVERLAYFS_ETC_DEVICE': overlayEtcDevice,
>           'SBIN_INIT_NAME': initBaseName + origInitNameSuffix if useOrigInit else initBaseName,
> -        'OVERLAYFS_ETC_EXPOSE_LOWER': "true" if exposeLower else "false"
> +        'OVERLAYFS_ETC_EXPOSE_LOWER': "true" if exposeLower else "false",
> +        'READ_ONLY_ROOTFS': bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
> +                                              "true", "false", d)
>       }
>   
>       if useOrigInit:
> diff --git a/meta/files/overlayfs-etc-preinit.sh.in b/meta/files/overlayfs-etc-preinit.sh.in
> index 8db076f4ba65..79cecf8ac97d 100644
> --- a/meta/files/overlayfs-etc-preinit.sh.in
> +++ b/meta/files/overlayfs-etc-preinit.sh.in
> @@ -3,12 +3,15 @@
>   echo "PREINIT: Start"
>   
>   PATH=/sbin:/bin:/usr/sbin:/usr/bin
> -mount -o remount,rw /
> -
> -mkdir -p /proc
> -mkdir -p /sys
> -mkdir -p /run
> -mkdir -p /var/run
> +if ! {READ_ONLY_ROOTFS}; then
> +    mount -o remount,rw /
> +
> +    mkdir -p /proc
> +    mkdir -p /sys
> +    mkdir -p /run
> +    mkdir -p /var/run
> +    mkdir -p {OVERLAYFS_ETC_MOUNT_POINT}
> +fi

I don't think this would be a correct approach. You probably should only 
remount to ro after all mount points are created.

With this patch 
overlayfs.OverlayFSEtcRunTimeTests.test_sbin_init_preinit fails:

2024-02-08 21:12:40,616 - oe-selftest - INFO - Traceback (most recent 
call last):
   File 
"/home/uvv/projects/upstream/poky/meta/lib/oeqa/core/decorator/__init__.py", 
line 35, in wrapped_f
     return func(*args, **kwargs)
   File 
"/home/uvv/projects/upstream/poky/meta/lib/oeqa/selftest/cases/overlayfs.py", 
line 370, in test_sbin_init_preinit
     self.run_sbin_init(False)
   File 
"/home/uvv/projects/upstream/poky/meta/lib/oeqa/selftest/cases/overlayfs.py", 
line 399, in run_sbin_init
     self.assertTrue("/data" in output, msg=output)
AssertionError: False is not true : /dev/sda2 on / type ext4 (ro,relatime)

The test is not really explicit, but it looks like overlay is not 
mounted. We could also add a generic test to search for "PREINIT" 
done/failed.

>   mount -t proc proc /proc
>   mount -t sysfs sysfs /sys
> @@ -20,7 +23,6 @@ UPPER_DIR=$BASE_OVERLAY_ETC_DIR/upper
>   WORK_DIR=$BASE_OVERLAY_ETC_DIR/work
>   LOWER_DIR=$BASE_OVERLAY_ETC_DIR/lower
>   
> -mkdir -p {OVERLAYFS_ETC_MOUNT_POINT}
>   if mount -n -t {OVERLAYFS_ETC_FSTYPE} \
>       -o {OVERLAYFS_ETC_MOUNT_OPTIONS} \
>       {OVERLAYFS_ETC_DEVICE} {OVERLAYFS_ETC_MOUNT_POINT}

Thanks,
Slava
Baruch Siach Feb. 11, 2024, 1:23 p.m. UTC | #2
Hi Slava,

On Thu, Feb 08 2024, Vyacheslav Yurkov wrote:
> On 08.02.2024 08:22, Baruch Siach wrote:
>> Don't remount rootfs read-write when read-only-rootfs feature is
>> enabled. Assume that all mount points are in place for the read-only
>> case.
>>
>> Cc: Vyacheslav Yurkov <uvv.mail@gmail.com>
>> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
>> ---
>>   meta/classes-recipe/overlayfs-etc.bbclass |  4 +++-
>>   meta/files/overlayfs-etc-preinit.sh.in    | 16 +++++++++-------
>>   2 files changed, 12 insertions(+), 8 deletions(-)
>>
>> diff --git a/meta/classes-recipe/overlayfs-etc.bbclass b/meta/classes-recipe/overlayfs-etc.bbclass
>> index 0c7834d01f43..e695ebdcf843 100644
>> --- a/meta/classes-recipe/overlayfs-etc.bbclass
>> +++ b/meta/classes-recipe/overlayfs-etc.bbclass
>> @@ -69,7 +69,9 @@ python create_overlayfs_etc_preinit() {
>>           'OVERLAYFS_ETC_FSTYPE': overlayEtcFsType,
>>           'OVERLAYFS_ETC_DEVICE': overlayEtcDevice,
>>           'SBIN_INIT_NAME': initBaseName + origInitNameSuffix if useOrigInit else initBaseName,
>> -        'OVERLAYFS_ETC_EXPOSE_LOWER': "true" if exposeLower else "false"
>> +        'OVERLAYFS_ETC_EXPOSE_LOWER': "true" if exposeLower else "false",
>> +        'READ_ONLY_ROOTFS': bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
>> +                                              "true", "false", d)
>>       }
>>         if useOrigInit:
>> diff --git a/meta/files/overlayfs-etc-preinit.sh.in b/meta/files/overlayfs-etc-preinit.sh.in
>> index 8db076f4ba65..79cecf8ac97d 100644
>> --- a/meta/files/overlayfs-etc-preinit.sh.in
>> +++ b/meta/files/overlayfs-etc-preinit.sh.in
>> @@ -3,12 +3,15 @@
>>   echo "PREINIT: Start"
>>     PATH=/sbin:/bin:/usr/sbin:/usr/bin
>> -mount -o remount,rw /
>> -
>> -mkdir -p /proc
>> -mkdir -p /sys
>> -mkdir -p /run
>> -mkdir -p /var/run
>> +if ! {READ_ONLY_ROOTFS}; then
>> +    mount -o remount,rw /
>> +
>> +    mkdir -p /proc
>> +    mkdir -p /sys
>> +    mkdir -p /run
>> +    mkdir -p /var/run
>> +    mkdir -p {OVERLAYFS_ETC_MOUNT_POINT}
>> +fi
>
> I don't think this would be a correct approach. You probably should only
> remount to ro after all mount points are created.

As I understand, the point of read-only-rootfs feature is to keep rootfs
intact. Filesystems like squashfs or erofs don't support rw mount at
all. How can we support this use case?

> With this patch overlayfs.OverlayFSEtcRunTimeTests.test_sbin_init_preinit
> fails:
>
> 2024-02-08 21:12:40,616 - oe-selftest - INFO - Traceback (most recent call
> last):
>   File
> "/home/uvv/projects/upstream/poky/meta/lib/oeqa/core/decorator/__init__.py",
> line 35, in wrapped_f
>     return func(*args, **kwargs)
>   File
> "/home/uvv/projects/upstream/poky/meta/lib/oeqa/selftest/cases/overlayfs.py",
> line 370, in test_sbin_init_preinit
>     self.run_sbin_init(False)
>   File
> "/home/uvv/projects/upstream/poky/meta/lib/oeqa/selftest/cases/overlayfs.py",
> line 399, in run_sbin_init
>     self.assertTrue("/data" in output, msg=output)
> AssertionError: False is not true : /dev/sda2 on / type ext4 (ro,relatime)

Where is this /dev/sda2 coming from? I have also seen it in my
/etc/fstab once I enabled the overlayfs-etc feature. I see no mention of
sda2 in meta/lib/oeqa/selftest/cases/overlayfs.py.

> The test is not really explicit, but it looks like overlay is not mounted. We
> could also add a generic test to search for "PREINIT" done/failed.

How can I run this test?

Thanks,
baruch

>
>>   mount -t proc proc /proc
>>   mount -t sysfs sysfs /sys
>> @@ -20,7 +23,6 @@ UPPER_DIR=$BASE_OVERLAY_ETC_DIR/upper
>>   WORK_DIR=$BASE_OVERLAY_ETC_DIR/work
>>   LOWER_DIR=$BASE_OVERLAY_ETC_DIR/lower
>>   -mkdir -p {OVERLAYFS_ETC_MOUNT_POINT}
>>   if mount -n -t {OVERLAYFS_ETC_FSTYPE} \
>>       -o {OVERLAYFS_ETC_MOUNT_OPTIONS} \
>>       {OVERLAYFS_ETC_DEVICE} {OVERLAYFS_ETC_MOUNT_POINT}
>
> Thanks,
> Slava
Vyacheslav Yurkov Feb. 11, 2024, 6:22 p.m. UTC | #3
On 11.02.2024 14:23, Baruch Siach wrote:
> As I understand, the point of read-only-rootfs feature is to keep rootfs
> intact. Filesystems like squashfs or erofs don't support rw mount at
> all. How can we support this use case?

That's a really good question. I assume we need to differentiate here 
the ro rootfs just because it's set this way in fstab, or ro rootfs, 
which doesn't support writing at all. For the latter you still need all 
your directories already created in the image (squashfs, erofs) or you 
would mount it in some location on tmpfs. Point is, mount point has to 
exist. I suggest we follow the similar approach like in 
overlayfs.bbclass, i.e. we add a flag, which can be used to skip 
directory creation for this use case. Please use 'false' as a default, 
so existing users don't have to change anything when they upgrade their 
Yocto version.

>> With this patch overlayfs.OverlayFSEtcRunTimeTests.test_sbin_init_preinit
>> fails:
>>
>> 2024-02-08 21:12:40,616 - oe-selftest - INFO - Traceback (most recent call
>> last):
>>    File
>> "/home/uvv/projects/upstream/poky/meta/lib/oeqa/core/decorator/__init__.py",
>> line 35, in wrapped_f
>>      return func(*args, **kwargs)
>>    File
>> "/home/uvv/projects/upstream/poky/meta/lib/oeqa/selftest/cases/overlayfs.py",
>> line 370, in test_sbin_init_preinit
>>      self.run_sbin_init(False)
>>    File
>> "/home/uvv/projects/upstream/poky/meta/lib/oeqa/selftest/cases/overlayfs.py",
>> line 399, in run_sbin_init
>>      self.assertTrue("/data" in output, msg=output)
>> AssertionError: False is not true : /dev/sda2 on / type ext4 (ro,relatime)
> Where is this /dev/sda2 coming from? I have also seen it in my
> /etc/fstab once I enabled the overlayfs-etc feature. I see no mention of
> sda2 in meta/lib/oeqa/selftest/cases/overlayfs.py.

The test actually expects sda3 as overlay partition. The partitions are 
created by means of wic, the configuration is in 
https://git.openembedded.org/openembedded-core/tree/meta-selftest/wic/overlayfs_etc.wks.in 
, and pulled in by WKS_FILE in meta/lib/oeqa/selftest/cases/overlayfs.py.

Perhaps we could extend test coverage for your use case by parametrizing 
wks.in file further and placing rootfs on squashfs partition? I haven't 
checked TBH whether wic supports it :)
>> The test is not really explicit, but it looks like overlay is not mounted. We
>> could also add a generic test to search for "PREINIT" done/failed.
> How can I run this test?

Use this command:
oe-selftest -r overlayfs.OverlayFSEtcRunTimeTests.test_sbin_init_preinit

Check also this link https://wiki.yoctoproject.org/wiki/Oe-selftest and 
prepare your environment first


Cheers,
Slava

>
> Thanks,
> baruch
Baruch Siach Feb. 12, 2024, 2:21 p.m. UTC | #4
Hi Slava,

On Sun, Feb 11 2024, Vyacheslav Yurkov wrote:
> On 11.02.2024 14:23, Baruch Siach wrote:
> Use this command:
> oe-selftest -r overlayfs.OverlayFSEtcRunTimeTests.test_sbin_init_preinit
>
> Check also this link https://wiki.yoctoproject.org/wiki/Oe-selftest and prepare your environment first

I reproduced the test failure. The output does not give much of a clue
as to the cause of failure. How can I run the same qemu command
interactively? Is qemu test console output saved somewhere? This log
might be useful.

Thanks,
baruch
Vyacheslav Yurkov Feb. 12, 2024, 6:38 p.m. UTC | #5
On 12.02.2024 15:21, Baruch Siach wrote:
> I reproduced the test failure. The output does not give much of a clue
> as to the cause of failure. How can I run the same qemu command
> interactively? Is qemu test console output saved somewhere? This log
> might be useful.
>
> Thanks,
> baruch
>

It could be that it failed, because qemu needs sudo for a few commands 
(or respective permissions for the user you run test under). These are 
included in my /etc/sudoers:
poky/scripts/runqemu-ifup
poky/scripts/runqemu-ifdown
poky/scripts/runqemu-gen-tapdevs

Could you please verify if it works after that? If yes, I'll extend the 
mentioned wiki page.

As for the interactive run, this command works for me:
runqemu 
../build-st/tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.wic

Slava
Baruch Siach Feb. 12, 2024, 6:40 p.m. UTC | #6
Hi Slava,

On Mon, Feb 12 2024, Vyacheslav Yurkov wrote:
> On 12.02.2024 15:21, Baruch Siach wrote:
>> I reproduced the test failure. The output does not give much of a clue
>> as to the cause of failure. How can I run the same qemu command
>> interactively? Is qemu test console output saved somewhere? This log
>> might be useful.
>>
>> Thanks,
>> baruch
>
> It could be that it failed, because qemu needs sudo for a few commands (or
> respective permissions for the user you run test under). These are included in
> my /etc/sudoers:
> poky/scripts/runqemu-ifup
> poky/scripts/runqemu-ifdown
> poky/scripts/runqemu-gen-tapdevs
>
> Could you please verify if it works after that? If yes, I'll extend the
> mentioned wiki page.

I think the failure is because /data does not exist in generated
rootfs. That explains why sda1/sda2 are mounted but not sda3. With that
insight I updated the patch to use an optional variable as you
suggested. Patch v2 passed the test here.

> As for the interactive run, this command works for me:
> runqemu
> ../build-st/tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.wic

Thanks for the tip.

baruch
diff mbox series

Patch

diff --git a/meta/classes-recipe/overlayfs-etc.bbclass b/meta/classes-recipe/overlayfs-etc.bbclass
index 0c7834d01f43..e695ebdcf843 100644
--- a/meta/classes-recipe/overlayfs-etc.bbclass
+++ b/meta/classes-recipe/overlayfs-etc.bbclass
@@ -69,7 +69,9 @@  python create_overlayfs_etc_preinit() {
         'OVERLAYFS_ETC_FSTYPE': overlayEtcFsType,
         'OVERLAYFS_ETC_DEVICE': overlayEtcDevice,
         'SBIN_INIT_NAME': initBaseName + origInitNameSuffix if useOrigInit else initBaseName,
-        'OVERLAYFS_ETC_EXPOSE_LOWER': "true" if exposeLower else "false"
+        'OVERLAYFS_ETC_EXPOSE_LOWER': "true" if exposeLower else "false",
+        'READ_ONLY_ROOTFS': bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
+                                              "true", "false", d)
     }
 
     if useOrigInit:
diff --git a/meta/files/overlayfs-etc-preinit.sh.in b/meta/files/overlayfs-etc-preinit.sh.in
index 8db076f4ba65..79cecf8ac97d 100644
--- a/meta/files/overlayfs-etc-preinit.sh.in
+++ b/meta/files/overlayfs-etc-preinit.sh.in
@@ -3,12 +3,15 @@ 
 echo "PREINIT: Start"
 
 PATH=/sbin:/bin:/usr/sbin:/usr/bin
-mount -o remount,rw /
-
-mkdir -p /proc
-mkdir -p /sys
-mkdir -p /run
-mkdir -p /var/run
+if ! {READ_ONLY_ROOTFS}; then
+    mount -o remount,rw /
+
+    mkdir -p /proc
+    mkdir -p /sys
+    mkdir -p /run
+    mkdir -p /var/run
+    mkdir -p {OVERLAYFS_ETC_MOUNT_POINT}
+fi
 
 mount -t proc proc /proc
 mount -t sysfs sysfs /sys
@@ -20,7 +23,6 @@  UPPER_DIR=$BASE_OVERLAY_ETC_DIR/upper
 WORK_DIR=$BASE_OVERLAY_ETC_DIR/work
 LOWER_DIR=$BASE_OVERLAY_ETC_DIR/lower
 
-mkdir -p {OVERLAYFS_ETC_MOUNT_POINT}
 if mount -n -t {OVERLAYFS_ETC_FSTYPE} \
     -o {OVERLAYFS_ETC_MOUNT_OPTIONS} \
     {OVERLAYFS_ETC_DEVICE} {OVERLAYFS_ETC_MOUNT_POINT}