Openembedded Core Discussions
 help / color / mirror / Atom feed
* [PATCH] core-image-minimal-initramfs: prepare initramfs for NFS boot
@ 2018-03-12 14:33 Oleksii Konoplitskyi
  2018-03-12 16:59 ` André Draszik
  0 siblings, 1 reply; 6+ messages in thread
From: Oleksii Konoplitskyi @ 2018-03-12 14:33 UTC (permalink / raw)
  To: openembedded-core; +Cc: Andrii Bordunov, xe-linux-external

It helps to boot device by mounting rootfs via NFS when network
drivers are built as modules.
We include modules in core-image-minimal-initramfs image
and start kernel with specifying custom rdinit in cmdline:
   rdinit=/init-nfs.sh

NFS and IP parameters should be passed to kernel as usual.
For example:
   ip=192.168.0.11::192.168.0.1:255.255.255.0:linux:eth0:off
   nfsroot=192.168.0.10:/exported_nfs,nfsvers=3,tcp
   root=/dev/nfs rw loglevel=7 rdinit=/init-nfs.sh

To use this initramfs, one could put the following
to conf/local.conf:
   INITRAMFS_LOAD_KERNEL_MODULES = "kernel-module-igb"
   INITRAMFS_IMAGE_BUNDLE = "1"
   INITRAMFS_IMAGE = "core-image-minimal-initramfs"

INITRAMFS_LOAD_KERNEL_MODULES is a space-separated list of
modules that will be added to initramfs.

Signed-off-by: Andrii Bordunov <aborduno@cisco.com>
Signed-off-by: Oleksii Konoplitskyi <okonopli@cisco.com>
---
 .../images/core-image-minimal-initramfs.bb         |   2 +-
 meta/recipes-core/initrdscripts/files/init-nfs.sh  | 108 +++++++++++++++++++++
 .../initrdscripts/initramfs-nfs-boot_1.0.bb        |  14 +++
 3 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 meta/recipes-core/initrdscripts/files/init-nfs.sh
 create mode 100644 meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb

diff --git a/meta/recipes-core/images/core-image-minimal-initramfs.bb b/meta/recipes-core/images/core-image-minimal-initramfs.bb
index c446e87..bf794bf 100644
--- a/meta/recipes-core/images/core-image-minimal-initramfs.bb
+++ b/meta/recipes-core/images/core-image-minimal-initramfs.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Small image capable of booting a device. The kernel includes \
 the Minimal RAM-based Initial Root Filesystem (initramfs), which finds the \
 first 'init' program more efficiently."
 
-PACKAGE_INSTALL = "initramfs-live-boot initramfs-live-install initramfs-live-install-efi ${VIRTUAL-RUNTIME_base-utils} udev base-passwd ${ROOTFS_BOOTSTRAP_INSTALL}"
+PACKAGE_INSTALL = "initramfs-live-boot initramfs-live-install initramfs-live-install-efi ${VIRTUAL-RUNTIME_base-utils} udev base-passwd ${ROOTFS_BOOTSTRAP_INSTALL} initramfs-nfs-boot"
 
 # Do not pollute the initrd image with rootfs features
 IMAGE_FEATURES = ""
diff --git a/meta/recipes-core/initrdscripts/files/init-nfs.sh b/meta/recipes-core/initrdscripts/files/init-nfs.sh
new file mode 100644
index 0000000..31a55ec
--- /dev/null
+++ b/meta/recipes-core/initrdscripts/files/init-nfs.sh
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+CONSOLE="/dev/console"
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+ROOT_MOUNT="/rootfs"
+
+fatal()
+{
+	echo $1 >$CONSOLE
+	echo >$CONSOLE
+	exec sh
+}
+
+net_up()
+{
+	[ "$(ifconfig $PARAM_IFNAME | awk '/inet addr/{print substr($2,6)}')" = "$PARAM_IP" ] && return
+	#load all ethernet drivers if network interface is not configured
+	MODULES="$(find /lib/modules/*/kernel/drivers/net/ethernet -name \*.ko | sed -e 's,^.*/,,' -e 's,\.ko$,,')"
+	[ -z "$MODULES" ] && fatal "Ethernet drivers list is emty. Nothing to load."
+	modprobe -a $MODULES
+
+	ifconfig $PARAM_IFNAME $PARAM_IP netmask $PARAM_NETMASK ||
+		fatal "Failed to configure ethernet interface"
+	route add default gw $PARAM_GW ||
+		fatal "Failed to set default gateway"
+}
+
+
+#TODO: IPv6 is not supported yet
+mount_nfs()
+{
+	mkdir $ROOT_MOUNT
+	for i in $(seq 1 10)
+	do
+		mount -t nfs "$PARAM_NFSROOT_PATH" -o nolock,"$PARAM_NFSROOT_OPTS" $ROOT_MOUNT && return
+		sleep 1
+	done
+	fatal "Could not mount rootfs via nfs"
+}
+
+
+early_setup()
+{
+	mkdir -p /proc
+	mkdir -p /sys
+	mount -t proc proc /proc
+	mount -t sysfs sysfs /sys
+	mount -t devtmpfs none /dev
+
+	mkdir -p /run
+	mkdir -p /var/run
+}
+
+
+#TODO: IPv6 is not supported yet
+read_args()
+{
+	[ -z "$CMDLINE" ] && CMDLINE=$(cat /proc/cmdline)
+	for arg in $CMDLINE; do
+		optarg=$(expr "x$arg" : 'x[^=]*=\(.*\)'$)
+		case $arg in
+		ip=*)
+			PARAM_IFNAME=$(echo "$optarg" | cut -d: -f6)
+			PARAM_IP_ALL=$(echo "$optarg" | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}')
+			PARAM_IP=$(echo "$PARAM_IP_ALL" | sed -n 1p)
+			PARAM_GW=$(echo "$PARAM_IP_ALL" | sed -n 2p)
+			PARAM_NETMASK=$(echo "$PARAM_IP_ALL" | sed -n 3p)
+			;;
+		nfsroot=*)
+			PARAM_NFSROOT_PATH=$(echo "$optarg" | cut -d, -f1)
+			PARAM_NFSROOT_OPTS=$(echo "$optarg" | cut -d, -f2-)
+			;;
+		debugshell)
+			DEBUGSHELL=1
+			;;
+		esac
+	done
+}
+
+boot_nfs()
+{
+	touch $ROOT_MOUNT/bin || fatal "Rootfs is not writeable"
+
+	mount -n --move /proc ${ROOT_MOUNT}/proc
+	mount -n --move /sys ${ROOT_MOUNT}/sys
+	mount -n --move /dev ${ROOT_MOUNT}/dev
+
+	cd $ROOT_MOUNT
+
+	# busybox switch_root supports -c option
+	exec switch_root -c /dev/console $ROOT_MOUNT /sbin/init $CMDLINE ||
+		fatal "Couldn't switch_root, dropping to shell"
+}
+
+early_setup
+
+read_args
+
+if [ -n "$DEBUGSHELL" ]; then
+	exec sh
+fi
+
+net_up
+
+mount_nfs
+
+boot_nfs
+
diff --git a/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb b/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb
new file mode 100644
index 0000000..ca4f191
--- /dev/null
+++ b/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb
@@ -0,0 +1,14 @@
+SUMMARY = "Live image init script"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
+RDEPENDS_${PN} = "${@['', d.getVar('INITRAMFS_LOAD_KERNEL_MODULES', True)][d.getVar('INITRAMFS_LOAD_KERNEL_MODULES', True) is not None]}"
+SRC_URI = "file://init-nfs.sh"
+
+S = "${WORKDIR}"
+
+do_install() {
+        install -m 0755 ${WORKDIR}/init-nfs.sh ${D}/init-nfs.sh
+}
+
+FILES_${PN} += " /init-nfs.sh "
+
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] core-image-minimal-initramfs: prepare initramfs for NFS boot
  2018-03-12 14:33 [PATCH] core-image-minimal-initramfs: prepare initramfs for NFS boot Oleksii Konoplitskyi
@ 2018-03-12 16:59 ` André Draszik
  2018-03-16 18:20   ` Oleksii Konoplitskyi
  0 siblings, 1 reply; 6+ messages in thread
From: André Draszik @ 2018-03-12 16:59 UTC (permalink / raw)
  To: openembedded-core

Hi.

It'd be nice if this was part of initramfs-framework instead.

In particular some devices need a bit more than ifconfig & route, e.g.
configuration of SoC internal Ethernet switches.

As it is, this patch is not very generic, whereas if it was integrated with
the initramfs-framework, another module could take care of the driver /
hardware specifics, and this module would just do the actual mounting of the
ROOTFS.

The remaining bits, like mount --move of /proc are also already part of
initramfs-framework.

That way, this new addition would be useful on a wide range of devices.


Cheers,
Andre'

On Mon, 2018-03-12 at 16:33 +0200, Oleksii Konoplitskyi wrote:
> It helps to boot device by mounting rootfs via NFS when network
> drivers are built as modules.
> We include modules in core-image-minimal-initramfs image
> and start kernel with specifying custom rdinit in cmdline:
>    rdinit=/init-nfs.sh
> 
> NFS and IP parameters should be passed to kernel as usual.
> For example:
>    ip=192.168.0.11::192.168.0.1:255.255.255.0:linux:eth0:off
>    nfsroot=192.168.0.10:/exported_nfs,nfsvers=3,tcp
>    root=/dev/nfs rw loglevel=7 rdinit=/init-nfs.sh
> 
> To use this initramfs, one could put the following
> to conf/local.conf:
>    INITRAMFS_LOAD_KERNEL_MODULES = "kernel-module-igb"
>    INITRAMFS_IMAGE_BUNDLE = "1"
>    INITRAMFS_IMAGE = "core-image-minimal-initramfs"
> 
> INITRAMFS_LOAD_KERNEL_MODULES is a space-separated list of
> modules that will be added to initramfs.
> 
> Signed-off-by: Andrii Bordunov <aborduno@cisco.com>
> Signed-off-by: Oleksii Konoplitskyi <okonopli@cisco.com>
> ---
>  .../images/core-image-minimal-initramfs.bb         |   2 +-
>  meta/recipes-core/initrdscripts/files/init-nfs.sh  | 108
> +++++++++++++++++++++
>  .../initrdscripts/initramfs-nfs-boot_1.0.bb        |  14 +++
>  3 files changed, 123 insertions(+), 1 deletion(-)
>  create mode 100644 meta/recipes-core/initrdscripts/files/init-nfs.sh
>  create mode 100644 meta/recipes-core/initrdscripts/initramfs-nfs-
> boot_1.0.bb
> 
> diff --git a/meta/recipes-core/images/core-image-minimal-initramfs.bb
> b/meta/recipes-core/images/core-image-minimal-initramfs.bb
> index c446e87..bf794bf 100644
> --- a/meta/recipes-core/images/core-image-minimal-initramfs.bb
> +++ b/meta/recipes-core/images/core-image-minimal-initramfs.bb
> @@ -3,7 +3,7 @@ DESCRIPTION = "Small image capable of booting a device.
> The kernel includes \
>  the Minimal RAM-based Initial Root Filesystem (initramfs), which finds
> the \
>  first 'init' program more efficiently."
>  
> -PACKAGE_INSTALL = "initramfs-live-boot initramfs-live-install initramfs-
> live-install-efi ${VIRTUAL-RUNTIME_base-utils} udev base-passwd
> ${ROOTFS_BOOTSTRAP_INSTALL}"
> +PACKAGE_INSTALL = "initramfs-live-boot initramfs-live-install initramfs-
> live-install-efi ${VIRTUAL-RUNTIME_base-utils} udev base-passwd
> ${ROOTFS_BOOTSTRAP_INSTALL} initramfs-nfs-boot"
>  
>  # Do not pollute the initrd image with rootfs features
>  IMAGE_FEATURES = ""
> diff --git a/meta/recipes-core/initrdscripts/files/init-nfs.sh
> b/meta/recipes-core/initrdscripts/files/init-nfs.sh
> new file mode 100644
> index 0000000..31a55ec
> --- /dev/null
> +++ b/meta/recipes-core/initrdscripts/files/init-nfs.sh
> @@ -0,0 +1,108 @@
> +#!/bin/sh
> +
> +CONSOLE="/dev/console"
> +PATH=/sbin:/bin:/usr/sbin:/usr/bin
> +ROOT_MOUNT="/rootfs"
> +
> +fatal()
> +{
> +	echo $1 >$CONSOLE
> +	echo >$CONSOLE
> +	exec sh
> +}
> +
> +net_up()
> +{
> +	[ "$(ifconfig $PARAM_IFNAME | awk '/inet addr/{print
> substr($2,6)}')" = "$PARAM_IP" ] && return
> +	#load all ethernet drivers if network interface is not configured
> +	MODULES="$(find /lib/modules/*/kernel/drivers/net/ethernet -name
> \*.ko | sed -e 's,^.*/,,' -e 's,\.ko$,,')"
> +	[ -z "$MODULES" ] && fatal "Ethernet drivers list is emty.
> Nothing to load."
> +	modprobe -a $MODULES
> +
> +	ifconfig $PARAM_IFNAME $PARAM_IP netmask $PARAM_NETMASK ||
> +		fatal "Failed to configure ethernet interface"
> +	route add default gw $PARAM_GW ||
> +		fatal "Failed to set default gateway"
> +}
> +
> +
> +#TODO: IPv6 is not supported yet
> +mount_nfs()
> +{
> +	mkdir $ROOT_MOUNT
> +	for i in $(seq 1 10)
> +	do
> +		mount -t nfs "$PARAM_NFSROOT_PATH" -o
> nolock,"$PARAM_NFSROOT_OPTS" $ROOT_MOUNT && return
> +		sleep 1
> +	done
> +	fatal "Could not mount rootfs via nfs"
> +}
> +
> +
> +early_setup()
> +{
> +	mkdir -p /proc
> +	mkdir -p /sys
> +	mount -t proc proc /proc
> +	mount -t sysfs sysfs /sys
> +	mount -t devtmpfs none /dev
> +
> +	mkdir -p /run
> +	mkdir -p /var/run
> +}
> +
> +
> +#TODO: IPv6 is not supported yet
> +read_args()
> +{
> +	[ -z "$CMDLINE" ] && CMDLINE=$(cat /proc/cmdline)
> +	for arg in $CMDLINE; do
> +		optarg=$(expr "x$arg" : 'x[^=]*=\(.*\)'$)
> +		case $arg in
> +		ip=*)
> +			PARAM_IFNAME=$(echo "$optarg" | cut -d: -f6)
> +			PARAM_IP_ALL=$(echo "$optarg" | grep -Eo '([0-
> 9]{1,3}\.){3}[0-9]{1,3}')
> +			PARAM_IP=$(echo "$PARAM_IP_ALL" | sed -n 1p)
> +			PARAM_GW=$(echo "$PARAM_IP_ALL" | sed -n 2p)
> +			PARAM_NETMASK=$(echo "$PARAM_IP_ALL" | sed -n 3p)
> +			;;
> +		nfsroot=*)
> +			PARAM_NFSROOT_PATH=$(echo "$optarg" | cut -d,
> -f1)
> +			PARAM_NFSROOT_OPTS=$(echo "$optarg" | cut -d,
> -f2-)
> +			;;
> +		debugshell)
> +			DEBUGSHELL=1
> +			;;
> +		esac
> +	done
> +}
> +
> +boot_nfs()
> +{
> +	touch $ROOT_MOUNT/bin || fatal "Rootfs is not writeable"
> +
> +	mount -n --move /proc ${ROOT_MOUNT}/proc
> +	mount -n --move /sys ${ROOT_MOUNT}/sys
> +	mount -n --move /dev ${ROOT_MOUNT}/dev
> +
> +	cd $ROOT_MOUNT
> +
> +	# busybox switch_root supports -c option
> +	exec switch_root -c /dev/console $ROOT_MOUNT /sbin/init $CMDLINE
> ||
> +		fatal "Couldn't switch_root, dropping to shell"
> +}
> +
> +early_setup
> +
> +read_args
> +
> +if [ -n "$DEBUGSHELL" ]; then
> +	exec sh
> +fi
> +
> +net_up
> +
> +mount_nfs
> +
> +boot_nfs
> +
> diff --git a/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb
> b/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb
> new file mode 100644
> index 0000000..ca4f191
> --- /dev/null
> +++ b/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb
> @@ -0,0 +1,14 @@
> +SUMMARY = "Live image init script"
> +LICENSE = "MIT"
> +LIC_FILES_CHKSUM =
> "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
> +RDEPENDS_${PN} = "${@['', d.getVar('INITRAMFS_LOAD_KERNEL_MODULES',
> True)][d.getVar('INITRAMFS_LOAD_KERNEL_MODULES', True) is not None]}"
> +SRC_URI = "file://init-nfs.sh"
> +
> +S = "${WORKDIR}"
> +
> +do_install() {
> +        install -m 0755 ${WORKDIR}/init-nfs.sh ${D}/init-nfs.sh
> +}
> +
> +FILES_${PN} += " /init-nfs.sh "
> +
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] core-image-minimal-initramfs: prepare initramfs for NFS boot
  2018-03-12 16:59 ` André Draszik
@ 2018-03-16 18:20   ` Oleksii Konoplitskyi
  2018-04-03 14:23     ` André Draszik
  0 siblings, 1 reply; 6+ messages in thread
From: Oleksii Konoplitskyi @ 2018-03-16 18:20 UTC (permalink / raw)
  To: André Draszik, openembedded-core, xe-linux-external

Hi Andre,

I could build initramfs using initramfs-framework. My device was booted 
successfully.

I created my own recipe to build initramfs image and added one more 
module nfsrootfs to initramfs-framework. Also initramfs-framework*.bb 
was updated.
Module "nfsrootfs" has content:


nfsrootfs_enabled() {
     [ -z ${bootparam_nfsroot+x} ] && return 1
     return 0
}

nfsrootfs_run() {
     MODULES="$(find /lib/modules/*/kernel/drivers/net/ethernet -name 
\*.ko | sed -e 's,^.*/,,' -e 's,\.ko$,,')"
     modprobe -a $MODULES

     ifname=$(echo $bootparam_ip | cut -d ':' -f 6)
     ipaddr=$(echo $bootparam_ip | cut -d ':' -f 1)
     netmask=$(echo $bootparam_ip | cut -d ':' -f 4)
     gateway=$(echo $bootparam_ip | cut -d ':' -f 3)

     ifconfig $ifname $ipaddr netmask $netmask
     route add default gw $gateway

     nfs_mount_point=$(echo $bootparam_nfsroot | cut -d ',' -f 1)
     nfs_mount_params=$(echo $bootparam_nfsroot | cut -d ',' -f 2)

     mount -t nfs ${nfs_mount_point} -o nolock,${nfs_server_params} 
$ROOTFS_DIR
}


This modules does not support ipv6 and dhcp configuration.

Taking into account your recommendations, module should have the next 
content:

nfsrootfs_enabled() {
     [ -z ${bootparam_nfsroot+x} ] && return 1
     return 0
}

nfsrootfs_run() {
     nfs_mount_point=$(echo $bootparam_nfsroot | cut -d ',' -f 1)
     nfs_mount_params=$(echo $bootparam_nfsroot | cut -d ',' -f 2)

     mount -t nfs ${nfs_mount_point} -o nolock,${nfs_server_params} 
$ROOTFS_DIR
}

What module is responsible for network configuration and network driver 
loading?
Should it be separate custom module in initramfs-framework not related 
to upstream?

Best regards,
Oleksii

On 12.03.18 18:59, André Draszik wrote:
> Hi.
>
> It'd be nice if this was part of initramfs-framework instead.
>
> In particular some devices need a bit more than ifconfig & route, e.g.
> configuration of SoC internal Ethernet switches.
>
> As it is, this patch is not very generic, whereas if it was integrated with
> the initramfs-framework, another module could take care of the driver /
> hardware specifics, and this module would just do the actual mounting of the
> ROOTFS.
>
> The remaining bits, like mount --move of /proc are also already part of
> initramfs-framework.
>
> That way, this new addition would be useful on a wide range of devices.
>
>
> Cheers,
> Andre'
>
> On Mon, 2018-03-12 at 16:33 +0200, Oleksii Konoplitskyi wrote:
>> It helps to boot device by mounting rootfs via NFS when network
>> drivers are built as modules.
>> We include modules in core-image-minimal-initramfs image
>> and start kernel with specifying custom rdinit in cmdline:
>>     rdinit=/init-nfs.sh
>>
>> NFS and IP parameters should be passed to kernel as usual.
>> For example:
>>     ip=192.168.0.11::192.168.0.1:255.255.255.0:linux:eth0:off
>>     nfsroot=192.168.0.10:/exported_nfs,nfsvers=3,tcp
>>     root=/dev/nfs rw loglevel=7 rdinit=/init-nfs.sh
>>
>> To use this initramfs, one could put the following
>> to conf/local.conf:
>>     INITRAMFS_LOAD_KERNEL_MODULES = "kernel-module-igb"
>>     INITRAMFS_IMAGE_BUNDLE = "1"
>>     INITRAMFS_IMAGE = "core-image-minimal-initramfs"
>>
>> INITRAMFS_LOAD_KERNEL_MODULES is a space-separated list of
>> modules that will be added to initramfs.
>>
>> Signed-off-by: Andrii Bordunov <aborduno@cisco.com>
>> Signed-off-by: Oleksii Konoplitskyi <okonopli@cisco.com>
>> ---
>>   .../images/core-image-minimal-initramfs.bb         |   2 +-
>>   meta/recipes-core/initrdscripts/files/init-nfs.sh  | 108
>> +++++++++++++++++++++
>>   .../initrdscripts/initramfs-nfs-boot_1.0.bb        |  14 +++
>>   3 files changed, 123 insertions(+), 1 deletion(-)
>>   create mode 100644 meta/recipes-core/initrdscripts/files/init-nfs.sh
>>   create mode 100644 meta/recipes-core/initrdscripts/initramfs-nfs-
>> boot_1.0.bb
>>
>> diff --git a/meta/recipes-core/images/core-image-minimal-initramfs.bb
>> b/meta/recipes-core/images/core-image-minimal-initramfs.bb
>> index c446e87..bf794bf 100644
>> --- a/meta/recipes-core/images/core-image-minimal-initramfs.bb
>> +++ b/meta/recipes-core/images/core-image-minimal-initramfs.bb
>> @@ -3,7 +3,7 @@ DESCRIPTION = "Small image capable of booting a device.
>> The kernel includes \
>>   the Minimal RAM-based Initial Root Filesystem (initramfs), which finds
>> the \
>>   first 'init' program more efficiently."
>>   
>> -PACKAGE_INSTALL = "initramfs-live-boot initramfs-live-install initramfs-
>> live-install-efi ${VIRTUAL-RUNTIME_base-utils} udev base-passwd
>> ${ROOTFS_BOOTSTRAP_INSTALL}"
>> +PACKAGE_INSTALL = "initramfs-live-boot initramfs-live-install initramfs-
>> live-install-efi ${VIRTUAL-RUNTIME_base-utils} udev base-passwd
>> ${ROOTFS_BOOTSTRAP_INSTALL} initramfs-nfs-boot"
>>   
>>   # Do not pollute the initrd image with rootfs features
>>   IMAGE_FEATURES = ""
>> diff --git a/meta/recipes-core/initrdscripts/files/init-nfs.sh
>> b/meta/recipes-core/initrdscripts/files/init-nfs.sh
>> new file mode 100644
>> index 0000000..31a55ec
>> --- /dev/null
>> +++ b/meta/recipes-core/initrdscripts/files/init-nfs.sh
>> @@ -0,0 +1,108 @@
>> +#!/bin/sh
>> +
>> +CONSOLE="/dev/console"
>> +PATH=/sbin:/bin:/usr/sbin:/usr/bin
>> +ROOT_MOUNT="/rootfs"
>> +
>> +fatal()
>> +{
>> +	echo $1 >$CONSOLE
>> +	echo >$CONSOLE
>> +	exec sh
>> +}
>> +
>> +net_up()
>> +{
>> +	[ "$(ifconfig $PARAM_IFNAME | awk '/inet addr/{print
>> substr($2,6)}')" = "$PARAM_IP" ] && return
>> +	#load all ethernet drivers if network interface is not configured
>> +	MODULES="$(find /lib/modules/*/kernel/drivers/net/ethernet -name
>> \*.ko | sed -e 's,^.*/,,' -e 's,\.ko$,,')"
>> +	[ -z "$MODULES" ] && fatal "Ethernet drivers list is emty.
>> Nothing to load."
>> +	modprobe -a $MODULES
>> +
>> +	ifconfig $PARAM_IFNAME $PARAM_IP netmask $PARAM_NETMASK ||
>> +		fatal "Failed to configure ethernet interface"
>> +	route add default gw $PARAM_GW ||
>> +		fatal "Failed to set default gateway"
>> +}
>> +
>> +
>> +#TODO: IPv6 is not supported yet
>> +mount_nfs()
>> +{
>> +	mkdir $ROOT_MOUNT
>> +	for i in $(seq 1 10)
>> +	do
>> +		mount -t nfs "$PARAM_NFSROOT_PATH" -o
>> nolock,"$PARAM_NFSROOT_OPTS" $ROOT_MOUNT && return
>> +		sleep 1
>> +	done
>> +	fatal "Could not mount rootfs via nfs"
>> +}
>> +
>> +
>> +early_setup()
>> +{
>> +	mkdir -p /proc
>> +	mkdir -p /sys
>> +	mount -t proc proc /proc
>> +	mount -t sysfs sysfs /sys
>> +	mount -t devtmpfs none /dev
>> +
>> +	mkdir -p /run
>> +	mkdir -p /var/run
>> +}
>> +
>> +
>> +#TODO: IPv6 is not supported yet
>> +read_args()
>> +{
>> +	[ -z "$CMDLINE" ] && CMDLINE=$(cat /proc/cmdline)
>> +	for arg in $CMDLINE; do
>> +		optarg=$(expr "x$arg" : 'x[^=]*=\(.*\)'$)
>> +		case $arg in
>> +		ip=*)
>> +			PARAM_IFNAME=$(echo "$optarg" | cut -d: -f6)
>> +			PARAM_IP_ALL=$(echo "$optarg" | grep -Eo '([0-
>> 9]{1,3}\.){3}[0-9]{1,3}')
>> +			PARAM_IP=$(echo "$PARAM_IP_ALL" | sed -n 1p)
>> +			PARAM_GW=$(echo "$PARAM_IP_ALL" | sed -n 2p)
>> +			PARAM_NETMASK=$(echo "$PARAM_IP_ALL" | sed -n 3p)
>> +			;;
>> +		nfsroot=*)
>> +			PARAM_NFSROOT_PATH=$(echo "$optarg" | cut -d,
>> -f1)
>> +			PARAM_NFSROOT_OPTS=$(echo "$optarg" | cut -d,
>> -f2-)
>> +			;;
>> +		debugshell)
>> +			DEBUGSHELL=1
>> +			;;
>> +		esac
>> +	done
>> +}
>> +
>> +boot_nfs()
>> +{
>> +	touch $ROOT_MOUNT/bin || fatal "Rootfs is not writeable"
>> +
>> +	mount -n --move /proc ${ROOT_MOUNT}/proc
>> +	mount -n --move /sys ${ROOT_MOUNT}/sys
>> +	mount -n --move /dev ${ROOT_MOUNT}/dev
>> +
>> +	cd $ROOT_MOUNT
>> +
>> +	# busybox switch_root supports -c option
>> +	exec switch_root -c /dev/console $ROOT_MOUNT /sbin/init $CMDLINE
>> ||
>> +		fatal "Couldn't switch_root, dropping to shell"
>> +}
>> +
>> +early_setup
>> +
>> +read_args
>> +
>> +if [ -n "$DEBUGSHELL" ]; then
>> +	exec sh
>> +fi
>> +
>> +net_up
>> +
>> +mount_nfs
>> +
>> +boot_nfs
>> +
>> diff --git a/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb
>> b/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb
>> new file mode 100644
>> index 0000000..ca4f191
>> --- /dev/null
>> +++ b/meta/recipes-core/initrdscripts/initramfs-nfs-boot_1.0.bb
>> @@ -0,0 +1,14 @@
>> +SUMMARY = "Live image init script"
>> +LICENSE = "MIT"
>> +LIC_FILES_CHKSUM =
>> "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
>> +RDEPENDS_${PN} = "${@['', d.getVar('INITRAMFS_LOAD_KERNEL_MODULES',
>> True)][d.getVar('INITRAMFS_LOAD_KERNEL_MODULES', True) is not None]}"
>> +SRC_URI = "file://init-nfs.sh"
>> +
>> +S = "${WORKDIR}"
>> +
>> +do_install() {
>> +        install -m 0755 ${WORKDIR}/init-nfs.sh ${D}/init-nfs.sh
>> +}
>> +
>> +FILES_${PN} += " /init-nfs.sh "
>> +
>> -- 
>> 2.7.4
>>



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] core-image-minimal-initramfs: prepare initramfs for NFS boot
  2018-03-16 18:20   ` Oleksii Konoplitskyi
@ 2018-04-03 14:23     ` André Draszik
  2018-04-18  9:55       ` Oleksii Konoplitskyi
  2018-04-18  9:57       ` Oleksii Konoplitskyi
  0 siblings, 2 replies; 6+ messages in thread
From: André Draszik @ 2018-04-03 14:23 UTC (permalink / raw)
  To: Oleksii Konoplitskyi, openembedded-core, xe-linux-external

Thanks!

On Fri, 2018-03-16 at 20:20 +0200, Oleksii Konoplitskyi wrote:
> Taking into account your recommendations, module should have the next 
> content:
> 
> nfsrootfs_enabled() {
>      [ -z ${bootparam_nfsroot+x} ] && return 1
>      return 0
> }
> 
> nfsrootfs_run() {
>      nfs_mount_point=$(echo $bootparam_nfsroot | cut -d ',' -f 1)
>      nfs_mount_params=$(echo $bootparam_nfsroot | cut -d ',' -f 2)
> 
>      mount -t nfs ${nfs_mount_point} -o nolock,${nfs_server_params} 
> $ROOTFS_DIR
> }

Actually, this is missing various things, according to
linux/Documentation/filesystems/nfs/nfsroot.txt

nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]

* The server-ip is optional (and would be taken from the ip= option in
  that case)
* there can be more than one nfs-option (which is probably more important
  to fix)
* it ignores the 'ro' or rootflags=ro option

Maybe something like this (completely untested):

nfsrootfs_run() {
    local nfs_opts
    local location
    local flags

    nfs_opts=""
    if [ "${bootparam_nfsroot#*,}" != "${bootparam_nfsroot}" ] ; then
        nfs_opts="-o ${bootparam_nfsroot#*,}"
    fi
    location="${bootparam_nfsroot%%,*}"
    if [ "${location#*:}" = "${location}" ]; then
        # server-ip not given
        location=${ROOTSERVER}:${location}
    fi

    flags="-o nolock"
    if [ -n "$bootparam_ro" ] && ! echo "$bootparam_rootflags" | grep -w -q "ro"; then
        if [  -n "$bootparam_rootflags" ]; then
            bootparam_rootflags="$bootparam_rootflags,"
        fi
        bootparam_rootflags="${bootparam_rootflags}ro"
    fi
    if [ -n "$bootparam_rootflags" ]; then
        flags="$flags -o$bootparam_rootflags"
    fi

    mount -t nfs ${flags} ${nfs_opts} ${location} ${ROOTFS_DIR}
}

? Just need to get at $ROOTSERVER now, or at least issue a warning that it
should be given on the command line.


> What module is responsible for network configuration and network driver 
> loading?

I'd say IP should be separate, as you can then also easily add DHCP or
zeroconf. It's not really related to nfsroot (except for the ROOTSERVER
bit).
Network driver loading should definitely be a machine specific thing...

> Should it be separate custom module in initramfs-framework not related 
> to upstream?
> 
> Best regards,
> Oleksii


Cheers,
Andre'



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] core-image-minimal-initramfs: prepare initramfs for NFS boot
  2018-04-03 14:23     ` André Draszik
@ 2018-04-18  9:55       ` Oleksii Konoplitskyi
  2018-04-18  9:57       ` Oleksii Konoplitskyi
  1 sibling, 0 replies; 6+ messages in thread
From: Oleksii Konoplitskyi @ 2018-04-18  9:55 UTC (permalink / raw)
  To: André Draszik, openembedded-core, xe-linux-external

Hi Andre,

I could boot my device using your code (+ parsing nfs server ip address 
from ip option):

nfsrootfs_run() {
     local nfs_opts
     local location
     local flags
     local server_ip

     nfs_opts=""
     if [ "${bootparam_nfsroot#*,}" != "${bootparam_nfsroot}" ]; then
         nfs_opts="-o ${bootparam_nfsroot#*,}"
     fi

     location="${bootparam_nfsroot%%,*}"
     if [ "${location#*:}" = "${location}" ]; then
         # server-ip is not given. Get server ip from ip option
         server_ip=""
         if [ "${bootparam_ip#*:}" != "${bootparam_ip}" ]; then
             server_ip=$(echo "$bootparam_ip" | cut -d: -f2)
         fi

         if [ -z "$server_ip" ]; then
             fatal "Server IP is not set. Update ip or nfsroot options."
         fi
         location=${server_ip}:${location}
     fi

     flags="-o nolock"
     if [ -n "$bootparam_ro" ] && ! echo "$bootparam_rootflags" | grep 
-w -q "ro"; then
         if [  -n "$bootparam_rootflags" ]; then
             bootparam_rootflags="$bootparam_rootflags,"
         fi
         bootparam_rootflags="${bootparam_rootflags}ro"
     fi
     if [ -n "$bootparam_rootflags" ]; then
         flags="$flags -o$bootparam_rootflags"
     fi

     mount -t nfs ${flags} ${nfs_opts} ${location} ${ROOTFS_DIR}
}

Should module fail if ip is set to dhcp (or off)?

Should we mount rootfs via nfs if "nfsroot" option is not set?

Best regards,
Oleksii


On 03.04.18 17:23, André Draszik wrote:
> Thanks!
>
> On Fri, 2018-03-16 at 20:20 +0200, Oleksii Konoplitskyi wrote:
>> Taking into account your recommendations, module should have the next
>> content:
>>
>> nfsrootfs_enabled() {
>>       [ -z ${bootparam_nfsroot+x} ] && return 1
>>       return 0
>> }
>>
>> nfsrootfs_run() {
>>       nfs_mount_point=$(echo $bootparam_nfsroot | cut -d ',' -f 1)
>>       nfs_mount_params=$(echo $bootparam_nfsroot | cut -d ',' -f 2)
>>
>>       mount -t nfs ${nfs_mount_point} -o nolock,${nfs_server_params}
>> $ROOTFS_DIR
>> }
> Actually, this is missing various things, according to
> linux/Documentation/filesystems/nfs/nfsroot.txt
>
> nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
>
> * The server-ip is optional (and would be taken from the ip= option in
>    that case)
> * there can be more than one nfs-option (which is probably more important
>    to fix)
> * it ignores the 'ro' or rootflags=ro option
>
> Maybe something like this (completely untested):
>
> nfsrootfs_run() {
>      local nfs_opts
>      local location
>      local flags
>
>      nfs_opts=""
>      if [ "${bootparam_nfsroot#*,}" != "${bootparam_nfsroot}" ] ; then
>          nfs_opts="-o ${bootparam_nfsroot#*,}"
>      fi
>      location="${bootparam_nfsroot%%,*}"
>      if [ "${location#*:}" = "${location}" ]; then
>          # server-ip not given
>          location=${ROOTSERVER}:${location}
>      fi
>
>      flags="-o nolock"
>      if [ -n "$bootparam_ro" ] && ! echo "$bootparam_rootflags" | grep -w -q "ro"; then
>          if [  -n "$bootparam_rootflags" ]; then
>              bootparam_rootflags="$bootparam_rootflags,"
>          fi
>          bootparam_rootflags="${bootparam_rootflags}ro"
>      fi
>      if [ -n "$bootparam_rootflags" ]; then
>          flags="$flags -o$bootparam_rootflags"
>      fi
>
>      mount -t nfs ${flags} ${nfs_opts} ${location} ${ROOTFS_DIR}
> }
>
> ? Just need to get at $ROOTSERVER now, or at least issue a warning that it
> should be given on the command line.
>
>
>> What module is responsible for network configuration and network driver
>> loading?
> I'd say IP should be separate, as you can then also easily add DHCP or
> zeroconf. It's not really related to nfsroot (except for the ROOTSERVER
> bit).
> Network driver loading should definitely be a machine specific thing...
>
>> Should it be separate custom module in initramfs-framework not related
>> to upstream?
>>
>> Best regards,
>> Oleksii
>
> Cheers,
> Andre'
>



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] core-image-minimal-initramfs: prepare initramfs for NFS boot
  2018-04-03 14:23     ` André Draszik
  2018-04-18  9:55       ` Oleksii Konoplitskyi
@ 2018-04-18  9:57       ` Oleksii Konoplitskyi
  1 sibling, 0 replies; 6+ messages in thread
From: Oleksii Konoplitskyi @ 2018-04-18  9:57 UTC (permalink / raw)
  To: André Draszik, openembedded-core, xe-linux-external

Hi Andre,

I could boot my device using your code (+ parsing nfs server ip address 
from ip option):

nfsrootfs_run() {
     local nfs_opts
     local location
     local flags
     local server_ip

     nfs_opts=""
     if [ "${bootparam_nfsroot#*,}" != "${bootparam_nfsroot}" ]; then
         nfs_opts="-o ${bootparam_nfsroot#*,}"
     fi

     location="${bootparam_nfsroot%%,*}"
     if [ "${location#*:}" = "${location}" ]; then
         # server-ip is not given. Get server ip from ip option
         server_ip=""
         if [ "${bootparam_ip#*:}" != "${bootparam_ip}" ]; then
             server_ip=$(echo "$bootparam_ip" | cut -d: -f2)
         fi

         if [ -z "$server_ip" ]; then
             fatal "Server IP is not set. Update ip or nfsroot options."
         fi
         location=${server_ip}:${location}
     fi

     flags="-o nolock"
     if [ -n "$bootparam_ro" ] && ! echo "$bootparam_rootflags" | grep 
-w -q "ro"; then
         if [  -n "$bootparam_rootflags" ]; then
             bootparam_rootflags="$bootparam_rootflags,"
         fi
         bootparam_rootflags="${bootparam_rootflags}ro"
     fi
     if [ -n "$bootparam_rootflags" ]; then
         flags="$flags -o$bootparam_rootflags"
     fi

     mount -t nfs ${flags} ${nfs_opts} ${location} ${ROOTFS_DIR}
}

Should module fail if ip is set to dhcp (or off)?

Should we mount rootfs via nfs if "nfsroot" option is not set?

Best regards,
Oleksii


On 03.04.18 17:23, André Draszik wrote:
> Thanks!
>
> On Fri, 2018-03-16 at 20:20 +0200, Oleksii Konoplitskyi wrote:
>> Taking into account your recommendations, module should have the next
>> content:
>>
>> nfsrootfs_enabled() {
>>       [ -z ${bootparam_nfsroot+x} ] && return 1
>>       return 0
>> }
>>
>> nfsrootfs_run() {
>>       nfs_mount_point=$(echo $bootparam_nfsroot | cut -d ',' -f 1)
>>       nfs_mount_params=$(echo $bootparam_nfsroot | cut -d ',' -f 2)
>>
>>       mount -t nfs ${nfs_mount_point} -o nolock,${nfs_server_params}
>> $ROOTFS_DIR
>> }
> Actually, this is missing various things, according to
> linux/Documentation/filesystems/nfs/nfsroot.txt
>
> nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
>
> * The server-ip is optional (and would be taken from the ip= option in
>    that case)
> * there can be more than one nfs-option (which is probably more important
>    to fix)
> * it ignores the 'ro' or rootflags=ro option
>
> Maybe something like this (completely untested):
>
> nfsrootfs_run() {
>      local nfs_opts
>      local location
>      local flags
>
>      nfs_opts=""
>      if [ "${bootparam_nfsroot#*,}" != "${bootparam_nfsroot}" ] ; then
>          nfs_opts="-o ${bootparam_nfsroot#*,}"
>      fi
>      location="${bootparam_nfsroot%%,*}"
>      if [ "${location#*:}" = "${location}" ]; then
>          # server-ip not given
>          location=${ROOTSERVER}:${location}
>      fi
>
>      flags="-o nolock"
>      if [ -n "$bootparam_ro" ] && ! echo "$bootparam_rootflags" | grep -w -q "ro"; then
>          if [  -n "$bootparam_rootflags" ]; then
>              bootparam_rootflags="$bootparam_rootflags,"
>          fi
>          bootparam_rootflags="${bootparam_rootflags}ro"
>      fi
>      if [ -n "$bootparam_rootflags" ]; then
>          flags="$flags -o$bootparam_rootflags"
>      fi
>
>      mount -t nfs ${flags} ${nfs_opts} ${location} ${ROOTFS_DIR}
> }
>
> ? Just need to get at $ROOTSERVER now, or at least issue a warning that it
> should be given on the command line.
>
>
>> What module is responsible for network configuration and network driver
>> loading?
> I'd say IP should be separate, as you can then also easily add DHCP or
> zeroconf. It's not really related to nfsroot (except for the ROOTSERVER
> bit).
> Network driver loading should definitely be a machine specific thing...
>
>> Should it be separate custom module in initramfs-framework not related
>> to upstream?
>>
>> Best regards,
>> Oleksii
>
> Cheers,
> Andre'
>



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-04-18 10:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-12 14:33 [PATCH] core-image-minimal-initramfs: prepare initramfs for NFS boot Oleksii Konoplitskyi
2018-03-12 16:59 ` André Draszik
2018-03-16 18:20   ` Oleksii Konoplitskyi
2018-04-03 14:23     ` André Draszik
2018-04-18  9:55       ` Oleksii Konoplitskyi
2018-04-18  9:57       ` Oleksii Konoplitskyi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox