Subject: [alpine-devel] [PATCH 1/3] mkinitfs: add option to avoid including kernel-specific files

From: Shiz <[email-masked]>
Date: Thu, 17 Nov 2016 02:52:50 +0100

This allows one to make a generic initramfs that doesn't require a running
kernel identical to the one used for booting, if said kernel already includes
everything it needs to function (such as compiling everything in instead of
using kernel modules).
---
 mkinitfs.in | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/mkinitfs.in b/mkinitfs.in
index d69ccc5..a860cbc 100755
--- a/mkinitfs.in
+++ b/mkinitfs.in
@@ -102,6 +102,7 @@ find_kmods() {
 }
 
 initfs_kmods() {
+	[ -z "$nokernel" ] || return
 	local glob= file= files= dirs=
 	rm -rf "$tmpdir"/lib/modules
 	# make sure we have modules.dep
@@ -123,6 +124,7 @@ initfs_kmods() {
 }
 
 initfs_firmware() {
+	[ -z "$nokernel" ] || return
 	rm -rf "$tmpdir"/lib/firmware
 	mkdir -p "$tmpdir"/lib/firmware
 	find "$tmpdir"/lib/modules -type f -name "*.ko" | xargs modinfo -F firmware | sort -u | while read FW; do
@@ -149,7 +151,7 @@ initfs_cpio() {
 
 usage() {
 	cat <<EOF
-usage: mkinitfs [-hkKLl] [-b basedir] [-c configfile] [-F features] [-f fstab]
+usage: mkinitfs [-hkKLln] [-b basedir] [-c configfile] [-F features] [-f fstab]
 		[-i initfile ] [-o outfile] [-t tempdir] [kernelversion]"
 options:
 	-b  prefix files and kernel modules with basedir
@@ -162,6 +164,7 @@ options:
 	-K  copy also host keys to initramfs
 	-l  only list files that would have been used
 	-L  list available features
+	-n  don't include kernel modules or firmware
 	-o  set another outfile
 	-q  Quiet mode
 	-t  use tempdir when creating initramfs image
@@ -173,7 +176,7 @@ EOF
 # main

-while getopts "b:c:f:F:hi:kKLlo:qt:" opt; do
+while getopts "b:c:f:F:hi:kKLlno:qt:" opt; do
 	case "$opt" in
 		b) basedir="$OPTARG";;
 		c) config="$OPTARG";;
@@ -185,6 +188,7 @@ while getopts "b:c:f:F:hi:kKLlo:qt:" opt; do
 		K) hostkeys=1;;
 		L) list_features=1;;
 		l) list_sources=1;;
+		n) nokernel=1;;
 		o) outfile="$OPTARG";;
 		q) quiet=1;;
 		t) tmpdir="$OPTARG";;
@@ -210,18 +214,22 @@ basedir="${basedir%/}/"
 [ "${basedir}" = "${basedir#/}" ] && basedir="${PWD}/${basedir}"

-[ -n "$1" ] && kernel="$1"
-[ -z "$kernel" ] && kernel=$(uname -r)
-kerneldir="${basedir}lib/modules/$kernel"
+if [ -z "$nokernel" ]; then
+	[ -n "$1" ] && kernel="$1"
+	[ -z "$kernel" ] && kernel=$(uname -r)
+	kerneldir="${basedir}lib/modules/$kernel"
 
-kflavor=${kernel##*-}
-[ "$kflavor" = "$kernel" ] && kflavor=vanilla
+	kflavor=${kernel##*-}
+	[ "$kflavor" = "$kernel" ] && kflavor=vanilla
+else
+	kflavor=generic
+fi
 
 if [ -z "$outfile" ]; then
 	outfile="${basedir}boot/initramfs-${kflavor}"
 fi
 
-if [ ! -d "$kerneldir" ]; then
+if [ -z "$nokernel"] && [ ! -d "$kerneldir" ]; then
 	echo "$kerneldir does not exist or is not a directory"
 	exit 1
 fi
-- 
2.10.0

---
Unsubscribe:  [email-masked]
Help:         [email-masked]
---

---

From: Shiz <[email-masked]>
Date: Thu, 17 Nov 2016 02:52:51 +0100

The kernel passes arguments from /proc/cmdline as a single string like
foo=bar baz="something with spaces". In the latter case, with the added
single quotes the actual value of ${KOPT_baz} would contain these quotes
as well, which is not the intention.
---
 initramfs-init.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/initramfs-init.in b/initramfs-init.in
index 78bcbe4..9aa1d3f 100755
--- a/initramfs-init.in
+++ b/initramfs-init.in
@@ -279,7 +279,7 @@ for opt; do
 
 	for i in $myopts; do
 		case "$opt" in
-		$i=*)	eval "KOPT_${i}='${opt#*=}'";;
+		$i=*)	eval "KOPT_${i}=${opt#*=}";;
 		$i)	eval "KOPT_${i}=yes";;
 		no$i)	eval "KOPT_${i}=no";;
 		esac
-- 
2.10.0

---

---

From: Przemysław Pawełczyk <[email-masked]>
Date: Wed, 30 Nov 2016 00:17:58 +0100

---- On Thu, 17 Nov 2016 02:52:51 +0100 Shiz <[email-masked]> wrote ---- 
 > as well, which is not the intention. 

Description is a bit wrong.  Kernel provides arguments used during boot
via /proc/cmdline as a single text line.

The problem is that

    set -- $(cat /proc/cmdline)

doesn't do what you think it does (or at least what your patch assumes).
There is even a comment earlier:

    # read the kernel options. we need surve things like:
    #  acpi_osi="!Windows 2006" xen-pciback.hide=(01:00.0)

to hint that it's not an easy matter.
If you'd perform in POSIX sh:

    ./script acpi_osi="!Windows 2006" xen-pciback.hide='(01:00.0)'

Then $1 would be equal to 'acpi_osi=!Windows 2006'
and $2 would be queal to 'xen-pciback.hide=(01:00.0)'
(single-quoting around value of xen-pciback.hide in ./script call was
necessary to avoid interpreting of parenthesis and raising error).
Both without the single-quotes, of course.
(Actually in bash you'd have to change double-quoting in first argument
to single-quoting too, because otherwise ! is interpreted and you get
error.)

But if you do:

    echo 'acpi_osi="!Windows 2006" xen-pciback.hide=(01:00.0)' >cmdline
    ./script $(cat cmdline)

then:

$1 = 'acpi_osi="!Windows'
$2 = '2006"'
$3 = 'xen-pciback.hide=(01:00.0)'
All without the single-quotes, of course.

so it's not what we want.
We don't have information about real argument boundaries.

What we need is to reassemble arguments. Something akin to recreating
"$@" from $*.  It's quite hard to do in POSIX sh. I spend some time
yesterday and I came up with:
https://gist.github.com/przemoc/168ecd5a263e1e498ee6d2ee4278e4ae

It's not perfect, it's not a beauty, but I think it's very good
approximation of what we need and it works (it handles many cases, but
obviously not all of them - doing it in shell is more than cumbersome).
The code (w/o show current arguments part) should be put after
set -- $(cat /proc/cmdline), and then your patch should be reverted
(i.e. single-quoting in eval KOPT_${i} assignment should be restored).

I hoped to provide such patch, but it's already so late, that I won't do
it today and I am merely informing about the problem.
I'm also starting to doubt that ncopa will happily include additional
150 lines in initramfs-init.in, even if they work, so it may be better
to get some kind of half-ACK at least before preparing the patch.

Regards,
Przemek

---

---

From: Shiz <[email-masked]>
Date: Thu, 17 Nov 2016 02:52:52 +0100

This fixes various issues in later boot procedures if relying on localhost
to work properly and if no further networking configuration is done.
---
 initramfs-init.in | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/initramfs-init.in b/initramfs-init.in
index 9aa1d3f..b8ce2f1 100755
--- a/initramfs-init.in
+++ b/initramfs-init.in
@@ -313,6 +313,9 @@ if [ "$KOPT_dma" = no ]; then
 	modprobe libata dma=0
 fi
 
+# setup loopback interface
+ip_set lo 127.0.0.1 255.0.0.0
+
 # The following values are supported:
 #   alpine_repo=auto         -- default, search for .boot_repository
 #   alpine_repo=http://...   -- network repository
-- 
2.10.0

---

---

From: Natanael Copa <[email-masked]>
Date: Mon, 28 Nov 2016 17:33:52 -0200

On Thu, 17 Nov 2016 02:52:52 +0100

> to work properly and if no further networking configuration is done.

Hi,

I'm just curious what those issues are?

I know that if you for example use /etc/init.d/dhcpcd instead
of /etc/init.d/networking then you'll have your lo interface
unconfigured. (which I work around by having lo only in networking and
enable both services)

I also think that you may have the same issues in LXC for example,
unless you explicitly configure lo during boot. and LXC does not use
initramfs at all.

So I wonder if this is the correct place to fix it.

-nc

---

---

From: Shiz <[email-masked]>
Date: Mon, 28 Nov 2016 21:17:15 +0100

> On 28 Nov 2016, at 20:33, Natanael Copa <[email-masked]> wrote:
> 

Hi,

You’re probably correct - I was lead to that approach perhaps more
because the initramfs already does configure the eth0 interface correctly.
Adding /etc/network/interfaces and the networking service is probably
the better approach, yes. Feel free to disregard this patch.

I do wonder to what extent applications rely on lo to work without
explicitly needing networking as such, but if that hasn’t been an issue
until now, no reason to further dig into it.

- Shiz

---