mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 07:22:33 +00:00
9851d4b6ce
OpenWrt uses a lot of (b)ash scripts for initial setup. This isn't the best solution as they almost never consider syncing files / data. Still this is what we have and we need to try living with it. Without proper syncing OpenWrt can easily get into an inconsistent state on power cut. It's because: 1. Actual (flash) inode and data writes are not synchronized 2. Data writeback can take up to 30 seconds (dirty_expire_centisecs) 3. ubifs adds extra 5 seconds (dirty_writeback_centisecs) "delay" Some possible cases (examples) for new files: 1. Power cut during 5 seconds after write() can result in all data loss 2. Power cut happening between 5 and 35 seconds after write() can result in empty file (inode flushed after 5 seconds, data flush queued) Above affects e.g. uci-defaults. After executing some migration script it may get deleted (whited out) without generated data getting actually written. Power cut will result in missing data and deleted file. There are three ways of dealing with that: 1. Rewriting all user-space init to proper C with syncs 2. Trying bash hacks (like creating tmp files & moving them) 3. Adding sync and hoping for no power cut during critical section This change introduces the last solution that is the simplest. It reduces time during which things may go wrong from ~35 seconds to probably less than a second. Of course it applies only to IO operations performed before /etc/init.d/boot . It's probably the stage when the most new files get created. All later changes are usually done using smarter C apps (e.g. busybox or uci) that creates tmp files and uses rename() that is expected to be atomic. Signed-off-by: Rafał Miłecki <rafal@milecki.pl> Acked-by: Hauke Mehrtens <hauke@hauke-m.de> Acked-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
56 lines
1.3 KiB
Bash
Executable File
56 lines
1.3 KiB
Bash
Executable File
#!/bin/sh /etc/rc.common
|
|
# Copyright (C) 2006-2011 OpenWrt.org
|
|
|
|
START=10
|
|
STOP=90
|
|
|
|
uci_apply_defaults() {
|
|
. /lib/functions/system.sh
|
|
|
|
cd /etc/uci-defaults || return 0
|
|
files="$(ls)"
|
|
[ -z "$files" ] && return 0
|
|
mkdir -p /tmp/.uci
|
|
for file in $files; do
|
|
( . "./$(basename $file)" ) && rm -f "$file"
|
|
done
|
|
uci commit
|
|
}
|
|
|
|
boot() {
|
|
[ -f /proc/mounts ] || /sbin/mount_root
|
|
[ -f /proc/jffs2_bbc ] && echo "S" > /proc/jffs2_bbc
|
|
|
|
mkdir -p /var/lock
|
|
chmod 1777 /var/lock
|
|
mkdir -p /var/log
|
|
mkdir -p /var/run
|
|
mkdir -p /var/state
|
|
mkdir -p /var/tmp
|
|
mkdir -p /tmp/.uci
|
|
chmod 0700 /tmp/.uci
|
|
touch /var/log/wtmp
|
|
touch /var/log/lastlog
|
|
mkdir -p /tmp/resolv.conf.d
|
|
touch /tmp/resolv.conf.d/resolv.conf.auto
|
|
ln -sf /tmp/resolv.conf.d/resolv.conf.auto /tmp/resolv.conf
|
|
grep -q debugfs /proc/filesystems && /bin/mount -o noatime -t debugfs debugfs /sys/kernel/debug
|
|
grep -q bpf /proc/filesystems && /bin/mount -o nosuid,nodev,noexec,noatime,mode=0700 -t bpf bpffs /sys/fs/bpf
|
|
grep -q pstore /proc/filesystems && /bin/mount -o noatime -t pstore pstore /sys/fs/pstore
|
|
[ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe
|
|
|
|
/sbin/kmodloader
|
|
|
|
[ ! -f /etc/config/wireless ] && {
|
|
# compat for bcm47xx and mvebu
|
|
sleep 1
|
|
}
|
|
|
|
/bin/config_generate
|
|
uci_apply_defaults
|
|
sync
|
|
|
|
# temporary hack until configd exists
|
|
/sbin/reload_config
|
|
}
|