diff options
Diffstat (limited to 'meta-phosphor/common/recipes-phosphor')
8 files changed, 333 insertions, 32 deletions
diff --git a/meta-phosphor/common/recipes-phosphor/clear-once/clear-once.bb b/meta-phosphor/common/recipes-phosphor/clear-once/clear-once.bb new file mode 100644 index 000000000..61e3c20cf --- /dev/null +++ b/meta-phosphor/common/recipes-phosphor/clear-once/clear-once.bb @@ -0,0 +1,8 @@ + +SUMMARY = "Clear boot-once variables" +DESCRIPTION = "Clear u-boot variables used for one-time boot flow" + +RPROVIDES_${PN} += "clear-once" + +inherit obmc-phosphor-systemd +inherit obmc-phosphor-license diff --git a/meta-phosphor/common/recipes-phosphor/clear-once/clear-once/clear-once.service b/meta-phosphor/common/recipes-phosphor/clear-once/clear-once/clear-once.service new file mode 100644 index 000000000..a7641e661 --- /dev/null +++ b/meta-phosphor/common/recipes-phosphor/clear-once/clear-once/clear-once.service @@ -0,0 +1,15 @@ +[Unit] +Description=Clear one time boot overrides + +ConditionFileNotEmpty=/etc/fw_env.config +RequiresMountsFor=/run /sbin /etc + +[Service] +Type=oneshot +RemainAfterExit=yes + +# It took 7 seconds to erase and write flash, be conservative +TimeoutStartSec=60 +Restart=no + +ExecStart=/sbin/fw_setenv openbmconce diff --git a/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid.bb b/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid.bb index d47d3d123..f694d2b05 100644 --- a/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid.bb +++ b/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid.bb @@ -14,6 +14,7 @@ inherit obmc-phosphor-c-daemon TARGET_CFLAGS += "-fpic" +RDEPENDS_${PN} += "clear-once" RDEPENDS_${PN} += "settings" RDEPENDS_${PN} += "network" SRC_URI += "git://github.com/openbmc/phosphor-host-ipmid" diff --git a/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid/host-ipmid.service b/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid/host-ipmid.service index ee9ce1ad1..ce96dbc9b 100644 --- a/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid/host-ipmid.service +++ b/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid/host-ipmid.service @@ -1,5 +1,7 @@ [Unit] Description=Phosphor OpenBMC IPMI daemon +Wants=clear-once.service +After=clear-once.service [Service] ExecStart=/usr/sbin/ipmid 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 index 12c5a2f1b..c37b3d53d 100644 --- 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 @@ -44,6 +44,84 @@ probe_fs_type() { echo ${fst:=jffs2} } +# This fw_get_env_var is a possibly broken version of fw_printenv that +# does not check the crc or flag byte. +# The u-boot environemnt starts with a crc32, followed by a flag byte +# when a redundannt environment is configured, followed by var=value\0 sets. +# The flag byte for nand is a 1 byte counter; for nor it is a 1 or 0 byte. + +get_fw_env_var() { + # do we have 1 or 2 copies of the environment? + # count non-blank non-comment lines + # copies=$(grep -v ^# /etc/fw_env.config | grep -c [::alnum::]) + # ... we could if we had the fw_env.config in the initramfs + copies=1 + + # * Change \n to \r and \0 to \n + # * Skip to the 5th byte to skip over crc + # * then skip to the first or 2nd byte to skip over flag if it exists + # * stop parsing at first empty line corresponding to the + # double \0 at the end of the environment. + # * print the value of the variable name passed as argument + + cat /run/fw_env | + tr '\n\000' '\r\n' | + tail -c +5 | tail -c +${copies-1} | + sed -ne '/^$/,$d' -e "s/^$1=//p" +} + +setup_resolv() { + runresolv=/run/systemd/resolve/resolv.conf + etcresolv=/etc/resolv.conf + + if test ! -e $etcresolv -a ! -L $etcresolv + then + mkdir -p ${runresolv%/*} + ln -s $runresolv $etcresolv + fi + if test ! -f $runresolv + then + cat /proc/net/pnp > $runresolv + fi + + return 0 +} + +try_tftp() { + # split into tftp:// host:port/ path/on/remote + # then spilt off / and then :port from the end of host:port/ + # and : from the beginning of port + + rest="${1#tftp://}" + path=${rest#*/} + host=${rest%$path} + host="${host%/}" + port="${host#${host%:*}}" + host="${host%$port}" + port="${port#:}" + + setup_resolv + + if test -z "$host" -o -z "$path" + then + debug_takeover "Invalid tftp download url '$url'." + elif echo "Downloading '$url' from $host ..." && + ! tftp -g -r "$path" -l /run/image-rofs "$host" ${port+"$port"} + then + debug_takeover "Download of '$url' failed." + fi +} + +try_wget() { + setup_resolv + + echo "Downloading '$1' ..." + if ! wget -O /run/image-rofs "$1" + then + debug_takeover "Download of '$url' failed." + fi +} + debug_takeover() { echo "$@" test -n "$@" && echo Enter password to try to manually fix. @@ -88,6 +166,10 @@ rwdev=/dev/mtdblock${rwfs#mtd} # Set to y for yes, anything else for no. force_rwfst_jffs2=y flash_images_before_init=n +consider_download_files=y +consider_download_tftp=y +consider_download_http=y +consider_download_ftp=y rofst=squashfs rwfst=$(probe_fs_type $rwdev) @@ -101,24 +183,94 @@ init=/sbin/init fsckbase=/sbin/fsck. fsck=$fsckbase$rwfst fsckopts=-a +optfile=/run/initramfs/init-options +urlfile=/run/initramfs/init-download-url +update=/run/initramfs/update + +if test -e /${optfile##*/} +then + cp /${optfile##*/} $optfile +fi + +if test ! -f $optfile +then + cat /proc/cmdline > $optfile + get_fw_env_var openbmcinit >> $optfile + get_fw_env_var openbmconce >> $optfile +fi echo rofs = $rofs $rofst rwfs = $rwfs $rwfst -if grep -w debug-init-sh /proc/cmdline +if grep -w debug-init-sh $optfile then debug_takeover "Debug initial shell requested by command line." fi -# If there are images in root move them to run/initramfs/ now. +if test "x$consider_download_files" = xy && + grep -w openbmc-init-download-files $optfile +then + if test -f ${urlfile##*/} + then + cp ${urlfile##*/} $urlfile + fi + if test ! -f $urlfile + then + get_fw_env_var openbmcinitdownloadurl > $urlfile + fi + url="$(cat $urlfile)" + rest="${url#*://}" + proto="${url%$rest}" + + if test -z "$url" + then + echo "Download url empty. Ignoring download request." + elif test -z "$proto" + then + echo "Download failed." + elif test "$proto" = tftp:// + then + if test "x$consider_download_tftp" = xy + then + try_tftp "$url" + else + echo "Download failed." + fi + elif test "$proto" = http:// + then + if test "x$consider_download_http" = xy + then + try_wget "$url" + else + echo "Download failed." + fi + elif test "$proto" = ftp:// + then + if test "x$consider_download_ftp" = xy + then + try_wget "$url" + else + echo "Download failed." + fi + else + echo "Download failed." + fi +fi + +# If there are images in root move them to /run/initramfs/ or /run/ now. imagebasename=${image##*/} -if test -n "${imagebasename}" -a "x$flash_images_before_init" = xy && - ls /${imagebasename}* > /dev/null 2>&1 +if test -n "${imagebasename}" && ls /${imagebasename}* > /dev/null 2>&1 then - echo "Pending flash updates found." - mv /${imagebasename}* ${image%$imagebasename} + if test "x$flash_images_before_init" = xy + then + echo "Flash images found, will update before starting init." + mv /${imagebasename}* ${image%$imagebasename} + else + echo "Flash images found, will use but deferring flash update." + mv /${imagebasename}* /run/ + fi fi -if grep -w clean-rwfs-filesystem /proc/cmdline +if grep -w clean-rwfs-filesystem $optfile then echo "Cleaning of read-write overlay filesystem requested." touch $trigger @@ -132,27 +284,64 @@ fi if ls $image* > /dev/null 2>&1 then - if ! test -x /update + if ! test -x $update then - debug_takeover "Flash update requested but /update missing!" + debug_takeover "Flash update requested but $update missing!" elif test -f $trigger -a ! -s $trigger then echo "Saving selected files from read-write overlay filesystem." - /update && rm -f $image* + $update --no-restore-files echo "Clearing read-write overlay filesystem." flash_eraseall /dev/$rwfs echo "Restoring saved files to read-write overlay filesystem." touch $trigger - /update - rm -rf /save $trigger + $update --no-save-files --clean-saved-files else - /update && rm -f $image* + $update --clean-saved-files fi rwfst=$(probe_fs_type $rwdev) fsck=$fsckbase$rwfst fi +if grep -w overlay-filesystem-in-ram $optfile +then + rwfst=none +fi + +copyfiles= +if grep -w copy-files-to-ram $optfile +then + rwfst=none + copyfiles=y +fi + +# It would be nice to do this after fsck but that mean rofs is mounted +# which triggers the mtd is mounted check +if test "$rwfst$copyfiles" = noney +then + touch $trigger + $update --copy-files --clean-saved-files --no-restore-files +fi + +if grep -w copy-base-filesystem-to-ram $optfile && + test ! -e /run/image-rofs && ! cp $rodev /run/image-rofs +then + # Remove any partial copy to avoid attempted usage later + if test -e /run/image-rofs + then + ls -l /run/image-rofs + rm -f /run/image-rofs + fi + debug_takeover "Copying $rodev to /run/image-rofs failed." +fi + +if test -s /run/image-rofs +then + rodev=/run/image-rofs + roopts=$roopts,loop +fi + mount $rodev $rodir -t $rofst -o $roopts if test -x $rodir$fsck @@ -171,12 +360,16 @@ then then debug_takeover "fsck of read-write fs on $rwdev failed (rc=$rc)" fi -elif test $fsck != /sbin/fsck.jffs2 +elif test "$rwfst" != jffs2 -a "$rwfst" != none then echo "No '$fsck' in read only fs, skipping fsck." fi -if ! mount $rwdev $rwdir -t $rwfst -o $rwopts +if test "$rwfst" = none +then + echo "Running with read-write overlay in RAM for this boot." + echo "No state will be preserved unless flash update performed." +elif ! mount $rwdev $rwdir -t $rwfst -o $rwopts then msg="$(cat)" << HERE 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 index fc359c5be..8d5d0c983 100644 --- 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 @@ -30,30 +30,37 @@ do done set +x +update=/run/initramfs/update image=/run/initramfs/image- + if test -s /run/fw_env -a -c /run/mtd:u-boot-env -a ! -e ${image}u-boot-env && ! cmp /run/mtd:u-boot-env /run/fw_env then ln -sn /run/fw_env ${image}u-boot-env fi -if test -x /update && ls $image* > /dev/null 2>&1 +if ls $image* > /dev/null 2>&1 then - /update ${1+"$@"} + if test -x $update + then + $update --clean-saved-files + else + echo 1>&2 "Flash update requested but $update program missing!" + fi fi echo Remaining mounts: cat /proc/mounts -test "umount_proc" && umount /proc && rmdir /proc +test "$umount_proc" && umount /proc && rmdir /proc -# ioctl(TIOC_DRAIN) to drain tty messages to console +# tcsattr(tty, TIOCDRAIN, mode) to drain tty messages to console test -t 1 && stty cooked 0<&1 # Execute the command systemd told us to ... if test -d /oldroot && test "$1" then - if test "$1" == kexec + if test "$1" = kexec then $1 -f -e else 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 index 367c302c7..aa8fd8934 100755 --- 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 @@ -55,15 +55,57 @@ rwdev=/dev/mtdblock${rwfs#mtd} rwopts=rw rorwopts=ro${rwopts#rw} -rwdir=rw +rwdir=/run/initramfs/rw upper=$rwdir/cow -save=save/${upper##*/} +save=/run/save/${upper##*/} -if test -n "$rwfs" && test -s whitelist -then +mounted= +doclean= +dosave=y +dorestore=y +toram= - mkdir -p $rwdir - mount $rwdev $rwdir -t $(probe_fs_type $rwdev) -o $rorwopts +whitelist=/run/initramfs/whitelist +image=/run/initramfs/image- + +while test "$1" != "${1#-}" +do + case "$1" in + --no-clean-saved-files) + doclean= + shift ;; + --clean-saved-files) + doclean=y + shift ;; + --no-save-files) + dosave= + shift ;; + --save-files) + dosave=y + shift ;; + --no-restore-files) + dorestore= + shift ;; + --restore-files) + dorestore=y + shift ;; + --copy-files) + toram=y + shift ;; + *) + echo 2>&1 "Unknown option $1" + exit 1 ;; + esac +done + +if test "x$dosave" = xy +then + if test ! -d $upper -a -n "$rwfs" + then + mkdir -p $rwdir + mount $rwdev $rwdir -t $(probe_fs_type $rwdev) -o $rorwopts + mounted=$rwdir + fi while read f do @@ -74,12 +116,14 @@ then d="$save/$f" mkdir -p "${d%/*}" cp -rp $upper/$f "${d%/*}/" - done < whitelist + done < $whitelist - umount $rwdir + if test -n "$mounted" + then + umount $mounted + fi fi -image=/run/initramfs/image- for f in $image* do m=$(findmtd ${f#$image}) @@ -92,17 +136,40 @@ done for f in $image* do + if test ! -s $f + then + echo "Skipping empty update of ${f#$image}." + rm $f + continue + fi m=$(findmtd ${f#$image}) echo "Updating ${f#$image}..." - # flasheraseall /dev/$m && dd if=$f of=/dev/$m - flashcp -v $f /dev/$m + flashcp -v $f /dev/$m && rm $f done -if test -d $save +if test "x$toram" = xy +then + mkdir -p $upper + cp -rp $save/. $upper/ +fi + +if test -d $save -a "x$dorestore" = xy then + odir=$rwdir + rwdir=/run/rw + upper=$rwdir${upper#$odir} + + mkdir -p $rwdir mount $rwdev $rwdir -t $(probe_fs_type $rwdev) -o $rwopts + mkdir -p $upper cp -rp $save/. $upper/ umount $rwdir + rmdir $rwdir +fi + +if test "x$doclean" = xy +then + rm -rf $save fi exit 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 index 68ee00d20..3fa88c9e6 100644 --- 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 @@ -12,6 +12,13 @@ SRC_URI += "file://obmc-update.sh" SRC_URI += "file://whitelist" do_install() { + for f in init-download-url init-options + do + if test -e $f + then + install -m 0755 ${WORKDIR}/$f ${D}/$f + fi + done 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 @@ -21,3 +28,4 @@ do_install() { } FILES_${PN} += " /init /shutdown /update /whitelist /dev " +FILES_${PN} += " /init-options /init-download-url " |