Musl libc realpath implementation calls readlink on a procfs
path it computes via __procfdname (code at [1] & [2]).
This is problematic if ubase mount is used in a PID 1 because procfs
is not mounted and the kernel passes the rootfs mounted read-only, so
the first step is to read-write remount the rootfs, which can't be
done because procfs is not mounted. Thus we are in a dependency cycle:
procfs can't be mounted because the root is read-only and so on.
To break this cycle, don't call readlink on "/" (it doesn't really make
sense anyway) so the rootfs can be remounted read-write, after which
proc itself can be mounted and the rest of mount calls will succeed
so systems running ubase + musl can succesfully boot into userspace.
[1] https://git.musl-libc.org/cgit/musl/tree/src/misc/realpath.c?h=v1.1.19
[2] https://git.musl-libc.org/cgit/musl/tree/src/internal/procfdname.c?h=v1.1.19
Signed-off-by: Ioan-Adrian Ratiu <adi@adirat.com>
If a mount helper is used, only argopts (given on commandline) are
passed to the helper via -o parameter. Option strings from fstab are
ignored.
This patch replaces global argopts pointer with a character array
fsopts. A maximum length for filesytem options is #defined (used by
fsopts and data), and argument/mntent options are length-checked to fit.
A filesystem with too long an option string will print an error, cause
mount to exit with an error status, and not attempt to mount the
filesystem. This obviates the need for overflow checking of data in
parseopts(), though it hasn't been removed.
- helper support (mount.type).
- helpers need to be in $PATH, if needed we can add a check for
/sbin/mount.XXXX
- pass -B, -M, -R to helper, its more reliable to pass these named
options with -o however.
- allow prefix "no" for which type no action should be taken:
mount -a -t nonfs,ext4
fix bugs:
- dont modify me->mnt_opts (used strtok).
- use getmntent_r instead of getmntent: because getmntent was nested it
overwrote the previous internal mntent structure.
- check mounted() first, if not try to mount: this also makes sure filesystems
were not mounted multiple times (like tmpfs) and errno is not overwritten in
mounted(). For this reason also mount() errno EBUSY can't be used (tested).