Revision (<<< Hide revision tags) (Show revision tags >>>) Date Author Comments
# e143c93c 14-Feb-2024 Andrew Geissler <geissonator@yahoo.com>

mmc-init.sh: ensure only one udevd running

Recently the following error started popping up in the journal:
```
Jan 04 07:53:25 p10bmc systemd-coredump[174]: Due to PID 1 having crashed coredump coll

mmc-init.sh: ensure only one udevd running

Recently the following error started popping up in the journal:
```
Jan 04 07:53:25 p10bmc systemd-coredump[174]: Due to PID 1 having crashed coredump collection will now be turned off.
Jan 04 07:53:25 p10bmc systemd-coredump[174]: Resource limits disable core dumping for process 76 (udevd).
Jan 04 07:53:25 p10bmc systemd-coredump[174]: Process 76 (udevd) of user 0 dumped core.
```

This error during boot was disabling all coredump generation and
collection on the system.

After a lot of digging, it was found that we were actually running 2
instances of udevd on the system. One started by this script, and
another by systemd-udevd.service. The one failing was the first one we
started. It's safe to assume that running 2 instances of udevd has
undefined behavior and something in more recent openbmc (or systemd) has
caused this fail to start.

Tested:
- Confirmed BMC still boots fine and coredumps now work

Change-Id: I3e4aaa82b18181f1bba62d76ff13af29437c9bb8
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>

show more ...


Revision tags: 2.16.0-dev
# e9284a5c 01-Jun-2023 Andrew Jeffery <andrew@aj.id.au>

meta-phosphor: mmc-init: Abide by init= from kernel commandline

Use of e.g. systemd-bootchart[1] requires that we override the path to
`init` on the kernel commandline. Currently `mmc-init.sh` hard-

meta-phosphor: mmc-init: Abide by init= from kernel commandline

Use of e.g. systemd-bootchart[1] requires that we override the path to
`init` on the kernel commandline. Currently `mmc-init.sh` hard-codes
`/sbin/init` as the init path and this prevents such boot analysis.

Generalise option processing for the kernel commandline so we can
extract the value for arbitrary key-value pairs and build the required
functionality on top of this new abstraction.

[1]: https://manpages.debian.org/testing/systemd-bootchart/systemd-bootchart.1.en.html

Change-Id: I3d3d441f4861e1ce37954a0fcd49eb15906006a1
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

show more ...


Revision tags: 2.14.0, 2.14.0-rc1, 2.15.0-dev
# 2ea84ebf 25-Apr-2023 Andrew Jeffery <andrew@aj.id.au>

meta-phosphor: mmc-init: Fix creation of critical directories

`mkdir $fslist` is responsible for creating all the critical mount-point
directories for a functioning Linux userspace, such as `/dev`,

meta-phosphor: mmc-init: Fix creation of critical directories

`mkdir $fslist` is responsible for creating all the critical mount-point
directories for a functioning Linux userspace, such as `/dev`, `/proc`
and `/sys`. 2345ace954c2 ("meta-phosphor: phosphor-mmc-init: fix
shellcheck") prevented their existence by instead creating a single
directory named "proc sys dev run":

```
~ # ls -1
bin
dev
etc
init
lib
mnt
proc sys dev run
root
run
sbin
usr
var
```

The lack of directories lead to the inability to mount the required
filesystems, with the boot process stalling at an initrd shell prompt:

```
[ 1.224302] Freeing initrd memory: 3272K
[ 1.265274] Freeing unused kernel image (initmem) memory: 1024K
[ 1.291134] Checked W+X mappings: passed, no W+X pages found
[ 1.291492] Run /init as init process
mount: mounting sys on sys failed: No such file or directory
mount: mounting proc on proc failed: No such file or directory
[ 2.600405] mmcblk0: p1 p2 p3 p4 p5 p6 p7
The operation has completed successfully.
Failed to parse kernel command line, ignoring: No such file or directory
Starting systemd-udevd version 253.1^
Running in chroot, ignoring request.
Running in chroot, ignoring request.
cat: can't open '/proc/cmdline': No such file or directory
[ 2.706024] /dev/disk/by-partlabel/: Can't open blockdev
mount: mounting /dev/disk/by-partlabel/ on /mnt/rofs failed: No such file or directory
/bin/sh: can't access tty; job control turned off
~ #
```

Change-Id: Ie0821508ed7e141c89d7620a6ed0adc069f5c267
Fixes: 2345ace954c2 ("meta-phosphor: phosphor-mmc-init: fix shellcheck")
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

show more ...


# f307a2f0 18-Apr-2023 Zev Weiss <zev@bewilderbeest.net>

meta-phosphor: phosphor-mmc-init: fix multi-word variable expansion

The $gpiopresent expansion needs to be unquoted, because gpioget needs
to take the gpiochip and line number (both of which gpiofin

meta-phosphor: phosphor-mmc-init: fix multi-word variable expansion

The $gpiopresent expansion needs to be unquoted, because gpioget needs
to take the gpiochip and line number (both of which gpiofind produces)
as separate arguments.

Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Change-Id: Iaa5943cf247e523a9c901325ce2290a4f537a50f

show more ...


# 2345ace9 14-Apr-2023 Patrick Williams <patrick@stwcx.xyz>

meta-phosphor: phosphor-mmc-init: fix shellcheck

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I1f668e1e40c937e016c60af13705ea60936ed739


# a2e2aea3 24-Jan-2023 Andrew Jeffery <andrew@aj.id.au>

meta-phosphor: phosphor-mmc-init: Fix commandline parsing for root

From Joel in [1]:

```
It expects a command line string to be in the form:

console=ttyS4,115200n8 rootwait root=PARTLABEL=rofs-a

meta-phosphor: phosphor-mmc-init: Fix commandline parsing for root

From Joel in [1]:

```
It expects a command line string to be in the form:

console=ttyS4,115200n8 rootwait root=PARTLABEL=rofs-a

If booting with root=PARTLABEL=rofs-a at the start of the command line
string (instead of the end), the parsing gets confused:

[ 8.241229] /dev/disk/by-partlabel/root=PARTLABEL=rofs-a: Can't open blockdev
mount: mounting /dev/disk/by-partlabel/root=PARTLABEL=rofs-a on /mnt/rofs failed: No such file or directory

Similarly if the partition is not set, it gets confused:

[ 1.919816] Run /init as init process
Starting version 251.8+
[ 8.219396] /dev/disk/by-partlabel/rootwait: Can't open blockdev
mount: mounting /dev/disk/by-partlabel/rootwait on /mnt/rofs failed: No such file or directory

We should fix get_root so that it checks for the existance of
root=PARTLABEL, and matches on it. We could fall back on rofs-a if it
can't be found?
```

Based on Joel's example I tested the new implementation as follows:

```
$ declare -f old_get_root
old_get_root ()
{
local root="$@";
root="${root##* root=PARTLABEL=}";
root="${root%% *}";
[ "${root}" != "" ] && echo "${root}"
}
$ declare -f new_get_root
new_get_root ()
{
local cmdline="$@";
root=;
for opt in $cmdline;
do
case $opt in
root=PARTLABEL=*)
root=${opt##root=PARTLABEL=}
;;
*)

;;
esac;
done;
[ -n "$root" ] && echo $root
}
```

Comparing the two under various commandline orderings:

```
$ echo $working_cmdline
console=ttyS4,115200n8 rootwait root=PARTLABEL=rofs-a
$ old_get_root $working_cmdline
rofs-a
$ new_get_root $working_cmdline
rofs-a
$
```

```
$ echo $broken_cmdline
root=PARTLABEL=rofs-a console=ttyS4,115200n8 rootwait
$ old_get_root $broken_cmdline
root=PARTLABEL=rofs-a
$ new_get_root $broken_cmdline
rofs-a
$
```

```
$ echo $maybe_cmdline
console=ttyS4,115200n8 root=PARTLABEL=rofs-a rootwait
$ old_get_root $maybe_cmdline
rofs-a
$ new_get_root $maybe_cmdline
rofs-a
$
```

```
$ echo $dev_cmdline
console=ttyS4,115200n8 root=/dev/sda1 rootwait
$ old_get_root $dev_cmdline
console=ttyS4,115200n8
$ new_get_root $dev_cmdline
$
```

In each case new_get_root() gives the expected output.

[1]: https://github.com/openbmc/openbmc/issues/3898

Fixes: 0998d1e4fc58 ("initramfs: Add init script for eMMC")
Change-Id: I68e95d74dd33c54d956d08ae3332ba7bdec9aeeb
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

show more ...


Revision tags: 2.13.0, 2.14.0-dev, 2.12.0, 2.12.0-rc1, 2.13.0-dev, 2.11.0, 2.12.0-dev
# 5003195b 07-Sep-2021 Isaac Kurth <isaac.kurth@ibm.com>

mmc-init: Enable factory reset from gpio change

The factory-reset-toggle GPIO can have its state changed by physically
toggling SWITCH_RESET_N. If this GPIO is in a different state than

mmc-init: Enable factory reset from gpio change

The factory-reset-toggle GPIO can have its state changed by physically
toggling SWITCH_RESET_N. If this GPIO is in a different state than it
was during the last boot, it triggers a BMC factory reset.

Tested: Added extra files to /var. Verified that a reset from a
physical toggle caused these files to be removed. Verified that resets
from the REST API and from setting rwreset to true still function
properly. Verified that repeated rebooting without calling for a reset
does not inadvertently trigger a reset.

Signed-off-by: Isaac Kurth <isaac.kurth@ibm.com>
Change-Id: I3cf3f9519033db240c0db2eec35a5b09b8fefdf2

show more ...


# 315698e5 25-Jun-2021 Isaac Kurth <isaac.kurth@ibm.com>

mmc-init: Add factory reset based on rwreset

To enable factory resets, the mmc-init.sh script checks on reboot if
the environment variable rwreset is set to "true". If it is, the rw

mmc-init: Add factory reset based on rwreset

To enable factory resets, the mmc-init.sh script checks on reboot if
the environment variable rwreset is set to "true". If it is, the rw
parts of the file system that users may have modified are reformatted
to remove all user changes and rwreset is set to "false".

Tested: Add a file to /var and use fw_setenv to set rwreset to true.
Reboot the machine and verify that the added file is gone and rwreset
is set to false.

Signed-off-by: Isaac Kurth <isaac.kurth@ibm.com>
Change-Id: I2d8b4f4eaf8ff6df092893760aaae9db2ce3917b

show more ...


Revision tags: 2.10.0-rc1, 2.11.0-dev
# 9e08ff4c 01-Apr-2021 Andrew Jeffery <andrew@aj.id.au>

phosphor-mmc-init: Determine EFI partition presence via exit code

Testing if $magic is empty is an indirect test of whether the grep
succeeded. Instead, just use the grep exit code.

phosphor-mmc-init: Determine EFI partition presence via exit code

Testing if $magic is empty is an indirect test of whether the grep
succeeded. Instead, just use the grep exit code.

Change-Id: I3eba40e8b54863ab9a1a4436f1419b69c5bea8e1
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

show more ...


# b5cbe9bb 01-Apr-2021 Andrew Jeffery <andrew@aj.id.au>

phosphor-mmc-init: exec switch_root(8) rather than chroot(1)

It was found that perf(1) had some issues with recording and analysing
data on Rainier systems:

```
root@rainier

phosphor-mmc-init: exec switch_root(8) rather than chroot(1)

It was found that perf(1) had some issues with recording and analysing
data on Rainier systems:

```
root@rainier:~# perf probe --add mem_serial_in
root@rainier:~# perf record -e probe:mem_serial_in -aR sleep 1
[ perf record: Woken up 1 times to write data ]
assertion failed at util/namespaces.c:257
No kallsyms or vmlinux with build-id e4e9c7cff1deb3bf32958039c696f094dc76cf5c was found
[ perf record: Captured and wrote 0.377 MB perf.data (25 samples) ]
root@rainier:~# perf script -v
build id event received for [kernel.kallsyms]: e4e9c7cff1deb3bf32958039c696f094dc76cf5c
broken or missing trace data
incompatible file format (rerun with -v to learn more)
```

Starting with the failed assertion in the recording, we find the
relevant code is the following WARN_ON_ONCE():

```
void nsinfo__mountns_exit(struct nscookie *nc)
{
...

if (nc->oldcwd) {
WARN_ON_ONCE(chdir(nc->oldcwd));
zfree(&nc->oldcwd);
}
```

A strace of `perf record` demonstrates the relevant syscall sequence,
where /home/root is the working directory at the time when `perf record`
is invoked.

```
openat(AT_FDCWD, "/proc/self/ns/mnt", O_RDONLY|O_LARGEFILE) = 12
openat(AT_FDCWD, "/proc/142/ns/mnt", O_RDONLY|O_LARGEFILE) = 13
setns(13, CLONE_NEWNS) = 0
statx(AT_FDCWD, "/mnt/rofs/bin/udevadm", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|0x1000, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=978616, ...}) = 0
openat(AT_FDCWD, "/mnt/rofs/bin/udevadm", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 14
setns(12, CLONE_NEWNS) = 0
chdir("/home/root") = -1 ENOENT (No such file or directory)
```

From the path of the binary, PID 142 is executing in an unanticipated
environment. Its path is representative of the state of the filesystem
prior to the initramfs handing over to /sbin/init in the real root,
suggesting an issue with the initramfs' /init implementation.

In /init we find a bunch of setup to discover and mount the root device.
At the end of the script we prepare for the real root by exec'ing chroot.

From `man 2 chroot`[0]:

```
DESCRIPTION
chroot() changes the root directory of the calling process to that speci‐
fied in path. This directory will be used for pathnames beginning with /.
The root directory is inherited by all children of the calling process.
```

Specifically, this outlines that chroot(2) affects the state of the
calling *process* and not the state of mount namespace in use by the
process.

Further, a call to `setns(..., CLONE_NEWNS)` explicitly replaces the
mount namespace for the *process*, and as such destroys any chroot state
that might have been associated with the process' original mount
namespace. As the chroot state is not a property of a mount namespace,
switching *back* to the application's original mount namespace does not
restore the process' original chroot state.

As such, the chdir(2) from the strace output above returns an error, as
the get_current_dir_name(3) call that yielded the provided path was
issued prior to switching into the target process' mount namespace, and
was thus derived in the chroot context. The path is therefore invalid
once the original mount namespace is restored via the second setns(2) as
the process has (already) lost the chroot context for the original
namespace.

For perf(1) to work in its current implementation the effective root for
PID 1 must remain the absolute path "/" with respect to the kernel's VFS
layer. This requires /init to use either pivot_root(1) or
switch_root(1). pivot_root(1) is ruled out by its own man-page[1]:

```
NOTES
...

The rootfs (initial ramfs) cannot be pivot_root()ed. The recommended
method of changing the root filesystem in this case is to delete every‐
thing in rootfs, overmount rootfs with the new root, attach stdin/std‐
out/stderr to the new /dev/console, and exec the new init(1). Helper pro‐
grams for this process exist; see switch_root(8).

...
```

As noted, the recommendation is a description of the switch_root(8)
application[2]. The details of why the specific sequence for
switch_root(8) is necessary is documented in [3].

Change /init to use switch_root(8) to avoid the nasty interaction of
chroot(2) and setns(2).

[0] https://man7.org/linux/man-pages/man2/chroot.2.html#DESCRIPTION
[1] https://man7.org/linux/man-pages/man2/pivot_root.2.html#NOTES
[2] https://man7.org/linux/man-pages/man8/switch_root.8.html
[3] https://git.busybox.net/busybox/tree/util-linux/switch_root.c?h=1_32_1#n298

Change-Id: Iac29b53a462b03559d18fe9b600aefcd1951057e
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

show more ...


Revision tags: 2.9.0, 2.9.0-rc1, 2.10.0-dev
# 1f6ac838 24-Aug-2020 Adriana Kobylak <anoo@us.ibm.com>

mmc-init: Run fsck.ext4 on the rwfs device

It's a good practice to run fsck before mounting a device. Call
fsck.ext4 -p on the read-write device, this option attempts to
fix any erro

mmc-init: Run fsck.ext4 on the rwfs device

It's a good practice to run fsck before mounting a device. Call
fsck.ext4 -p on the read-write device, this option attempts to
fix any error that can be fixed safely without user intervention.
No need to check for the return code, if it fails then the mount
command will likely fail.

It also takes no time to run:

mount read-only -> fsck read-write -> mount read-write:

[ 4.174115] EXT4-fs (mmcblk0p4): mounted filesystem with ordered data mode. Opts: (null)
rwfs: clean, 11/917504 files, 81919/1835008 blocks
[ 4.185143] EXT4-fs (mmcblk0p6): mounted filesystem with ordered data mode. Opts: (null)

(From meta-phosphor rev: c3d695892ef990f70cb851b5613dee68068471b3)

Change-Id: I946791233a06da0c8ee16585d92f64039a845879
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>

show more ...


# 331a3695 17-Aug-2020 Adriana Kobylak <anoo@us.ibm.com>

mmc-init.sh: Wait for mmc device

The initramfs was accessing the mmc device before it was probed
in some cases, leading to this error message:

[ 4.412464] mmcblk0rpmb: mmc0:0

mmc-init.sh: Wait for mmc device

The initramfs was accessing the mmc device before it was probed
in some cases, leading to this error message:

[ 4.412464] mmcblk0rpmb: mmc0:0001 R1J56L partition 3 128 KiB, chardev (248:0)
tail: can't open '/dev/mmcblk0': No such file or directory
tail: no files
[ 5.471158] mmcblk0: p1 p2 p3 p4 p5 p6 p7

Implement a wait loop of up to 5s to wait for the device,
similar to what the kernel would do with rootwait.

Tested: Verified the error is not longer seen. Printing the count
value as debug, it took one sleep iteration to appear:

[ 4.396492] mmcblk0boot1: mmc0:0001 R1J56L partition 2 16.0 MiB
0
[ 4.403500] mmcblk0rpmb: mmc0:0001 R1J56L partition 3 128 KiB, chardev (248:0)
[ 4.416176] mmcblk0: p1 p2 p3 p4 p5 p6 p7
1
[ 6.159693] EXT4-fs (mmcblk0p4): mounted filesystem with ordered data mode. Opts: (null)

(From meta-phosphor rev: b7dccc1c380431f4cc96e0228fb9975d33df1f88)

Change-Id: I625a879882311285dbdeaa2ea271c379366f4b9b
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>

show more ...


# 0998d1e4 03-Jun-2020 Adriana Kobylak <anoo@us.ibm.com>

initramfs: Add init script for eMMC

This init script mounts the rootfs based on the root u-boot env
variable, mounts the read-write filesystem and sets up the overlay.

(From met

initramfs: Add init script for eMMC

This init script mounts the rootfs based on the root u-boot env
variable, mounts the read-write filesystem and sets up the overlay.

(From meta-phosphor rev: 86164b2e072cc6cebc9caf1614e2b1fa0e0884a0)

Change-Id: If9121048b6223d5391e5f6a8b7d6cd7d22707969
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>

show more ...