core icon indicating copy to clipboard operation
core copied to clipboard

Resizing on the first boot on disks with MBR scheme

Open matheusber opened this issue 9 months ago • 16 comments

Important notices

Before you add a new report, we ask you kindly to acknowledge the following:

  • [X] I have read the contributing guide lines at https://github.com/opnsense/core/blob/master/CONTRIBUTING.md
  • [X] I am convinced that my issue is new after having checked both open and closed issues at https://github.com/opnsense/core/issues?q=is%3Aissue

Describe the bug

The resize of the root file system on ARM64 systems is not working when the image uses MBR partition scheme. This happens in 25.1, I don't know when started, but 24.7 is also affected.

To Reproduce

I compile opnsense here for NanoPi R5S, but it was tested on the NanoPi R4S conf available on opnsense repository as well.

Just issue:

make DEVICE=R4S base; 
make DEVICE=R4S kernel;
make DEVICE=R4S ports;
make DEVICE=R4S plugins;
make DEVICE=R4S core;
make DEVICE=R4S packages;
make DEVICE=R4S arm;

and write the final image to a micoSD. The boot will go fine, but root FS won't resize. I run this on ARM64 box (Raspberry Pi 5).

Expected behavior

The boot script will try to resize partition with ID 1 using gpart, and on MBR scheme the root FS is ID 2 (ID 1 is vfat for EFI files). Then there will be message as:

mmcsd0s1 resized
growfs: requested size 2.9GB is equal to the current filesystem size 2.9GB

If the right partition is addressed, the resize runs fine and after the first boot the root FS uses all microSD space.

Describe alternatives you considered

A clear and concise description of any alternative solutions or workaround you considered. The script has an "if" test that when MBR scheme is present (and this is the default for the arch as R4S uses on default R4S.conf), it always returns IDX=1. So gpart runs on partition 1. I took the liberty to create another test here. The line:

local IDX=${1##"${DEV}p"} Won't match for MBR cases, where the pattern will be like ada0s2, as the "p" looks like GPT scheme. So here I created the test:

if [ "${SCHEME}" = "MBR" ]; then
                # MBR, the device slice will not end in pX, but sX, as in "ada0s2a"
                local SLICE=${1##"${DEV}s"}
                # Need to get only the index of the partition, the letter for BSD label should go
                local IDX=$(echo "${SLICE}" | cut -c1)
        else
                # No MBR, as was treated befoe
                local IDX=${1##"${DEV}p"}
        fi

I had to change a few lines also on the main code (outside the grow_partition function), as after the gpart resize running on ARM64, it tells on the console to run gpart issuing the commit comand:

mmcsd0 recovering is not needed
GEOM_PART: ufs/OPNsense was automatically resized.
  Use `gpart commit ufs/OPNsense` to save changes or `gpart undo ufs/OPNsense` to revert them.
mmcsd0s2 resized

So the lines were added:

          # Find out if its a MBR scheme, as the ones on ARM64 boards
              DEV=$(echo "${ROOT_IS_UFS}" | awk 'match($0, /^[a-z]+[0-9]+/) { print substr( $0, RSTART, RLENGTH )}')
              SCHEME=$(gpart list $DEV | grep scheme | awk '{print $2}')
              
              if [ "${SCHEME}" = "MBR" ]; then
                      # Need to run gpart commit to keep going the resizing
                      gpart commit $FS_LABEL
              fi

Screenshots Relevant log files Additional context

For more information, I have the full thread on opnsense forum in https://forum.opnsense.org/index.php?topic=46663.15

There is a suggested core/src/etc/rc file on that thread, that I have tested here but my resources are far smaller than yours, as are my skills.

The rc was tested on Nano images for AMD64 as well.

Environment

Software version used and hardware type if relevant, e.g.: OPNsense 25.1.3 and 25.1.4 running on R5S and R4S

matheusber avatar Apr 13 '25 12:04 matheusber

DMS? I'm unsure we really need to have a preinstalled jail for every DMS across the world. The filters are principally OK (it's just additional file unless referenced), but the jail.conf will be always used, and every jail costs time (even if not enabled)... I must think about some encapsulation of jails/filters in new version, either by some additional groups or probably much better: a remodeling moving jail info (default port, logpath, etc) to the filter and remove all "non-generic" (or even completely all) jails from jail.conf, so if one would add new section for the jail in jail.local, everything else would work out-of-the-box.

sebres avatar Apr 03 '25 09:04 sebres

That's actually great idea. Maybe add the filter and reference the example jail in the filter so if anyone wants to use the filter knows how to set the jail also. That way we can add more filters for option but at the same time not consuming time because the jail.conf. should I remove the jail from this PR and add the example jail in the filter?

DMS? I'm unsure we really need to have a preinstalled jail for every DMS across the world. The filters are principally OK (it's just additional file unless referenced), but the jail.conf will be always used, and every jail costs time (even if not enabled)... I must think about some encapsulation of jails/filters in new version, either by some additional groups or probably much better: a remodeling moving jail info (default port, logpath, etc) to the filter and remove all "non-generic" (or even completely all) jails from jail.conf, so if one would add new section for the jail in jail.local, everything else would work out-of-the-box.

LearningSpot avatar Apr 03 '25 09:04 LearningSpot

Not yet, maybe later... IIRC, the jail is mandatory right now.

sebres avatar Apr 03 '25 11:04 sebres

Not yet, maybe later... IIRC, the jail is mandatory right now.

Just a thought, how about commenting out the jails no need to be there always. That shouldn't affect the time consumption. Will it work?

LearningSpot avatar Apr 03 '25 12:04 LearningSpot

Well, doesn't matter currently, to be covered correctly by the test-suite it shall be with a jail, so if jail gets commented it'd produce at least this error: https://github.com/fail2ban/fail2ban/blob/c76e90fbb17115b90ca5b641c2183c0e3e644942/fail2ban/tests/clientreadertestcase.py#L889

sebres avatar Apr 03 '25 14:04 sebres

Well, doesn't matter currently, to be covered correctly by the test-suite it shall be with a jail, so if jail gets commented it'd produce at least this error: https://github.com/fail2ban/fail2ban/blob/c76e90fbb17115b90ca5b641c2183c0e3e644942/fail2ban/tests/clientreadertestcase.py#L889

Well I also thought it won't be that easy or you would have implemented that already. I think it's because the verification on line 873

LearningSpot avatar Apr 03 '25 15:04 LearningSpot