lauhub Posted July 1, 2016 Posted July 1, 2016 Hi, I am currently working on a OLinuxIno A20 limeX system which works in read only mode. I use the code I developped here: https://github.com/lauhub/debian-to-readonly I have small problems with armbian evolutions, since it uses, creates and modifies some files in some directories that should not be modified according to this page. Example of files : /etc/init.d/armhwinfo (modifies permissions of /etc/logrotate.d/armhwinfo) /sbin/fake-hwclock (creates /etc/fake-hwclock.data) /etc/update-motd.d/40-updates /usr/local/bin/armbianmonitor (modifies /etc/armbianmonitor/datasources/soctemp) I can easily disable these files for my purposes, but I would be glad to help or discuss about how to integrate this "read only mode" into Armbian project. Does it interest someone ?
Igor Posted July 1, 2016 Posted July 1, 2016 Better than read only is overlay file system aka "virtual read only". If you use recent kernel: apt-get install overlayroot echo 'overlayroot="tmpfs"' >> /etc/overlayroot.conf reboot After reboot you can't make any permanent changes unless you use it within: overlayroot-chroot Overlay is done (with current settings) to RAM which is very fast but small. You can have overlay on any other device ... 2
lauhub Posted July 1, 2016 Author Posted July 1, 2016 Thank you for this lead. I had forgotten that solution. Overlayfs was not OK for me two years ago, because of my needs of 3.4 kernel with NAND support. At that time, it was not as simple as you indicate (there were some patches, but it gave me some headaches). So I developed my own solution. (it sounds like I re-invented the wheel ) Do you know if there are consequences in term of speed, boot time, reliability, ram footprint (I will run a Java VM (or more on a 1Gb RAM machine)) ?
Igor Posted July 1, 2016 Posted July 1, 2016 Do you know if there are consequences in term of speed, boot time, reliability, ram footprint (I will run a Java VM (or more on a 1Gb RAM machine)) ? If you can, rather use modern kernel but it works on our 3.4.x out of the box. I only made few tests but one of my friends is using this on several Cubietruck workstations with 3.4 and he just confirmed "yes it works perfectly".
lauhub Posted July 1, 2016 Author Posted July 1, 2016 Thanks, I change hardware from NAND based A20-Lime to eMMC based ones. So I now use 4.x kernel. I will give it a try.
lauhub Posted July 1, 2016 Author Posted July 1, 2016 Hi again, Sorry, but it seems that overlayroot package is not available for Debian (package is missing from both Jessie an Wheezy). Seems to be an Ubuntu only package. As I am stuck (for now) to Debian, I have to use my solution.
zador.blood.stained Posted July 1, 2016 Posted July 1, 2016 Sorry, but it seems that overlayroot package is not available for Debian (package is missing from both Jessie an Wheezy). Seems to be an Ubuntu only package. As I am stuck (for now) to Debian, I have to use my solution. This package doesn't have any OS specific dependencies, so you should be able to install Ubuntu package on Debian manually without any issues.
lauhub Posted July 1, 2016 Author Posted July 1, 2016 Thank you for this info, I will try it, hoping that the package version are not too old (initramfs-tools 0.109 under Wheezy, although 0.122 under Ubuntu Xenial). I will try it with Trusty packages as soon as I have some time.
chradev Posted October 6, 2016 Posted October 6, 2016 Hi Lauhub, Thank you for this info, I will try it, hoping that the package version are not too old (initramfs-tools 0.109 under Wheezy, although 0.122 under Ubuntu Xenial). I will try it with Trusty packages as soon as I have some time. Do you have success in using overlayfs to make rootfs read only on Armbian? I am using Lime2-eMMC and latest Armbian (5.21), U-Boot (2016.09) and Kernel (4.7.6) and need to make rootfs read only when installed on eMMC and have: SSD for system and data and make the system to boot from both eMMC and SSD; succeeded to use overlayfs for merging read only and read/write data staff easily. Unfortunately, described by Igor way is not possible because overlayfs-root packet is not in Debian. In my opinion it is not good idea to rely on other distribution packages. Any way did you try suggested by Zador way to install it in Armbian? I am interested in getting work done with Armbian customization features only. On the other hand read only root fs is a very frequent use case in embedded systems. @Igor, Is it possible to add overlayfs-root packet (will not be a precedent) in Armbian? Best regards Chris
Igor Posted October 6, 2016 Posted October 6, 2016 I can add this package to our repo if it works on Debian? http://packages.ubuntu.com/xenial/overlayroot
chradev Posted October 6, 2016 Posted October 6, 2016 Hi to All, Is it possible to use bindfs as alternative of overlayfs to make root fs read only? Best regards Chris
chradev Posted October 6, 2016 Posted October 6, 2016 Hi Igor, I can add this package to our repo if it works on Debian? http://packages.ubuntu.com/xenial/overlayroot I have installed manually overlayroot and change its configuration as mentioned above. Before installation I have to install cryptsetup and cryptsetup-bin dependencies and installation had no problem. After adding 'overlayroot="tmpfs"' to /etc/overlayroot.conf and reboot I try to test it by creating of some file in the root home directory. Unfortunately, after rebooting the created file was still there and command 'overlayroot-chroot' says: ERROR: Unable to find an overlayroot filesystem which means there is something wrong. Where could be the problem? EDIT: I have removed the line for rootfs from /etc/fstab file for ability to support boot from any device without changing any files. At overlayroot installation initrd.img was rebuild with warnings because of rootfs line lack in /etc/fstab file. cryptsetup: WARNING: could not determine root device from /etc/fstab Could it be the reason of the problem? EDIT2: I try to install and configure overlayroot with rootfs line added to /etc/fstab and the installation (rebuilding initrd.img) completed without errors and warnings. Unfortunately, the problem is still there. Best regards Chris
chradev Posted October 7, 2016 Posted October 7, 2016 Hi Igor, I can add this package to our repo if it works on Debian? http://packages.ubuntu.com/xenial/overlayroot I have tried to get overlayroot working with migration from Jessie to Xenial. Unfortunately, the result is the same with a difference that overlayroot exists as a package in Ubuntu Xenial distribution. Any ideas what is wrong? Best regards Chris
Igor Posted October 7, 2016 Posted October 7, 2016 None. I made quick investigation and haven't found a solution. Anyway, there are at least two ways to go from here - close examine of overlayroot scripts or DIY. You need an overlay modules, which is build in and few proper mounts, which you can find in driver documentation. This way is also userspace independent and must work. It's just a bit more rough way.
chradev Posted October 7, 2016 Posted October 7, 2016 Thanks Igor, None. I made quick investigation and haven't found a solution. Anyway, there are at least two ways to go from here - close examine of overlayroot scripts or DIY. You need an overlay modules, which is build in and few proper mounts, which you can find in driver documentation. This way is also userspace independent and must work. It's just a bit more rough way. I have already used overlayfs to merge both RO and RW staff in a single directory used by our application. It was very easy to setup and it is working perfect. Unfortunately, overlaying the root fs is more troublesome that is why I prefer to rely on a working and reliable solution. Is it possible to use btrfs or bindfs as alternative of overlayfs to make root fs read only? Best regards Chris
chradev Posted October 7, 2016 Posted October 7, 2016 Hi to All, As Igor recommended I start looking into overlayroot package staff. After a brief search I find that overlayroot is looking for overlayfs Kernel module which do not exists (trying with modeprobe). In my experience the Kernel module is 'overlay' instead of 'overlayfs' and probably this is a problem. On the other hand in overlayroot script '/usr/share/initramfs-tools/scripts/init-bottom/overlayroot' can be read: # overlayroot_driver *could* be defined in one of the configs above # but we're not documenting that. overlayroot_driver=${overlayroot_driver:-overlayfs} I try to put in /etc/overlayroot.config following line: overlayroot_driver="overlay" and add 'overlay' to /etc/modules abut without success in activating overlayroot. May be it is related with initrd image usage for early preparation to mount of overlayed root. By default it is not loaded because U-Boot searches for /boot/initramfs-linux.img file. It is rising a question is there any special reason for the lack of the link to initrd.img-4.7.6-sunxi in /boot directory? That why I make appropriate link: cd /boot && ln -sf initrd.img-4.7.6-sunxi initramfs-linux.img and reboot. After loading the initram disk following messages can be read: Begin: Running /scripts/init-bottom ... Warning: overlayroot: debug is busted Warning: overlayroot: configuring overlayroot with mode=tmpfs opts='' per /dev/mmcblk0p1/etc/overlayroot.conf Failure: overlayroot: missing kernel module overlayfs /scripts/init-bottom/plymouth: line 18: /bin/plymouth: not found which shows that overlayroot is looking for overlayfs kernel module but it is missing. Even 'overlay' module is missing in initram disk image. On the other hand it looks for overlayroot.conf file on /dev/mmcblk0p1/etc/ which may be a problem when booting from other device (eMMC, SSD etc.). Did somebody have such a problem and find a proper solution? Best regards Chris
chradev Posted October 7, 2016 Posted October 7, 2016 Hi to All, After findings that overlayroot initialization is invoked in initram disk I have tried to make use of it in Jessie build by running: cd /boot && ln -sf initrd.img-4.7.6-sunxi initramfs-linux.img and after rebooting following is printed: ## Flattened Device Tree blob at 43000000 Booting using the fdt blob at 0x43000000 Loading Ramdisk to 49b93000, end 49fff18f ... OK Loading Device Tree to 49b84000, end 49b92f95 ... OK Starting kernel ... Uncompressing Linux... done, booting the kernel. Loading, please wait... Begin: Loading essential drivers ... done. Begin: Running /scripts/init-premount ... done. Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done. Begin: Running /scripts/local-premount ... Scanning for Btrfs filesystems done. Begin: Will now check root file system ... fsck from util-linux 2.25.2 fsck: error 2 (No such file or directory) while executing fsck.ext4 for /dev/sda1 fsck exited with status code 8 done. Warning: File system check failed but did not detect errors mount: No such file or directory done. Target filesystem doesn't have requested /sbin/init. Begin: Running /scripts/local-bottom ... done. Begin: Running /scripts/init-bottom ... trap: EXIT: bad trap Warning: overlayroot: debug is busted mount: No such file or directory done. Could not copy file: No such file or directory No init found. Try passing init= bootarg. Rebooting automatically due to panic= boot argument and the system continuously reboots itself. Trying the same on a build without overlayroot installed the situation is the almost the same: ## Flattened Device Tree blob at 43000000 Booting using the fdt blob at 0x43000000 Loading Ramdisk to 49c25000, end 49fff4cd ... OK Loading Device Tree to 49c16000, end 49c24f95 ... OK Starting kernel ... Uncompressing Linux... done, booting the kernel. Loading, please wait... Begin: Loading essential drivers ... done. Begin: Running /scripts/init-premount ... done. Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done. Begin: Running /scripts/local-premount ... Scanning for Btrfs filesystems done. Begin: Will now check root file system ... fsck from util-linux 2.25.2 [/sbin/fsck.ext4 (1) -- /dev/mmcblk1p1] fsck.ext4 -a -C0 /dev/mmcblk1p1 /dev/mmcblk1p1: clean, 64029/228928 files, 291923/895744 blocks done. mount: No such file or directory done. Target filesystem doesn't have requested /sbin/init. Begin: Running /scripts/local-bottom ... done. Begin: Running /scripts/init-bottom ... mount: No such file or directory done. Could not copy file: No such file or directory No init found. Try passing init= bootarg. Rebooting automatically due to panic= boot argument In my opinion there is some problem in default initram disk staff causing system panic and reboot. On the other hand one of the problems in overlayroot is trying to use not existing 'overlayfs' module instead of existing 'overlay' one. Last one is very rough difference with Kernel module name which is unlikely to be simply bug. Does somebody knows working solution using overlayroot? Best egards Chris
lauhub Posted November 10, 2016 Author Posted November 10, 2016 Hi Chris, I think I found at least a lead to that problem There are some missing parts into the initramfs scripts / configuration problem in boot.cmd. I experienced the same problem with a small difference Investigation To investigate the problem, I modified the /usr/share/initramfs-tools/init first line as follow (shell debug mode): #!/bin/sh -x To correct the problem, I did the following: FIrst bug correction: creating the /root/dev mount point I had to modify the script /usr/share/initramfs-tools/scripts/init-bottom/udev adding a line prior to the mount command: #This line prevents the "mount: No such file or directory" error: mkdir -p ${rootmnt}/dev #The following mount call was leading to "mount: No such file or directory" error #Creating the directory works better # move the /dev tmpfs to the rootfs mount -n -o move /dev ${rootmnt}/dev Second bug: modification of boot.cmd I changed my boot.cmd script. I replaced boot parameters PARTUUID=e8198e69-01 with the UUID value (root=UUID=abcdef-012345-abcdef-123456) My script is (if I remember well) is close to the one you provided: setenv verbosity 7 part uuid ${devtype} ${devnum}:${distro_bootpart} uuid #Old line: #setenv bootargs "console=${console} root="PARTUUID=${uuid}" rw rootwait nomodeset mac_addr=02:8f:06:c0:f4:31 loglevel=${verbosity} ${extended_bootargs}" #New line setenv bootargs "console=${console} root="UUID=6b742ea8-78e6-403f-8558-d57ec67755c4" rw rootwait nomodeset mac_addr=02:8f:06:c0:f4:31 loglevel=${verbosity} ${extended_bootargs}" if load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} /boot/zImage; then if load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} /boot/dtb/${fdtfile}; then if load ${devtype} ${devnum}:${distro_bootpart} ${ramdisk_addr_r} /boot/initramfs-linux.img; then bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}; else bootz ${kernel_addr_r} - ${fdt_addr_r}; fi; fi; fi if load ${devtype} ${devnum}:${distro_bootpart} 0x48000000 /boot/uImage; then if load ${devtype} ${devnum}:${distro_bootpart} 0x43000000 /boot/script.bin; then setenv bootm_boot_mode sec; bootm 0x48000000; fi; fi # Recompile with: # mkimage -C none -A arm -T script -d boot.cmd boot.scr This make my initramfs work. Now, I have to make overlayfs work. Conclusion Two bugs, and two ways to correct the second one. The second way: I think it could be possible to retrieve UUID from PARTUUID in u-boot, but I don't know how to do this. Another way could be to change the scripts/functions script (resolve_device function) by adding the PARTUUID parsing (line 327), and/or the scripts/local (function local_mount_root, line 152 adn 154, replacing "mount" with "mount -f ") EDIT: There is a bug about PARTUUID in Debian BTS: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=801154 Version 0.121 of initramfs-tools support PARTUUID
lauhub Posted November 12, 2016 Author Posted November 12, 2016 Hi again, I successfully made overlayroot work under Debian Jessie. Ubuntu package I installed overlayroot_0.27ubuntu1.2_all.deb package wget http://fr.archive.ubuntu.com/ubuntu/pool/main/c/cloud-initramfs-tools/overlayroot_0.27ubuntu1.2_all.deb dpkg -i overlayroot_0.27ubuntu1.2_all.deb Correcting overlayfs module name About the following error: Failure: overlayroot: missing kernel module overlayfs I had to modify the /usr/share/initramfs-tools/scripts/init-bottom/overlayroot file: Here is a diff: diff --suppress-common-lines -r -y ./usr/share/initramfs-tools/scripts/init-bottom/overlayroot /usr/share/initramfs-tools/scripts/init-bottom/overlayroot VARIABLES="overlayroot overlayroot_cfgdisk" | VARIABLES="overlayroot overlayroot_cfgdisk overlayroot_driver overlayfs) | overlayfs|overlay) mount_type="overlayfs" | mount_type="overlay" mount_opts="${mount_opts} overlayroot ${ROOTM | mount_opts="${mount_opts} overlay ${ROOTMNT}" mount --move "${ROOTMNT}" "${root_ro}" || | mount -o move "${ROOTMNT}" "${root_ro}" || mount --move ${root_ro} ${ROOTMNT} | mount -o move ${root_ro} ${ROOTMNT} mount --move ${root_ro} "${ROOTMNT}${root_ro}" || | mount -o move ${root_ro} "${ROOTMNT}${root_ro}" || mount --move "${root_rw}" "${ROOTMNT}${root_rw}" || | mount -o move "${root_rw}" "${ROOTMNT}${root_rw}" || As you can see, I added one variable to the VARIABLES list and made some changes to mount parameters. Here is the complete file: #!/bin/sh# Copyright, 2012 Dustin Kirkland <kirkland@ubuntu.com># Copyright, 2012 Scott Moser <smoser@ubuntu.com># Copyright, 2012 Axel Heider## Based on scripts from# Sebastian P.# Nicholas A. Schembri State College PA USA# Axel Heider# Dustin Kirkland# Scott Moser### This program is free software: you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation, either version 3 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program. If not, see# <http://www.gnu.org/licenses/>.case "$1" in # no pre-reqs prereqs) echo ""; exit 0;;esac. /scripts/functionsPATH=/usr/sbin:/usr/bin:/sbin:/binMYTAG="overlayroot"TEMP_D="${TMPDIR:-/tmp}/${0##*/}.configs"VARIABLES="overlayroot overlayroot_cfgdisk overlayroot_driver"# generic settings# ${ROOT} and ${rootmnt} are predefined by caller of this script. Note that# the root fs ${rootmnt} it mounted readonly on the initrams, which fits# nicely for our purposes.root_rw=/media/root-rwroot_ro=/media/root-roROOTMNT=${rootmnt} # use global name to indicate created outside thisOVERLAYROOT_DEBUG=0log() { "log_${1}_msg" "$MYTAG: $2"; _debug "[$1]:" "$2"}log_fail() { log failure "$*"; }log_success() { log success "$*"; }log_warn() { log warning "$*"; }fail() { [ $# -eq 0 ] || log_fail "$@"; exit 0; # why do we exit success?}cleanup() { [ -d "${TEMP_D}" ] && rm -Rf "${TEMP_D}"}debug() { _debug "$@" [ "${OVERLAYROOT_DEBUG:-0}" = "0" ] && return echo "$MYTAG:" "$@"}_debug() { if [ "${DEBUG_BUSTED:-0}" = "0" ]; then { echo "$@" >> "/dev/.initramfs/${MYTAG}.log"; } 2>/dev/null || { DEBUG_BUSTED=1; log_warn "debug is busted"; } fi}safe_string() { local prev="$1" allowed="$2" cur="" [ -n "$prev" ] || return 1 while cur="${prev#[${allowed}]}"; do [ -z "$cur" ] && return 0 [ "$cur" = "$prev" ] && break prev="$cur" done return 1}parse_string() { # parse a key/value string like: # name=mapper,pass=foo,fstype=ext4,mkfs=1 # set variables under namespace 'ns'. # _RET_name=mapper # _RET_pass=foo # _RET_fstype=ext4 # set _RET to the list of variables found local input="${1}" delim="${2:-,}" ns="${3:-_RET_}" local oifs="$IFS" tok="" keys="" key="" val="" set -f; IFS="$delim"; set -- $input; IFS="$oifs"; set +f; _RET="" for tok in "$@"; do key="${tok%%=*}" val="${tok#${key}}" val=${val#=} safe_string "$key" "0-9a-zA-Z_" || { debug "$key not a safe variable name"; return 1; } eval "${ns}${key}"='${val}' || return 1 keys="${keys} ${ns}${key}" done _RET=${keys# } return}get_varval() { eval _RET='${'$1'}'; }write_kernel_cmdline_cfg() { local cfg="$1" desc="${2:-kernel cmdline}" local cmdline="" var="" read cmdline < /proc/cmdline || return 1 : > "${cfg}" || return set -f { echo "desc='${desc}'" for tok in $cmdline; do for var in $VARIABLES; do if [ "$tok" = "$var" ]; then log_warn "kernel param without value '${tok}'"; continue; elif [ "${tok}" = "${var}=" ]; then echo "${var}=''"; elif [ "${tok#${var}=}" != "${tok}" ]; then echo "${var}='${tok#${var}=}'" fi done done } >> "$cfg" set +f}wait_for_dev() { local dev="$1" timeout="${2:-0}" [ -b "$dev" ] && return 0 [ "$timeout" = "0" ] && return 1 # wait-for-root writes fstype to stdout, redirect to null wait-for-root "$dev" "$timeout" >/dev/null}crypto_setup() { local fstype="ext4" pass="" mapname="secure" mkfs="1" dev="" local timeout=0 local entropy_sources="/proc/sys/kernel/random/boot_id /proc/sys/kernel/random/uuid /dev/urandom" local seed= # Seed the psuedo random number generator with available seeds for seed in "/.random-seed" "${ROOTMNT}/var/lib/urandom/random-seed"; do [ -f "${seed}" ] && cat "${seed}" > /dev/urandom || { debug "missing rng seed [${seed}]"; } done # this does necessary crypto setup and sets _RET # to the appropriate block device (ie /dev/mapper/secure) # mkfs (default is 1): # 0: never create filesystem # 1: if pass is given and mount fails, create a new one # if no pass given, create new # 2: if pass is given and mount fails, fail # if no pass given, create new local options="$1" parse_string "${options}" || { log_fail "failed parsing '${options}'"; return 1; } fstype=${_RET_fstype:-${fstype}} pass=${_RET_pass:-${pass}} mapname=${_RET_mapname:-${mapname}} mkfs=${_RET_mkfs:-${mkfs}} dev=${_RET_dev:-${dev}} timeout=${_RET_timeout:-${timeout}} [ -n "$dev" ] || { log_fail "dev= argument not provided in '${options}'"; return 1; } short2dev "$dev" || { log_fail "failed to convert $dev to a device"; return 1; } dev="${_RET}" debug "fstype=${fstype} pass=${pass} mapname=${mapname}" debug "mkfs=${mkfs} dev=${dev} timeout=${timeout}" wait_for_dev "$dev" "$timeout" || { log_fail "crypt dev device $dev does not exist after ${timeout}s"; return 1; } if [ -n "$pass" ]; then printf "%s" "$pass" | cryptsetup luksOpen "$dev" "$mapname" --key-file - if [ $? -eq 0 ]; then local tdev="/dev/mapper/$mapname" log_warn "reusing existing luks device at $dev" wait_for_dev "$tdev" 20 || { log_fail "$tdev did not appear"; return 1; } _RET_DEVICE="/dev/mapper/$mapname" return 0 fi if [ "$mkfs" != "1" ]; then log_fail "luksOpen failed on $dev with mkfs=$mkfs"; return 1; fi log_warn "re-opening $dev failed with mkfs=$mkfs will create new" else [ "$mkfs" = "0" ] && { log_fail "mkfs=0, but no password provided"; return 1; } entropy_sources="$entropy_sources $dev" local pass_file=$(mktemp /dev/.initramfs/${MYTAG}.XXXXXX) || { log_fail "failed creation of password file"; return 1; } stat -L /dev/* /proc/* /sys/* >${pass_file} 2>&1 || { log_warn "could not seed with stat entropy [$entropy_sources]"; } head -c 4096 $entropy_sources >> ${pass_file} || { log_fail "failed reading entropy [$entropy_sources]"; return 1; } pass=$(sha512sum ${pass_file}) || { log_fail "failed generation of password"; return 1; } pass=${pass%% *} printf "%s" "${pass}" > ${pass_file} fi log_warn "setting up new luks device at $dev" # clear backing device wipefs -a "$dev" || { log_fail "failed to wipe $dev"; return 1; } printf "%s" "$pass" | cryptsetup luksFormat "$dev" --key-file - || { log_fail "luksFormat $dev failed"; return 1; } printf "%s" "$pass" | cryptsetup luksOpen "$dev" "$mapname" --key-file - || { log_fail "luksOpen $dev failed"; return 1; } mke2fs -t "${fstype}" "/dev/mapper/${mapname}" || { log_fail "failed to mkfs -t $fstype on map $mapname"; return 1; } _RET_DEVICE="/dev/mapper/$mapname" return 0}dev_setup() { local options="$1" dev="" timeout=0 path="/" # options supported: # dev=device,timeout=X,path=/ parse_string "${options}" || { log_fail "failed parsing '${options}'"; return 1; } dev=${_RET_dev:-${dev}} timeout=${_RET_timeout:-${timeout}} [ -n "$dev" ] || { log_fail "dev= argument not provided in '${options}'"; return 1; } short2dev "$dev" || { log_fail "failed to convert $dev to a device"; return 1; } dev="${_RET}" debug "dev=${dev} timeout=${timeout}" wait_for_dev "$dev" "$timeout" _RET_DEVICE="$dev"}overlayrootify_fstab() { # overlayrootify_fstab(input, root_ro, root_rw, dir_prefix, recurse, swap) # read input fstab file, write an overlayroot version to stdout # also returns (_RET) a list of directories that will need to be made local input="$1" root_ro="${2:-/media/root-ro}" local root_rw="${3:-/media/root-rw}" dir_prefix="${4:-/}" local recurse=${5:-1} swap=${6:-0} local hash="#" oline="" ospec="" upper="" dirs="" copy_opts="" local vfstypes=" proc sys tmpfs dev udev " local spec file vfstype opts pass freq line ro_line dir_prefix="${dir_prefix#/}" [ -f "$input" ] || return 1 while read spec file vfstype opts pass freq; do line="$spec $file $vfstype $opts $pass $freq" case ",$opts," in *,ro,*) ro_opts="$opts";; *) ro_opts="ro,${opts}";; esac ro_line="$spec ${root_ro}$file $vfstype ${ro_opts} $pass $freq" if [ "${spec#${hash}}" != "$spec" ] || [ -z "$freq" ]; then # line has a comment in first field, or not 6 fields echo "$line" elif [ "${vfstypes# *${vfstype} }" != "${vfstypes}" ]; then # this is a virtual filesystem, just let it through echo "${line}" elif [ "$vfstype" = "swap" ]; then if [ "$swap" = "0" ]; then # comment out swap lines echo "#overlayroot:swap=${swap}#${line}" elif [ "${spec#/}" != "${spec}" ] && [ "${spec#/dev/}" = "${spec}" ]; then # comment out swap files (spec starts with / and not in /dev) echo "#overlayroot:swapfile#${line}" else echo "${line}" fi else ospec="${root_ro}${file}" copy_opts="" [ "${opts#*nobootwait*}" != "${opts}" ] && copy_opts=",nobootwait" upper="${root_rw%/}/${dir_prefix%/}${file%/}" oline="${ospec} ${file} overlayfs " oline="${oline}lowerdir=${root_ro}${file}," oline="${oline}upperdir=${upper}${copy_opts} $pass $freq" if [ "$recurse" != "0" ]; then echo "$ro_line" echo "$oline" dirs="${dirs} ${upper}" else echo "$line" [ "$file" = "/" ] && dirs="${dirs} ${upper}" fi fi done < "$input" _RET=${dirs# }}short2dev() { # turn 'LABEL=' or 'UUID=' into a device path # also support /dev/* and 'vdb' or 'xvda' local input="$1" oifs="$IFS" dev newdev s case "$input" in LABEL=*) dev="${input#LABEL=}" case "${dev}" in */*) dev="$(echo "${dev}" | sed 's,/,\\x2f,g')";; esac dev="/dev/disk/by-label/${dev}" ;; UUID=*) dev="/dev/disk/by-uuid/${input#UUID=}" ;; /dev/*) dev="${input}";; *) dev="/dev/${input}";; esac _RET=$dev}get_cfg() { # get_cfg(device, file, cfg, timeout=0) # copy the file $cfg off $device to $file, waiting $timeout for # $device to appear local dev="$1" file="$2" cfg="${3:-overlayroot.conf}" timeout="${4:-0}" local cfgdev="" success=0 didmnt=false mp="" pre="get_cfg($dev):" [ -z "$dev" ] && return 1 if [ "$timeout" != "0" ]; then wait_for_dev "$dev" "$timeout" || { debug "$pre did not appear in $timeout"; return 1; } else udevadm settle fi short2dev "$dev" && cfgdev="$_RET" && [ -b "$cfgdev" ] || { debug "$pre not present"; return 1; } if mp="${TEMP_D}/mp" && mkdir "$mp" && mount -o ro "$cfgdev" "$mp"; then if [ -f "$mp/$cfg" ]; then cp "$mp/$cfg" "$file" && success=1 || debug "$pre copy failed" else debug "$pre '$file' file not found" fi umount "$mp" else debug "$pre mount failed" fi [ -d "$mp" ] || rmdir "$mp" [ $success -eq 1 ] || return 1 _RET="$dev/$cfg"}parse_cfg() { # parse_cfg($file,$desc,$vars) # this reasonably safely sources the "config" file $file # and then declares the variables listed to stdout # # known issues: # * sourced file could re-define 'echo' # * just fails if a value has a ' in it [ -f "$1" ] || return 0 tick="'" sh -c ' __tick=$tick __file=$1; __desc=$2; __unset__="__unset__" shift 2 __vars="$*" readonly __tick __file __desc __vars . "${__file}" if [ $? -ne 0 ]; then echo "failed source \"${__file}\" ($__desc)" 1>&2 return 1 fi set -e echo "desc=${__tick}${__desc}${__tick}" for var in ${__vars}; do eval val=\${${var}-${__unset__}} || { echo "eval of $var failed"; exit 1; } [ "${val#*${__tick}}" = "${val}" ] || { echo "variable \"$var\" had single tick in it. fail"; exit 1; } [ "${val}" = "${__unset__}" ] || echo "$var=${__tick}${val}${__tick}" done ' -- "$@"}readcfgd() { local cfg_d="$1" # this kind of stinks, each VARIABLE goes into global scope local or="" or_cfgdisk="" _RET_desc_oroot="" _RET_desc_cfgdisk="" set +f for f in "${cfg_d}"/*; do . "$f" || fail "failed reading $f" [ "$or" != "${overlayroot}" ] && _RET_desc_oroot="$desc" [ "${or_cfgdisk}" != "${overlayroot_cfgdisk}" ] && _RET_desc_cfgdisk="$desc" or=${overlayroot} or_cfgdisk=${overlayroot_cfgdisk} done set -f}fix_upstart_overlayfs() { # inotify events on an overlayfs underlay do not propogate through # a newly created overlay. This causes job creation and deletion issues # for upstart, which uses inotify on /etc/init. So ensure that the overlay # explicitly has a /etc/init (LP: #1213925) local root="$1" local initctl="$root/sbin/initctl" local eifile="/etc/init/.overlayfs-upstart-helper" [ -e "$initctl" -o -L "$initctl" ] || return 0 [ -d "$root/etc/init" ] || return 0 echo "#upstart needs help for overlayfs (LP: #1213925)." \ > "$root/$eifile" || { log_fail "failed to write $root/$eifile"; return 1; } debug "created $eifile under $root (LP: #1213925)"}cfgd="${TEMP_D}/configs"mkdir -p "${cfgd}" || fail "failed to create tempdir"trap cleanup EXIT# collect the different config locations into a file# write individual config files in $cfgd that contain{echo "desc='builtin'"echo "overlayroot=''"echo "overlayroot_cfgdisk='disabled'"} > "$cfgd/00-builtin"write_kernel_cmdline_cfg "${cfgd}/90-kernel" || fail "failed to read kernel command line!"parse_cfg "/conf/conf.d/overlayroot" "initramfs config" \ "$VARIABLES" > "${cfgd}/10-initramfs" || fail "failed parsing initramfs config"parse_cfg "${ROOTMNT}/etc/overlayroot.conf" "$ROOT/etc/overlayroot.conf" \ "$VARIABLES" > "${cfgd}/20-root-config" || fail "failed parsing root config"parse_cfg "${ROOTMNT}/etc/overlayroot.local.conf" \ "$ROOT/etc/overlayroot.local.conf" \ "$VARIABLES" > "${cfgd}/30-root-local-config" || fail "failed parsing root config"# now read the trusted configs, to see if overlayroot_cfgdisk is setreadcfgd "$cfgd" || fail "reading configs failed"used_desc="${_RET_desc_oroot}"[ -n "${_RET_desc_cfgdisk}" ] && debug "${_RET_desc_cfgdisk} set cfgdisk='${overlayroot_cfgdisk}'"# if one of the trusted configs above gave us set the overlayroot_cfgdisk# variable, then look for such a device and read a config from it.cfgdisk=0if [ "${overlayroot_cfgdisk:-disabled}" != "disabled" ] && get_cfg "${overlayroot_cfgdisk}" "${TEMP_D}/cfgdisk"; then desc=${_RET} parse_cfg "${TEMP_D}/cfgdisk" "${desc}" "$VARIABLES" \ > "${cfgd}/80-cfgdisk" || fail "reading config from ${desc} failed" used_desc="${_RET_desc_oroot}" # now read the parsed configs again. readcfgd "$cfgd" || fail "reading configs failed" [ -n "${_RET_desc_cfgdisk}" ] && debug "${_RET_desc_cfgdisk} set cfgdisk=${overlayroot_cfgdisk}" [ -n "${_RET_desc_oroot}" ] && debug "${_RET_desc_oroot} set overlayroot=${overlayroot}"fiopts=""cfgmsg="${used_desc:+ (per ${used_desc})}"case "${overlayroot:-disabled}" in tmpfs|tmpfs:*) mode="tmpfs" opts="${overlayroot#tmpfs}"; opts=${opts#:} ;; /dev/*|device:*) case "$overlayroot" in /dev/*) opts="dev=${overlayroot}";; *) opts="${overlayroot#device:}";; esac dev_setup "${opts}" || fail "failed setup overlay for ${overlayroot} [$opts]${cfgmsg}" mode="device" device="$_RET_DEVICE" ;; crypt:*) mode="crypt" opts=${overlayroot#crypt:} crypto_setup "${opts}" || fail "failed setup crypt for ${overlayroot}${cfgmsg}" device="$_RET_DEVICE" ;; disabled) debug "overlayroot disabled${cfgmsg}" exit 0;; *) fail "invalid value for overlayroot: ${overlayroot}${cfgmsg}" exit 0;;esacparse_string "$opts" "," _RET_common_swap=${_RET_common_swap:-0}recurse=${_RET_common_recurse:-1}OVERLAYROOT_DEBUG=${_RET_common_debug:-${OVERLAYROOT_DEBUG}}dir_prefix=${_RET_common_dir:-"/overlay"}debug "swap=$swap recurse=$recurse debug=$OVERLAYROOT_DEBUG dir=$dir_prefix"debug "device=$device mode=$mode"[ "$swap" = "0" -o "$swap" = "1" ] || fail "invalid setting for swap: $swap. must be '0' or '1'"[ "$recurse" = "0" -o "$recurse" = "1" ] || fail "invalid setting for recurse: $recurse. must be '0' or '1'"log_warn "configuring overlayroot with mode=$mode opts='$opts' per $used_desc"# overlayroot_driver *could* be defined in one of the configs above# but we're not documenting that.overlayroot_driver=${overlayroot_driver:-overlayfs}# settings based on overlayroot_driverworkdir=""case "${overlayroot_driver}" in overlayfs|overlay) mount_type="overlay" mount_opts="-o lowerdir=${root_ro},upperdir=${root_rw}/${dir_prefix}" # 3.18+ require 'workdir=' option. case "$(uname -r)" in 2*|3.1[01234567]*|3.[0-9].*) :;; *) workdir="${dir_prefix%/}-workdir" mount_opts="${mount_opts},workdir=${root_rw}/${workdir}";; esac mount_opts="${mount_opts} overlay ${ROOTMNT}" ;; aufs) mount_type="aufs" mount_opts="-o dirs=${root_rw}/${dir_prefix}:${root_ro}=ro aufs-root ${ROOTMNT}" ;; *) log_fail "invalid overlayroot driver: ${overlayroot_driver}" panic "$MYTAG" ;;esac# check if kernel module existsmodprobe -qb "${overlayroot_driver}" || fail "missing kernel module ${overlayroot_driver}"# make the mount point on the init root fs ${root_rw}mkdir -p "${root_rw}" || fail "failed to create ${root_rw}"# make the mount point on the init root fs ${root_ro}mkdir -p "${root_ro}" || fail "failed to create ${root_ro}"# mount the backing device to $root_rwif [ "$mode" = "tmpfs" ]; then # mount a tmpfs using the device name tmpfs-root mount -t tmpfs tmpfs-root "${root_rw}" || fail "failed to create tmpfs"else # dev or crypto mount "$device" "${root_rw}" || fail "failed mount backing device $device"fimkdir -p "${root_rw}/${dir_prefix}" || fail "failed to create ${dir_prefix} on ${device}"[ -z "$workdir" ] || mkdir -p "$root_rw/${workdir}" || fail "failed to create workdir '$workdir' on ${device}"# root is mounted on ${ROOTMNT}, move it to ${ROOT_RO}.mount -o move "${ROOTMNT}" "${root_ro}" || fail "failed to move root away from ${ROOTMNT} to ${root_ro}"# there is nothing left at ${ROOTMNT} now. So for any error we get we should# either do recovery to restore ${ROOTMNT} for drop to a initramfs shell using# "panic". Otherwise the boot process is very likely to fail with even more# errors and leave the system in a wired state.# mount virtual fs ${ROOTMNT} with rw-fs ${root_rw} on top or ro-fs ${root_ro}.debug mount -t "$mount_type" $mount_optsmount -t "$mount_type" $mount_optsif [ $? -ne 0 ]; then log_fail "failed to create new ro/rw layered ${ROOTMNT}" log_fail "mount command was: mount -t $mount_type $mount_opts" # do recovery and try resoring the mount for ${ROOTMNT} mount -o move ${root_ro} ${ROOTMNT} if [ $? -ne 0 ]; then # thats bad, drop to shell to let the user try fixing this log_fail "RECOVERY_ERROR: failed to move $root_ro back to ${ROOTMNT}" panic "$MYTAG" fi exit 0fi# now the real root fs is on ${root_ro} of the init file system, our# layered root fs is set up at ${ROOTMNT}. So we can write anywhere in# {ROOTMNT} and the changes will end up in ${root_rw} while ${root_ro} it# not touched. However ${root_ro} and ${root_rw} are on the initramfs root# fs, which will be removed an replaced by ${ROOTMNT}. Thus we must move# ${root_ro} and ${root_rw} to the rootfs visible later, ie.# ${ROOTMNT}${root_ro} and ${ROOTMNT}${root_ro}. Since the layered ro/rw# is already up, these changes also end up on ${root_rw} while ${root_ro}# is not touched.# move mount from ${root_ro} to ${ROOTMNT}${root_ro}mkdir -p "${ROOTMNT}/${root_ro}"mount -o move ${root_ro} "${ROOTMNT}${root_ro}" || fail "failed to move ${root_ro} to ${ROOTMNT}${root_ro}"# move mount from ${root_rw} to ${ROOTMNT}${root_rw}[ -d ${ROOTMNT}${root_rw} ] || mkdir -p ${ROOTMNT}${root_rw}mount -o move "${root_rw}" "${ROOTMNT}${root_rw}" || fail "failed to move ${root_rw} to ${ROOTMNT}${root_rw}"# technically, everything is set up nicely now. Since ${ROOTMNT} had beend# mounted read-only on the initfamfs already, ${ROOTMNT}${root_ro} is it,# too. Now we init process could run - but unfortunately, we may have to# prepare some more things here.# Basically, there are two ways to deal with the read-only root fs. If the# system is made aware of this, things can be simplified a lot. If it is# not, things need to be done to our best knowledge.## So we assume here, the system does not really know about our read-only# root fs.## Let's deal with /etc/fstab first. It usually contains an entry for the# root fs, which is no longer valid now. We have to remove it and add our# new ${root_ro} entry.# Remember we are still on the initramfs root fs here, so we have to work# on ${ROOTMNT}/etc/fstab. The original fstab is# ${ROOTMNT}${root_ro}/etc/fstab.cat <<EOF >${ROOTMNT}/etc/fstab## This fstab is in an overlayfs. The real one can be found at# ${root_ro}/etc/fstab# The original entry for '/' and other mounts have been updated to be placed# under $root_ro.# To permanently modify this (or any other file), you should change-root into# a writable view of the underlying filesystem using:# sudo overlayroot-chroot#EOF[ $? -eq 0 ] || log_fail "failed to modify /etc/fstab (step 1)"overlayrootify_fstab ""${ROOTMNT}${root_ro}/etc/fstab"" "$root_ro" \ "$root_rw" "$dir_prefix" "$recurse" "$swap" >> "${ROOTMNT}/etc/fstab" || log_fail "failed to modify /etc/fstab (step 2)"# we have to make the directories in ${root_rw} because if they do not# exist, then the 'upper=' argument to overlayfs will fail.for d in ${_RET}; do mkdir -p "${ROOTMNT}/$d"doneif [ "${overlayroot_driver}" = "overlayfs" ]; then fix_upstart_overlayfs "$ROOTMNT" || log_fail "failed to fix upstart for overlayfs"fi# if / is supposed to be mounted read-only (cmdline with 'ro')# then mount our overlayfs as read-only just to be more normalread cmdline < /proc/cmdlinecmdline=" $cmdline "if [ "${cmdline#* ro }" != "$cmdline" ]; then mount -o remount,ro "$ROOTMNT" || log_fail "failed to remount overlayroot read-only" debug "mounted $ROOTMNT read-only per kernel cmdline"fimsg="configured root with '$overlayroot' using ${overlayroot_driver} per"msg="$msg ${used_desc}"log_success "$msg"exit 0# vi: ts=4 noexpandtab I modified the /usr/share/initramfs-tools/hooks/overlayroot: diff --suppress-common-lines -r -y ./usr/share/initramfs-tools/hooks/overlayroot /usr/share/initramfs-tools/hooks/overlayroot manual_add_modules overlayfs | manual_add_modules overlay Configuration I added a file named /etc/overlayroot.local.conf (instead of modifying /etc/overlayroot.conf): overlayroot_cfgdisk="disabled" overlayroot="tmpfs" overlayroot_driver="overlay" Chrooting to R/W Last but not least, I had to modify the overlayroot-chroot executable diff --suppress-common-lines -r -y ./usr/sbin/overlayroot-chroot /usr/sbin/overlayroot-chroot overlay=$(grep -m1 "^overlayroot / overlayfs " /proc/ | overlay=$(grep -m1 "^overlay / overlay " /proc/mounts #!/bin/sh## overlayroot-chroot - chroot wrapper script for overlayroot# Copyright © 2012 Dustin Kirkland## Authors: Dustin Kirkland## This program is free software: you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation, version 3 of the License.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program. If not, see <http://www.gnu.org/licenses/>.set -eset -f # disable path expansionREMOUNTS=""error() { printf "ERROR: $@\n" 1>&2}fail() { [ $# -eq 0 ] || error "$@"; exit 1; }info() { printf "INFO: $@\n" 1>&2}get_lowerdir() { #overlay=$(grep -m1 "^overlayroot / overlayfs " /proc/mounts) || overlay= overlay=$(grep -m1 "^overlay / overlay " /proc/mounts) || overlay= if [ -n "${overlay}" ]; then lowerdir=${overlay##*lowerdir=} lowerdir=${lowerdir%%,*} if mountpoint "${lowerdir}" >/dev/null; then _RET="${lowerdir}" else fail "Unable to find the overlayroot lowerdir" fi else fail "Unable to find an overlayroot filesystem" fi}clean_exit() { local mounts="$1" rc=0 d="" lowerdir="" mp="" for d in ${mounts}; do if mountpoint ${d} >/dev/null; then umount ${d} || rc=1 fi done for mp in $REMOUNTS; do mount -o remount,ro "${mp}" || error "Note that [${mp}] is still mounted read/write" done [ "$2" = "return" ] && return ${rc} || exit ${rc}}# Try to find the overlayroot filesystemget_lowerdirlowerdir=${_RET}recurse_mps=$(awk '$1 ~ /^\/dev\// && $2 ~ starts { print $2 }' \ starts="^$lowerdir/" /proc/mounts)mounts=for d in proc run sys; do if ! mountpoint "${lowerdir}/${d}" >/dev/null; then mount -o bind "/${d}" "${lowerdir}/${d}" || fail "Unable to bind /${d}" mounts="$mounts $lowerdir/$d" trap "clean_exit \"${mounts}\" || true" EXIT HUP INT QUIT TERM fidone# Remount with read/writefor mp in "$lowerdir" $recurse_mps; do mount -o remount,rw "${mp}" && REMOUNTS="$mp $REMOUNTS" || fail "Unable to remount [$mp] writable"doneinfo "Chrooting into [${lowerdir}]"chroot ${lowerdir} "$@"# Clean up mounts on exitclean_exit "${mounts}" "return"trap "" EXIT HUP INT QUIT TERM# vi: ts=4 noexpandtab Fast-forward I attached an archive with the modifications. Using tar zxvf overlayroot-debian-lauhub.tar.gz -C / after package installation should do the trick overlayroot-debian.tar.gz 1
chradev Posted November 13, 2016 Posted November 13, 2016 Hi Lauhub, I successfully made overlayroot work under Debian Jessie. Ubuntu package I installed overlayroot_0.27ubuntu1.2_all.deb package Why did you base your solution on Debian Jessie and Ubuntu overlayroot package while it is available in Xenial? As I have noted here the problem is probably the same in both cases. Any way I will try your modification a.s.a.p. Best regards Chris
lauhub Posted November 19, 2016 Author Posted November 19, 2016 Hi, Why did you base your solution on Debian Jessie and Ubuntu overlayroot package while it is available in Xenial? Because all the work I have already done on my current project is based on Jessie
dottgonzo Posted November 21, 2016 Posted November 21, 2016 you can use unionfs-fuse, available on debian, that do the same stuff. I'm using it right now on several boards. You have to search on google how to conf it, but basically you need to unite the static and read-only /etc and /var with a temporary rw /etc /var that is mounted as tempfs file system. unionfs do that for you if you configure /usr/local/bin/mount_unionfs with echo '[ -z "$1" ] && exit 1 || DIR=$1' > /usr/local/bin/mount_unionfsecho 'ROOT_MOUNT=$(grep -v "^#" /etc/fstab | awk '"'"'$2=="/" {print substr($4,1,2)}'"'"')' >> /usr/local/bin/mount_unionfsecho 'if [ "$ROOT_MOUNT" != "ro" ]; then' >> /usr/local/bin/mount_unionfsecho '/bin/mount --bind ${DIR}_org ${DIR}' >> /usr/local/bin/mount_unionfsecho 'else' >> /usr/local/bin/mount_unionfsecho '/bin/mount -t tmpfs ramdisk ${DIR}_rw' >> /usr/local/bin/mount_unionfsecho '/usr/bin/unionfs-fuse -o cow,allow_other,suid,dev,nonempty ${DIR}_rw=RW:${DIR}_org=RO ${DIR}' >> /usr/local/bin/mount_unionfsecho 'fi' >> /usr/local/bin/mount_unionfs chmod +x /usr/local/bin/mount_unionfs and then switch to ro the partitions and add on fstab mount_unionfs /etc fuse defaults 0 0 mount_unionfs /var fuse defaults 0 0 before it you need to create those 2 direcories and copy the static /etc and /var on them, you can do that by: cp -al /etc /etc_orgmv /var /var_orgmkdir /etc_rwmkdir /var /var_rw
chradev Posted November 23, 2016 Posted November 23, 2016 Thanks for your suggestion Dottgonzo, you can use unionfs-fuse, available on debian, that do the same stuff. I'm using it right now on several boards... I tried it and succeeded out-of-the-box following your description also applied for RPi. Of course there was a small obstacle because in my use case rootfs options are transferred from uboot to kernel via its command line but it can be solved by a small change in mount_unionfs script. Fortunately, simplicity and long life time (9+ years) of the project are more important for me at the moment than possible speed lost. The only question for now is can we rely on Debian support to continue? Best regards Chris
chradev Posted November 23, 2016 Posted November 23, 2016 Thanks Dottgonzo, on unionfs rely many projects, relax After your words I am definitely more peaceful. Best regards Chris
alyubomirov Posted December 18, 2016 Posted December 18, 2016 Does this work? How is it done? Is there any guide for dummies?
hardvk0 Posted December 28, 2016 Posted December 28, 2016 Does this work? How is it done? Is there any guide for dummies?Ubuntu xenial is not valid for me for missing php5 and something else, but if it works overlayroot. I really liked how it works.In debian jessie with kernel 4.8.4 it works but I want to freeze the system. I just need to make overlayroot work.PD: On behalf of google, sorry for the translation.
gailu Posted February 10, 2017 Posted February 10, 2017 @lauhub I am facing SD card corruption problem on power off (https://forum.armbian.com/index.php/topic/3427-armbian-sd-card-image-gets-corrupted-when-power-off-without-proper-shutdown/. I am following your steps to make my rootfs read only with overlayfs debian jessie/orange pi zero. However I am not able to make it readonly. If I save any file and reboot file is present. There are some differences from your setup so looking forward to your help comment. Your scripts in the attachment is expected to be applied on overlayroot_0.27ubuntu1.2_all.deb however this package is replaced with overlayroot_0.27ubuntu1.3_all.deb and it has some changes so not able to apply your changes directly. If you have a copy of overlayroot_0.27ubuntu1.2_all.deb can you please provide it Or if you have any suggestion to make it work on overlayroot_0.27ubuntu1.3_all.deb please let me know. Based on diffs you provided I made changes, while I do not see any error, I am not able to make it readonly. Thanks
sufialhussaini Posted May 1, 2017 Posted May 1, 2017 Same problem with me @gailu. Were you able to solve this? I too couldn't find overlayroot_0.27ubuntu1.2_all.deb and I just can't get overlayroot_0.27ubuntu1.3_all.deb to work with modifications based on @lauhub's patch.
Kamil Krawczyk Posted June 3, 2017 Posted June 3, 2017 Solusion for overlayroot in Armbian Jessie: 1) install overlayroot_0.27ubuntu1.4_all.deb dpkg -i overlayroot_0.27ubuntu1.4_all.deb 2) add following lines to /usr/share/initramfs-tools/hooks/overlayroot file: copy_exec /bin/grep /bin copy_exec /usr/bin/stat /bin copy_exec /bin/echo /bin This will load missing tools required by /usr/share/initramfs-tools/scripts/init-bottom/overlayroot script. 3) replace all "mount --move" with "mount -o move" in /usr/share/initramfs-tools/scripts/init-bottom/overlayroot file. 4) update-initramfs -u :-) overlayroot_0.27ubuntu1.4_all.deb 3
Recommended Posts