summaryrefslogtreecommitdiffstats
path: root/meta-phosphor/common/recipes-phosphor
diff options
context:
space:
mode:
authorMilton D. Miller II <miltonm@us.ibm.com>2016-01-20 14:57:54 -0600
committerMilton D. Miller II <miltonm@us.ibm.com>2016-01-28 15:45:20 -0600
commit0e77514678f66cde28a00a7618c9d20c88c92a5a (patch)
tree7cc0284b25a6de5725b6c2137dcb21c5f3e6969c /meta-phosphor/common/recipes-phosphor
parent1af7dcca3b1e9e4904b3a386ccb18b8526da9ba9 (diff)
downloadtalos-openbmc-0e77514678f66cde28a00a7618c9d20c88c92a5a.tar.gz
talos-openbmc-0e77514678f66cde28a00a7618c9d20c88c92a5a.zip
Create obmc-phosphor-initfs startup and shutdown scripts
This recipe holds the key scripts for an initramfs image. Written in sh to run with busybox, these three scripts handle mounting, unmounting, and updating a set of mtd partitions to form a read-write overlay on a read-only compressed base. The init script will mount the base sysfs, proc, and devtmpfs as well as run. It copies the filesystem to run/initramfs to create the shutdown and update environment. It then mounts a base read-only and read-write file system and then an overlay of them combined, then continues with chroot into the overlay and execute the normal /sbin/init. The shutdown script will unmount the remaining nodev and root filesystems from oldroot where systemd-shutdown pivots the old file system, then looks for image- files. If any are found it invokes update otherwise it performs the final reboot, powerdown, or kexec, or halt. The update script will attempt to mount the read/write overlay and preserve selected files and directories based on a whitelist. It then unmounts that fs and writes all image files to their named mtd partition using flashcp, mounts and restores the saved files, and finally unmounts the fs and performs the final reboot, shutdown, kexec, or halt. Signed-off-by: Milton Miller <miltonm@us.ibm.com>
Diffstat (limited to 'meta-phosphor/common/recipes-phosphor')
-rw-r--r--meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-init.sh78
-rw-r--r--meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-shutdown.sh55
-rwxr-xr-xmeta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-update.sh106
-rw-r--r--meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/whitelist8
-rw-r--r--meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/obmc-phosphor-init.bb23
5 files changed, 270 insertions, 0 deletions
diff --git a/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-init.sh b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-init.sh
new file mode 100644
index 000000000..431780a70
--- /dev/null
+++ b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-init.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+rodir=run/initramfs/ro
+rwdir=run/initramfs/rw
+upper=$rwdir/cow
+work=$rwdir/work
+
+cd /
+mkdir -p sys proc dev run
+mount dev dev -tdevtmpfs
+mount sys sys -tsysfs
+mount proc proc -tproc
+if ! grep run proc/mounts
+then
+ mount tmpfs run -t tmpfs -o mode=755,nodev
+fi
+
+mkdir -p $rodir $rwdir
+
+cp -rp init shutdown update whitelist bin sbin usr lib etc var run/initramfs
+
+# To start a interactive shell with job control at this point, run
+# getty 38400 ttyS4
+
+findmtd() {
+ m=$(grep -xl "$1" /sys/class/mtd/*/name)
+ m=${m%/name}
+ m=${m##*/}
+ echo $m
+}
+
+rofs=$(findmtd rofs)
+rwfs=$(findmtd rwfs)
+
+rofst=squashfs
+rwfst=ext4
+
+echo rofs = $rofs $rofst rwfs = $rwfs $rwfst
+
+if grep -w debug-init-sh /proc/cmdline ||
+ ! mount -o rw /dev/mtdblock${rwfs#mtd} $rwdir -t $rwfst
+then
+ echo Please mount the rw file system on $rwdir from this shell
+ while ! sulogin && ! test -f /takeover
+ do
+ echo getty failed, retrying
+ done
+fi
+
+# Touch /takeover in the above getty to become pid 1
+if test -e /takeover
+then
+ export PS1=init#\
+ exec /bin/sh
+fi
+
+mount -o ro /dev/mtdblock${rofs#mtd} $rodir -t $rofst
+
+rm -rf $work
+mkdir -p $upper
+mkdir -p $work
+
+mount -t overlay -o lowerdir=$rodir,upperdir=$upper,workdir=$work cow /root
+
+if ! chroot /root /bin/sh -c exit
+then
+ echo 'chroot test failed; invoking emergency shell.'
+ PS1=rescue#\ sulogin
+fi
+
+for f in sys dev proc run
+do
+ mount --move $f root/$f
+done
+
+# switch_root /root /sbin/init
+exec chroot /root /sbin/init
+
diff --git a/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-shutdown.sh b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-shutdown.sh
new file mode 100644
index 000000000..029cd6556
--- /dev/null
+++ b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-shutdown.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+echo shutdown: "$@"
+
+export PS1=shutdown-sh#\
+# exec bin/sh
+
+if [ ! -e /proc/mounts ]
+then
+ mkdir -p /proc
+ mount proc proc -tproc
+ umount_proc=1
+else
+ umount_proc=
+fi
+
+# remove an empty oldroot, that means we are not invoked from systemd-shutdown
+rmdir /oldroot 2>/dev/null
+
+set -x
+for f in $( awk '/oldroot/ { print $2 }' < /proc/mounts | sort -r )
+do
+ umount $f
+done
+set +x
+
+
+if test -x /update && ls image-* > /dev/null 2>&1
+then
+ exec /update ${1+"$@"}
+fi
+
+echo Remaining mounts:
+cat /proc/mounts
+
+test "umount_proc" && umount /proc && rmdir /proc
+
+
+
+# Execute the command systemd told us to ...
+if test -d /oldroot && test "$1"
+then
+ if test "$1" == kexec
+ then
+ $1 -f -e
+ else
+ $1 -f
+ fi
+fi
+
+
+echo "Execute ${1-reboot} -f if all unounted ok, or exec /init"
+
+export PS1=shutdown-sh#\
+exec /bin/sh
diff --git a/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-update.sh b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-update.sh
new file mode 100755
index 000000000..1122e83fa
--- /dev/null
+++ b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-update.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+echo update: "$@"
+
+export PS1=update-sh#\
+# exec /bin/sh
+
+cd /
+if ! test -r /proc/mounts || ! test -f /proc/mounts
+then
+ mkdir -p /proc
+ mount -t proc proc proc
+fi
+if ! test -d /sys/class
+then
+ mkdir -p /sys
+ mount -t sysfs sys sys
+fi
+if ! test -c /dev/null
+then
+ mkdir -p /dev
+ mount -t devtmpfs dev dev
+fi
+while grep mtd /proc/mounts
+do
+ echo 1>&2 "Error: A mtd device is mounted."
+ sulogin
+ # exec /bin/sh
+done
+
+findmtd() {
+ m=$(grep -xl "$1" /sys/class/mtd/*/name)
+ m=${m%/name}
+ m=${m##*/}
+ echo $m
+}
+
+rofs=$(findmtd rofs)
+rwfs=$(findmtd rwfs)
+
+rofst=squahsfs
+rwfst=ext4
+
+if test -n "$rwfs" && test -s whitelist
+then
+
+ mkdir -p rw
+ mount /dev/mtdblock${rwfs#mtd} rw -oro -t $rwfst
+
+ while read f
+ do
+ if ! test -e rw/cow/$f
+ then
+ continue
+ fi
+ d="save/cow/$f"
+ mkdir -p "${d%/*}"
+ cp -rp rw/cow/$f "${d%/*}/"
+ done < whitelist
+
+ umount rw
+fi
+
+
+for f in image-*
+do
+ m=$(findmtd ${f#image-})
+ if test -z "$m"
+ then
+ echo 1>&2 "Unable to find mtd partiton for $f"
+ exec /bin/sh
+ fi
+done
+
+for f in image-*
+do
+ m=$(findmtd ${f#image-})
+ echo "Updating ${f#image-}"
+ # flasheraseall /dev/$m && dd if=$f of=/dev/$m
+ flashcp -v $f /dev/$m
+done
+
+
+if test -d save/cow
+then
+ mount /dev/mtdblock${rwfs#mtd} rw -o rw -t $rwfst
+ cp -rp save/cow/. rw/cow/
+ umount rw
+fi
+
+# Execute the command systemd told us to ...
+if test -d /oldroot && test -x "/sbin/$1" && test -f "/sbin/$1"
+then
+ if test "$1" == kexec
+ then
+ /sbin/$1 -f -e
+ else
+ /sbin/$1 -f
+ fi
+fi
+
+
+echo "Execute ${1-reboot} -f if all is ok"
+
+export PS1=update-sh#\
+exec /bin/sh
diff --git a/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/whitelist b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/whitelist
new file mode 100644
index 000000000..80f9c81e7
--- /dev/null
+++ b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/whitelist
@@ -0,0 +1,8 @@
+/etc/dropbear/dropbear_rsa_host_key
+/etc/systemd/network
+/etc/resolv.conf
+/etc/machine-id
+/etc/passwd
+/etc/group
+/etc/shadow
+/etc/gshadow
diff --git a/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/obmc-phosphor-init.bb b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/obmc-phosphor-init.bb
new file mode 100644
index 000000000..68ee00d20
--- /dev/null
+++ b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/obmc-phosphor-init.bb
@@ -0,0 +1,23 @@
+SUMMARY = "Phosphor OpenBMC pre-init scripts"
+DESCRIPTION = "Phosphor OpenBMC filesytem mount reference implementation."
+PR = "r1"
+
+inherit obmc-phosphor-license
+inherit obmc-phosphor-initfs
+
+S = "${WORKDIR}"
+SRC_URI += "file://obmc-init.sh"
+SRC_URI += "file://obmc-shutdown.sh"
+SRC_URI += "file://obmc-update.sh"
+SRC_URI += "file://whitelist"
+
+do_install() {
+ install -m 0755 ${WORKDIR}/obmc-init.sh ${D}/init
+ install -m 0755 ${WORKDIR}/obmc-shutdown.sh ${D}/shutdown
+ install -m 0755 ${WORKDIR}/obmc-update.sh ${D}/update
+ install -m 0644 ${WORKDIR}/whitelist ${D}/whitelist
+ install -d ${D}/dev
+ mknod -m 622 ${D}/dev/console c 5 1
+}
+
+FILES_${PN} += " /init /shutdown /update /whitelist /dev "
OpenPOWER on IntegriCloud