🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

+33
View File
@@ -0,0 +1,33 @@
#!/bin/sh
#docker run -d --rm \
exec docker run -it --rm \
--stop-signal SIGINT \
--stop-timeout 30 \
--security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
--cap-add=SYS_ADMIN \
--cap-add=SYS_CHROOT \
--cap-drop=MKNOD \
--cap-add=LEASE \
--cap-add=SETGID \
--cap-add=SETUID \
--cap-add=NET_ADMIN \
--cap-add=NET_RAW \
--cap-add=NET_BIND_SERVICE \
-v /usr/share/shadowrt/container:/shadowrt:ro \
--entrypoint /shadowrt/entrypoint.sh \
--name istoreos-shadow0 \
--hostname istoreos-shadow0 \
--label creator=istoreos-shadow \
--label com.istoreos.shadow.id=istoreos-shadow0 \
--dns 172.17.0.1 \
--dns 8.8.8.8 \
-p 8080:80 \
-p 17681:7681 \
-v /dev/net:/dev/net \
--device /dev/fuse:/dev/fuse \
-v /rom:/rom:ro \
-v /mnt:/mnt:rshared \
-v /mnt/data/is-diff/0:/overlay:rw \
alpine
@@ -0,0 +1,42 @@
#!/bin/sh
# env
# IP_PROTO=dhcp|static
# IP_ADDRESS=ipv4/prefixlen
# IP_GATEWAY=ipv4
# IP_DNS="dns1 dns2 ..."
# DHCP_SERVER=on|off
[ -s /rom/etc/openwrt_release ] || {
echo "/rom is not a openwrt rootfs!" >&2
exit 1
}
[ -e /rom/.dockerenv ] && {
echo "/rom is already a docker container rootfs!" >&2
exit 1
}
CONSOLE=`readlink /proc/$$/fd/2`
if echo "$CONSOLE" | grep -q '^/dev/'; then
[ -e /dev/kmsg ] || ln -s "$CONSOLE" /dev/kmsg
[ -e /dev/console ] || ln -s "$CONSOLE" /dev/console
else
[ -e /dev/kmsg ] || ln -s /proc/self/fd/2 /dev/kmsg
[ -e /dev/console ] || ln -s /dev/null /dev/console
fi
mount --make-private /
mount --make-private /rom
mount --make-private /overlay
if unshare -m --propagation unchanged true 2>/dev/null; then
exec unshare -m --propagation unchanged /shadowrt/s1-unshared.sh "$CONSOLE"
elif unshare -m --propagation shared true 2>/dev/null; then
exec unshare -m --propagation shared /shadowrt/s1-unshared.sh "$CONSOLE"
else
echo "unshare does not support propagation flag, fallback to default" >&2
exec unshare -m /shadowrt/s1-unshared.sh "$CONSOLE"
fi
Whitespace-only changes.
@@ -0,0 +1,32 @@
#!/bin/sh
CFG=$1
IP_PROTO=dhcp
IP_ADDRESS=
[ -n "$CFG" ] || CFG=/etc/board.json
. /lib/functions/uci-defaults.sh
board_config_update
json_is_a network object && exit 0
ucidef_set_hostname "iStoreOS"
ucidef_set_timezone "CST-8"
ucidef_set_ntpserver "0.cn.pool.ntp.org" "1.cn.pool.ntp.org" "2.cn.pool.ntp.org" "3.cn.pool.ntp.org"
if [ "static" = "$IP_PROTO" -a -n "$IP_ADDRESS" ]; then
eval $(ipcalc.sh "$IP_ADDRESS")
ucidef_set_interface_lan "eth0"
ucidef_set_interface "lan" ipaddr "$IP" netmask "$NETMASK"
else
ucidef_set_interface_lan "eth0" "dhcp"
fi
board_config_flush
[ -s "$CFG" ] || return 1
@@ -0,0 +1,12 @@
# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.
# Internal uci firewall chains are flushed and recreated on reload, so
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
# special user chains, e.g. input_wan_rule or postrouting_lan_rule.
# workaround route shortcut issue in shadowrt clones on openwrt 22.03
iptables -t mangle -I PREROUTING -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -m socket -j ACCEPT || true
ip6tables -t mangle -I PREROUTING -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -m socket -j ACCEPT || true
@@ -0,0 +1,38 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
set quickstart.main.disable_dhns=1
commit quickstart
EOF
uci -q batch <<-EOF >/dev/null
set argon.@global[0].primary='#5b7e99'
set argon.@global[0].dark_primary='#337d8c'
commit argon
EOF
GATEWAY=
DNS=
DHCP_SERVER=
[ -n "$GATEWAY" ] && uci set network.lan.gateway="$GATEWAY"
if [ -n "$DNS" ]; then
for dns in $DNS; do
uci add_list network.lan.dns="$dns"
done
fi
uci commit network
uci -q batch <<-EOF >/dev/null
del dhcp.lan.ra
del dhcp.lan.ra_slaac
del dhcp.lan.ra_flags
del dhcp.lan.dhcpv6
EOF
if [ -z "$DHCP_SERVER" ]; then
uci set dhcp.lan.ignore='1'
fi
uci commit dhcp
exit 0
@@ -0,0 +1,8 @@
do_sysinfo_generic() {
mkdir -p /tmp/sysinfo
echo "docker" > /tmp/sysinfo/board_name
echo "Docker" > /tmp/sysinfo/model
}
boot_hook_add preinit_main do_sysinfo_generic
@@ -0,0 +1,4 @@
#!/bin/sh
echo "ignore '$0 $@' in container" >&2
exit 0
@@ -0,0 +1 @@
/usr/libexec/kmodloader
@@ -0,0 +1 @@
/usr/libexec/kmodloader
@@ -0,0 +1,127 @@
# > getbootdisk
# mmcblk0
_getbootdisk()
{
local rootpart="`grep -Fm1 ' - squashfs /dev/root ' /proc/self/mountinfo | cut -d' ' -f3`"
[ -z "$rootpart" ] && return 1
local devpath="`readlink /sys/dev/block/$rootpart`"
[ -z "$devpath" ] && return 1
rootpart="${devpath##*/}"
devpath="${devpath%%/$rootpart}"
local rootdisk="${devpath##*/}"
echo "$rootdisk"
}
# > getbootdisk_lvm
# dm-0
_getbootdisk_lvm()
{
local rootpart
if [ -e /rom/note ]; then
rootpart="`grep -Fm1 ' / / ' /proc/self/mountinfo | grep -F ' - squashfs ' | cut -d' ' -f3`"
else
rootpart="`grep -Fm1 ' / /rom ' /proc/self/mountinfo | grep -F ' - squashfs ' | cut -d' ' -f3`"
fi
[ -z "$rootpart" ] && return 1
local major=${rootpart%%:*}
local minor=${rootpart##*:}
minor="$(( $minor & 0xfffc ))"
local devpath="`readlink /sys/dev/block/$major:$minor`"
[ -z "$devpath" ] && return 1
local rootdisk="${devpath##*/}"
echo "$rootdisk"
}
# > getpartofdisk sda 3
# sda3
# > getpartofdisk mmcblk0 3
# mmcblk0p3
_getpartofdisk()
{
local disk="$1" offset="$2" part
if [[ "$offset" = 0 ]]; then
echo "$disk"
else
part="$disk"
echo "$part" | grep -q '^.*[0-9]$' && part="${part}p"
part="${part}"$(( ${offset} ))
if [ ! -b "/dev/$part" ]; then
# lvm
local line
local MAJOR MINOR DEVNAME DEVTYPE
while read line; do
export -n "$line"
done < "/sys/block/$disk/uevent"
local devpath="`readlink /sys/dev/block/$MAJOR:$(($MINOR + $offset))`"
if [ -n "$devpath" ]; then
part="${devpath##*/}"
fi
fi
echo "$part"
fi
return 0
}
_get_overlay_partition_default()
{
local bootdisk="`_getbootdisk`"
[ -z "$bootdisk" ] && {
log "getbootdisk failed, try lvm"
bootdisk="`_getbootdisk_lvm`"
}
[ -z "$bootdisk" ] && {
log "getbootdisk_lvm failed"
return 1
}
if [ ! -e "/sys/block/$bootdisk/uevent" ]; then
log "/sys/block/$bootdisk/uevent does not exist"
return 1
fi
if [ -e /rom/note ]; then
# we are in mount_root if /rom/note exists
cat "/sys/block/$bootdisk/uevent" > /tmp/.bootdisk
fi
local overlay_dev="`_getpartofdisk $bootdisk 3`"
[ -z "$overlay_dev" ] && {
log "getpartofdisk $bootdisk 3 failed"
return 1
}
OVERLAY_DEV="/dev/$overlay_dev"
return 0
}
_get_overlay_partition_fallback()
{
log "get_overlay_partition_fallback"
rm -f /tmp/.bootdisk >/dev/null 2>&1
local overlay_dev=$(
. /lib/functions.sh
. /lib/upgrade/common.sh
export_bootdevice && export_partdevice overlay_dev 3 && echo $overlay_dev
)
[ -z "$overlay_dev" ] && return 1
OVERLAY_DEV="/dev/$overlay_dev"
return 0
}
get_overlay_partition()
{
if [ -e /.dockerenv ]; then
if mountpoint -q /overlay; then
log "Overlay partition in Docker was mounted /overlay"
OVERLAY_DEV="/overlay"
OVERLAY_FS="DIR"
FSTYPE="DIR"
[ -f "/overlay/.reset" ] && FSTYPE="RESET"
return 0
else
log "No overlay partition in Docker"
return 1
fi
fi
_get_overlay_partition_default || _get_overlay_partition_fallback || {
log "Unable to determine overlay partition"
return 1
}
return 0
}
@@ -0,0 +1,98 @@
#!/bin/sh
# Copyright (C) 2022 jjm2473@gmail.com
DEFAULT_OVERLAY_FS="ext4"
OVERLAY_LABEL="etc"
OVERLAY_FS=${DEFAULT_OVERLAY_FS}
OVERLAY_DEV=
log() {
echo "$1" >&2
}
inlog() {
$@ >&2
}
. /lib/functions/istoreos-boot.sh
CONFIRM=n
REBOOT=n
confirm()
{
[ "$1" = "y" ] && return 0
echo "This will erase all settings and remove any installed packages. Are you sure? [N/y]"
read CONFIRM
[ "$CONFIRM" = "y" -o "$CONFIRM" = "Y" ] && return 0
return 1
}
do_reset_nofs()
{
get_overlay_partition || exit 1
if [ -z "$OVERLAY_DEV" ]; then
echo "Unable to determine overlay partition" >&2
return 1
fi
if [ "RESET" = "$FSTYPE" ]; then
echo "Already resetted" >&2
return 1
fi
if [ "DIR" = "$FSTYPE" ]; then
touch /$OVERLAY_DEV/.reset
sync /$OVERLAY_DEV
return 0
fi
# if ! blkid -o device -t LABEL=$OVERLAY_LABEL "$OVERLAY_DEV" >/dev/null; then
# echo "Overlay partition $OVERLAY_DEV not labeled $OVERLAY_LABEL" >&2
# return 1
# fi
echo "RESET000" | dd of="$OVERLAY_DEV" bs=512 count=1 conv=notrunc,sync,fsync 2>/dev/null
echo 3 > /proc/sys/vm/drop_caches
return 0
}
do_reset_ext_overlay()
{
[ -d /ext_overlay ] && mountpoint -q /ext_overlay || return 0
rm -f /ext_overlay/etc/.extroot-uuid
touch /ext_overlay/.reset
sync /ext_overlay
}
do_reset()
{
if [ -f /.recovery_mode ]; then
mount_root || ( echo "/overlay mount failed!" ; exit 1 )
rm -rf /overlay/upper
mkdir /overlay/upper
sync /overlay
else
do_reset_nofs
do_reset_ext_overlay
fi
if [ -f /lib/upgrade/keep.d/grub ]; then
cat /lib/upgrade/keep.d/grub | while read; do
rm -f "$REPLY"
done
fi
[ "$REBOOT" = "y" ] && reboot
exit 0
}
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-y) CONFIRM=y ;;
-r) REBOOT=y ;;
esac
shift
done
confirm $CONFIRM && do_reset
exit 0
@@ -0,0 +1 @@
/sbin/firstboot
@@ -0,0 +1,549 @@
#!/bin/sh
# Copyright (C) 2010 OpenWrt.org
# Copyright (C) 2020-2023 jjm2473@gmail.com
DEFAULT_OVERLAY_FS="ext4"
OVERLAY_LABEL="etc"
OVERLAY_FS=${DEFAULT_OVERLAY_FS}
OVERLAY_DEV=
log() {
echo "<1>mount_root: $1" >/dev/kmsg
}
inlog() {
$@ >/dev/kmsg 2>&1
}
. /lib/functions/istoreos-boot.sh
validate_overlay_partition()
{
log "- mount overlayfs -"
# Check device existence
[ ! -e "$OVERLAY_DEV" ] && \
log "overlay: $OVERLAY_DEV not found" && return 1
[ -n "$FSTYPE" ] && return 0
# get filesystem
if dd if="$OVERLAY_DEV" bs=5 count=1 2>/dev/null | grep -qF RESET; then
FSTYPE=RESET
log "overlay: $OVERLAY_DEV marked as RESET, format later"
return 0
elif blkid -o device -t LABEL=$OVERLAY_LABEL "$OVERLAY_DEV" >/dev/null; then
FSTYPE=`blkid -o value -s TYPE $OVERLAY_DEV`
else
FSTYPE=RESET
log "overlay: $OVERLAY_DEV not labeled, format later"
return 0
fi
if [ -z "$FSTYPE" ]; then
log "overlay: no valid filesystem"
else
log "overlay: filesystem $FSTYPE found"
fi
}
format_overlay_partition()
{
local RET
[ "$FSTYPE" = "$OVERLAY_FS" ] && return 0
log "overlay: try to format $OVERLAY_DEV as $OVERLAY_FS partition"
case "$OVERLAY_FS" in
ext4)
mkfs.ext4 -q -j -FF -L $OVERLAY_LABEL "$OVERLAY_DEV"
RET=$?
[ $RET -ne 0 ] || tune2fs -o '^user_xattr,^acl' -r 1024 "$OVERLAY_DEV"
;;
DIR)
rm -rf "$OVERLAY_DEV/upper" "$OVERLAY_DEV/work" "$OVERLAY_DEV/.reset"
RET=0
;;
*)
log "overlay: unhandled fs type : $OVERLAY_FS"
RET=1
;;
esac
if [ $RET -ne 0 ]; then
log "overlay: format command failed ret: $RET"
else
echo 3 > /proc/sys/vm/drop_caches
FSTYPE=$OVERLAY_FS
fi
return $RET
}
check_overlay_partition()
{
case "$FSTYPE" in
ext4)
fsck.ext4 -y "$OVERLAY_DEV" >/dev/null
sync
resize2fs "$OVERLAY_DEV"
sync
;;
esac
}
mount_overlay_partition()
{
local RET
[ "DIR" = "$OVERLAY_FS" ] && return 0
mount -t $OVERLAY_FS "$OVERLAY_DEV" /overlay
RET=$?
[ $RET -ne 0 ] && \
log "overlay: failed to mount $OVERLAY_DEV as $OVERLAY_FS partition ret: $RET" && return $RET
log 'overlay: successfully mounted'
}
OVERLAYFS_XATTR=""
is_overlayfs_use_xattr() {
# only linux 4.13 or above
[ -z "$OVERLAYFS_XATTR" ] && OVERLAYFS_XATTR=$([ "0$((`uname -r | cut -d. -f1-2 | sed 's/\./ * 100 + /'`))" -ge 413 ] && echo 1 || echo 0)
[ "$OVERLAYFS_XATTR" = "1" ]
}
ROOTFS_UUID=""
rootfs_uuid() {
if [ -z "$ROOTFS_UUID" ]; then
ROOTFS_UUID=`block info | grep -Fw 'MOUNT="/"' | sed -E 's/.* UUID="([^"]+)" .*/\1/'`
[ -z "$ROOTFS_UUID" ] && [ -e /.dockerenv ] && ROOTFS_UUID=rel-`md5sum /etc/openwrt_release | cut -d' ' -f1`
[ -z "$ROOTFS_UUID" ] && ROOTFS_UUID="UNKNOWN"
fi
echo "$ROOTFS_UUID"
}
update_overlay_lower_uuid() {
local realuuid=`rootfs_uuid`
local lastuuid="NULL"
if [ -f "$1/.rootfs-uuid" ]; then
lastuuid=`cat "$1/.rootfs-uuid"`
fi
if [ "$realuuid" != "$lastuuid" ]; then
echo "$realuuid" >"$1/.rootfs-uuid"
return 0
fi
return 1
}
clean_overlayfs_origin() {
local line
cd "$1"
getfattr -R -P -h --match='trusted.overlay.origin' . 2>/dev/null | grep '^# file: ' | cut -c9- | while read; do
line="$REPLY"
setfattr -x "trusted.overlay.origin" -h "$line" 2>/dev/null
done
cd - >/dev/null 2>&1
}
clean_overlayfs_redundant_opaque() {
local line
cd "$1"
getfattr -R -P -h --match='trusted.overlay.opaque' . 2>/dev/null | grep '^# file: ' | cut -c9- | while read; do
line="$REPLY"
[ -z "$line" -o -d "/$line" ] && continue
setfattr -x "trusted.overlay.opaque" -h "$line" 2>/dev/null
done
cd - >/dev/null 2>&1
}
clean_overlayfs_redundant_whiteout_marker()
{
local line
cd "$1"
find upper -xdev -path 'upper/opt' -prune ! -type d -o -type c -perm 0 -user 0 -group 0 | sed 's#^upper/#/#g' | while read; do
line="$REPLY"
[ ! -e "$line" -a \( -z "$2" -o ! -e "$2/upper$line" \) ] && \
rm -f "upper$line"
done
cd - >/dev/null 2>&1
}
clean_overlayfs_redundant_whiteout_marker_luci()
{
local line
[ -d "$1/upper/usr/lib/lua/luci" ] || return 0
cd "$1/upper/usr/lib/lua"
find luci -xdev -type c -perm 0 -user 0 -group 0 | while read; do
line="$REPLY"
[ ! -e "/usr/lib/lua/$line" -a \( -z "$2" -o ! -e "$2/upper/usr/lib/lua/$line" \) ] && \
rm -f "$line"
done
cd - >/dev/null 2>&1
}
clean_os_version_files()
{
cd "$1"
rm -f upper/etc/openwrt_release \
upper/etc/openwrt_version \
upper/usr/lib/os-release
cd - >/dev/null 2>&1
}
nonconf_files_of_pkg() {
local pkgname="$1"
if [ -s /usr/lib/opkg/info/${pkgname}.conffiles ]; then
grep -hvxFf /usr/lib/opkg/info/${pkgname}.conffiles \
/usr/lib/opkg/info/${pkgname}.list
else
cat /usr/lib/opkg/info/${pkgname}.list
fi
}
clean_pkg_content() {
local overlay="$1"
local pkgname="$2"
local line
if [ -f /usr/lib/opkg/info/${pkgname}.control ]; then
if [ -f /usr/lib/opkg/info/${pkgname}.list ]; then
nonconf_files_of_pkg "${pkgname}" | grep -v '^/etc/uci-defaults/' | while read; do
line="$REPLY"
rm -f "$overlay/upper/${line}"
done
rm -f $overlay/upper/usr/lib/opkg/info/${pkgname}.list
fi
rm -f $overlay/upper/usr/lib/opkg/info/${pkgname}.*
fi
}
pkg_depends_rec() {
local pkgname="$1"
local line
local dep
local deps
echo "${pkgname}" | grep -q '^kmod-' && return
if [ -f /usr/lib/opkg/info/${pkgname}.control -a ! -f /tmp/reset_core_packages/${pkgname} ]; then
deps=`grep '^Depends: ' /usr/lib/opkg/info/${pkgname}.control | sed -e 's/^Depends: //' -e 's/ ([^)]*)//g' -e 's/,/ /g'`
touch /tmp/reset_core_packages/${pkgname}
for dep in $deps ; do
pkg_depends_rec "$dep"
done
fi
}
list_core_packages()
{
local pkg
mkdir -p /tmp/reset_core_packages
for pkg in \
luci-compat luci-lua-runtime luci-lib-base luci-base uhttpd luci-ssl-openssl luci-ssl \
rpcd procd \
netifd dnsmasq-full dnsmasq firewall4 \
block-mount \
curl \
ttyd dropbear kernel
do
pkg_depends_rec $pkg
done
}
reset_core_packages()
{
local overlay="$1"
local running_ver=$(grep 'DISTRIB_RELEASE=' /etc/openwrt_release 2>/dev/null | sed -E "s/.*='(.+)'.*/\1/")
[ "v$(cat "$overlay/.upgrading" 2>/dev/null)" = "v$running_ver" ] && return
local pkg
[ -d /tmp/reset_core_packages ] || list_core_packages
echo "Reset packages in $overlay: `ls /tmp/reset_core_packages/ | xargs echo`" | dd bs=960 2>/dev/null
ls /tmp/reset_core_packages/ | while read; do
pkg="$REPLY"
clean_pkg_content "$overlay" $pkg
done
}
clean_kmods()
{
local DUMMY_VERSION=0.0.0-r1
if [ -d "$1/upper/usr/lib/opkg/info" ]; then
local compat=`grep -m1 '^Version: ' /usr/lib/opkg/info/kernel.control | sed 's/^Version: //'`
if [ -n "$compat" ]; then
cd "$1/upper/usr/lib/opkg/info"
# ignore processed
grep -Lm1 '^Version: '$DUMMY_VERSION'$' kmod-*.control 2>/dev/null | sed 's/.control$//' > /tmp/cand_kmods.txt
if [ -s /tmp/cand_kmods.txt ]; then
grep -LFm1 "kernel (=$compat)" kmod-*.control | sed 's/.control$//' | grep -Fxf /tmp/cand_kmods.txt > /tmp/del_kmods.txt
grep -lFm1 "kernel (=$compat)" kmod-*.control | sed 's/.control$//' | grep -Fxf /tmp/cand_kmods.txt > /tmp/safe_kmods.txt
else
> /tmp/del_kmods.txt
fi
rm -f /tmp/cand_kmods.txt
# remove duplicated
if [ -s /tmp/safe_kmods.txt ]; then
( cd /usr/lib/opkg/info && ls kmod-*.control 2>/dev/null | sed 's/.control$//' ) | grep -Fxf /tmp/safe_kmods.txt >> /tmp/del_kmods.txt
fi
rm -f /tmp/safe_kmods.txt
if [ -s /tmp/del_kmods.txt ]; then
echo "Clean kmods in $1: `cat /tmp/del_kmods.txt | xargs echo`" | dd bs=960 2>/dev/null
cat /tmp/del_kmods.txt | sed 's/$/.list/' | xargs cat | sed "s#^/#$1/upper/#" | xargs -r rm -f
cat /tmp/del_kmods.txt | xargs -rn1 sh -c 'rm -f $0.list $0.prerm $0.postinst'
cat /tmp/del_kmods.txt | sed 's/$/.control/' | xargs -r sed -i 's/^Version: .*$/Version: '$DUMMY_VERSION'/g'
fi
rm -f /tmp/del_kmods.txt
cd - >/dev/null 2>&1
return 0
fi
else
return 0
fi
# rm -rf $1/upper/lib/modules $1/upper/etc/modules-boot.d \
# $1/upper/etc/modules.d $1/upper/usr/lib/opkg/info/kmod-* \
# $1/upper/usr/lib/opkg/info/kernel.* 2>/dev/null
}
prepare_primary_overlay()
{
if [ -f /overlay/.reset ]; then
rm -rf /overlay/upper /overlay/work
rm -f /overlay/.reset
sync /overlay
fi
}
prepare_primary_overlay_after_merge()
{
if [ -d /overlay/upper ]; then
if update_overlay_lower_uuid /overlay || [ -f /overlay/.upgrading ] ; then
clean_os_version_files /overlay
reset_core_packages /overlay
touch /overlay/.upgrading
fi
if [ -f /overlay/.upgrading -o -f /overlay/.merged ] ; then
if is_overlayfs_use_xattr ; then
clean_overlayfs_origin /overlay/upper
clean_overlayfs_redundant_opaque /overlay/upper
fi
clean_overlayfs_redundant_whiteout_marker /overlay
else
clean_overlayfs_redundant_whiteout_marker_luci /overlay
fi
else
update_overlay_lower_uuid /overlay
fi
if [ -f /overlay/upper/usr/lib/opkg/.upgrading ]; then
clean_kmods /overlay
fi
rm -f /overlay/.upgrading /overlay/.merged
mkdir -p /overlay/upper /overlay/work
}
pivot_root_to_overlayfs()
{
# pivot
mount --move /proc /mnt/proc
pivot_root /mnt /mnt/rom || return 1
mount --move /rom/dev /dev
mount --move /rom/tmp /tmp
mount --move /rom/sys /sys
mount --move /rom/overlay /overlay
}
mount_extroot()
{
[ "DIR" = "$OVERLAY_FS" ] && return 1
[ -f /overlay/upper/etc/config/fstab ] || return 1
# let `block extroot` read /overlay/upper/etc/config/fstab
mount --bind /overlay/upper/etc/config /etc/config || return 1
block extroot
local ret=$?
umount /etc/config
return $ret
}
apply_overlayfs_opaque() {
local line
local dest="$2"
cd "$1"
if is_overlayfs_use_xattr; then
getfattr -R -P -h --match='trusted.overlay.opaque' upper 2>/dev/null | grep '^# file: ' | cut -c9- | while read; do
line="$REPLY"
rm -rf "$dest/$line"
done
fi
find upper -xdev -type c | while read; do
line="$REPLY"
rm -rf "$dest/$line"
done
cd - >/dev/null 2>&1
}
prepare_ext_overlay()
{
local newoverlaydir=$1
local overlaydir=$2
if [ -f "$newoverlaydir/.reset" ]; then
rm -rf "$newoverlaydir/upper"
rm -f "$newoverlaydir/.commit" "$newoverlaydir/.reset"
elif [ -f "$newoverlaydir/.commit" ]; then
if [ -d "$newoverlaydir/upper" ]; then
apply_overlayfs_opaque "$newoverlaydir" "$overlaydir"
fi
cp -a "$newoverlaydir/upper/." "$overlaydir/upper" && {
touch "$overlaydir/.merged"
rmdir "$overlaydir/upper/ext_overlay"
rm -rf "$newoverlaydir/upper"
mkdir -m 0755 -p "$newoverlaydir/upper/ext_overlay"
}
rm -f "$newoverlaydir/.commit"
else
prepare_primary_overlay_after_merge
touch "$overlaydir/.clean"
if [ -f "$newoverlaydir/upper/usr/lib/opkg/.upgrading" ]; then
clean_kmods "$newoverlaydir"
fi
if [ -f "$newoverlaydir/.upgrading" ]; then
clean_os_version_files "$newoverlaydir"
reset_core_packages "$newoverlaydir"
is_overlayfs_use_xattr && clean_overlayfs_origin "$newoverlaydir/upper"
fi
if [ -d "$newoverlaydir/upper" -a \( -f "$newoverlaydir/upper/usr/lib/opkg/.upgrading" -o ! -f "$overlaydir/.sandbox" \) ]; then
clean_overlayfs_redundant_whiteout_marker "$newoverlaydir" "$overlaydir"
else
clean_overlayfs_redundant_whiteout_marker_luci "$newoverlaydir" "$overlaydir"
fi
fi
rm -f "$newoverlaydir/.upgrading"
( mkdir -m 0755 -p $newoverlaydir/upper/ext_overlay && \
mkdir -m 0755 -p $newoverlaydir/work ) || return 1
return 0
}
prepare_mnt()
{
rm -rf /tmp/reset_core_packages
prepare_primary_overlay
if mount_extroot && mountpoint -q /tmp/extroot/mnt; then
local dir
for dir in proc dev tmp sys overlay rom root; do
mkdir -m 0755 /tmp/extroot/mnt/$dir
done
if mount --move /tmp/extroot/mnt /mnt; then
# writeable extroot existed, we don't need overlay
umount /tmp/extroot/overlay
return 0
fi
umount /tmp/extroot/mnt
fi
local lowerdir=/
local overlaydir=/overlay
if mountpoint -q /tmp/extroot/overlay; then
# use ext overlay as upper layer
local newoverlaydir=/tmp/extroot/overlay
if [ `mountpoint -x "$OVERLAY_DEV"` != `mountpoint -d $newoverlaydir` ] && \
prepare_ext_overlay $newoverlaydir $overlaydir && \
mount --move /tmp/extroot/overlay /ext_overlay; then
lowerdir=$overlaydir/upper:$lowerdir
overlaydir=/ext_overlay
else
umount /tmp/extroot/overlay
fi
fi
if [ -f /overlay/.clean ]; then
rm -f /overlay/.clean
else
prepare_primary_overlay_after_merge
fi
rm -rf /tmp/reset_core_packages
mount -o noatime,lowerdir=$lowerdir,upperdir=$overlaydir/upper,workdir=$overlaydir/work \
-t overlay "overlayfs:/overlay" /mnt \
|| return 1
if [ "$overlaydir" = "/ext_overlay" ]; then
[ -f "/overlay/.sandbox" ] || touch "/overlay/.sandbox"
else
rm -f "/overlay/.sandbox"
fi
sync
return 0
}
post_extroot()
{
mountpoint -q /rom/ext_overlay && mount --move /rom/ext_overlay /ext_overlay
mountpoint -q /tmp/extroot/overlay && umount /tmp/extroot/overlay
rmdir /tmp/extroot/overlay
mountpoint -q /tmp/extroot/mnt && umount /tmp/extroot/mnt
rmdir /tmp/extroot/mnt
rmdir /tmp/extroot
mountpoint -q /rom/dev && umount /rom/dev
}
do_mount_overlayfs()
{
local SHAREDMNT=false
[ ! -e /rom/note ] && return 0
inlog get_overlay_partition || return 1
inlog validate_overlay_partition || return 1
inlog format_overlay_partition || return 1
inlog check_overlay_partition
inlog mount_overlay_partition || return 1
# if we are in recovery mode, just skip pivot_root
if [ -f /.recovery_mode ]; then
rm -f /rom/note >/dev/null 2>&1
return 0
fi
if [ -e /.dockerenv ] && mountpoint -q /mnt; then
SHAREDMNT=true
mkdir /dev/mnt
mount --move /mnt /dev/mnt
fi
inlog prepare_mnt || return 1
inlog pivot_root_to_overlayfs || return 1
post_extroot >/dev/null 2>&1
if $SHAREDMNT; then
mount --rbind /dev/mnt /mnt
mount --make-rprivate /dev/mnt
umount -R /dev/mnt || /bin/umount -r -l /dev/mnt
rmdir /dev/mnt
else
inlog mount --make-shared -t tmpfs -o size=4M tmpfs /mnt
fi
return 0
}
[ -n "$1" -a "$1" != "start" ] || ( do_mount_overlayfs && exit 0 )
@@ -0,0 +1,31 @@
#!/bin/sh
mkdir -p /var/lock
for service in adb-enablemodem appfilter dockerd gpio_switch hd-idle \
kmods kmods-unload lcdsimple led lm-sensors luci-fan \
mdadm modemmanager odhcpd smartd sysfixtime sysfsutils sysntpd \
tuning_net umount usbmode usbmuxd wan_drop zprintk zram
do
[ -x /etc/init.d/$service ] && /etc/init.d/$service disable
done
for file in \
/etc/board.d \
/etc/config/appfilter \
/etc/config/kmods \
/etc/init.d/appfilter \
/etc/init.d/umount \
/ext_overlay \
/lib/upgrade/ota.sh \
/lib/upgrade/platform.sh \
/lib/board \
/sbin/ujail \
/usr/lib/opkg/info/luci-app-oaf.control \
/usr/libexec/fan-control \
/usr/sbin/sandbox
do
rm -rf "$file"
done
rm -rf /var/lock/*.lock
@@ -0,0 +1,149 @@
#!/bin/sh
NEWROOT=/rom
PATCHROM=/tmp/rom
SHAREDMNT=false
mountpoint -q /mnt && SHAREDMNT=true
mount --make-private /
mount --make-private /sys
mount --make-rprivate /tmp 2>/dev/null
mount --make-rprivate /proc
mount --make-private /rom
mount --make-private /overlay
mount -t tmpfs -o ro,relatime tmpfs /sys/block
mount -t tmpfs -o size=1M tmpfs /tmp
# make all private except /mnt
mkdir -p $PATCHROM
mount --bind / $PATCHROM
mount --move /proc $PATCHROM/proc
# move /mnt to tmproot/mnt
$SHAREDMNT && mount --move /mnt $PATCHROM/mnt
pivot_root $PATCHROM $PATCHROM/tmp || exit 1
# old root now in /tmp
mount --make-rprivate /tmp
$SHAREDMNT && mount --move /mnt /tmp/mnt
mount --move /proc /tmp/proc
pivot_root /tmp /tmp$PATCHROM || exit 1
umount $PATCHROM
# umount annoying docker rootfs
if $SHAREDMNT; then
OLDROOTFS=`grep -m1 "^overlay / overlay" /proc/1/mounts | sed -nE 's#^.*,workdir=(/mnt/.*)/work 0 0$#\1/merged#p'`
if [ -n "$OLDROOTFS" ]; then
echo "umount $OLDROOTFS" >&2
mount --make-rprivate "$OLDROOTFS"
umount -l "$OLDROOTFS"
fi
fi
# patch rom
LOWERDIR=/rom
mkdir -p /tmp/tmp/shadowrt /tmp/patch/upper/usr/libexec /tmp/patch/work
cp -a /rom/sbin/kmodloader /tmp/patch/upper/usr/libexec/
for o in 0 2; do
cp -a /shadowrt/overwrite/$o/. /tmp/patch/upper/
done
OVERLAYFS_UUID=",uuid=null"
if ! mount -o noatime,lowerdir=$LOWERDIR,upperdir=/tmp/patch/upper,workdir=/tmp/patch/work,xino=off$OVERLAYFS_UUID \
-t overlay "/dev/root" $PATCHROM ; then
OVERLAYFS_UUID=""
mount -o noatime,lowerdir=$LOWERDIR,upperdir=/tmp/patch/upper,workdir=/tmp/patch/work,xino=off \
-t overlay "/dev/root" $PATCHROM || exit 1
fi
mount --bind /tmp/tmp $PATCHROM/tmp
mount --bind /shadowrt $PATCHROM/tmp/shadowrt
chroot $PATCHROM /tmp/shadowrt/s1-chroot-patchrom.sh
umount $PATCHROM/tmp/shadowrt
umount $PATCHROM/tmp
rm -rf /tmp/tmp
set_default_ip()
{
local ip=$1
[ -n "$ip" ] || return 1
echo "pass ip address to shadow: $ip" >&2
sed -i -e "s/^IP_PROTO=.*/IP_PROTO=static/g" -e "s#^IP_ADDRESS=.*#IP_ADDRESS=$ip#g" "$PATCHROM/bin/board_detect"
}
set_default_gw_dns()
{
local gw=$1
local dns="$2"
echo "pass gateway/dns to shadow: $gw/$dns" >&2
sed -i -e "s/^GATEWAY=.*/GATEWAY=$gw/g" -e "s/^DNS=.*/DNS='$dns'/g" "$PATCHROM/etc/uci-defaults/zzz-dockerenv"
}
set_default_network()
{
if [ "dhcp" != "$IP_PROTO" ]; then
# ip
local ip=$IP_ADDRESS
[ -z "$ip" ] && ip=`ip addr show dev eth0 | grep -m1 'inet ' | head -1 | sed -nE 's#.*inet ([0-9\.]*)/([0-9]*) .*#\1/\2#p'`
set_default_ip "$ip"
# gateway dns
local gw dns
gw=$IP_GATEWAY
dns="$IP_DNS"
[ -z "$gw" ] && gw="$(route -n | grep -m1 '^0\.0\.0\.0 .* eth0$' | head -1 | xargs -r sh -c 'echo $1')"
[ -z "$dns" ] && dns="$(grep '^nameserver ' /etc/resolv.conf | grep -oE '\d+\.\d+\.\d+\.\d+' | xargs -r sh -c 'echo $@' ignored)"
set_default_gw_dns "$gw" "$dns"
[ "on" = "$DHCP_SERVER" ] && sed -i -e "s/^DHCP_SERVER=.*/DHCP_SERVER=1/g" "$PATCHROM/etc/uci-defaults/zzz-dockerenv"
fi
}
set_default_network
export -n IP_PROTO IP_ADDRESS IP_GATEWAY IP_DNS DHCP_SERVER
unset IP_PROTO IP_ADDRESS IP_GATEWAY IP_DNS DHCP_SERVER
umount $PATCHROM
# make sysctl net.* writable
mount --bind -o rw /proc/sys/net /proc/sys/net
# workaround busybox mount bug (alpine 3.22.2 arm64/v8)
grep '^proc /proc' /proc/mounts > /tmp/proconly.txt
sh -c 'mount --bind /tmp/proconly.txt /proc/$$/mounts && exec mount -o rw,remount /proc/sys/net'
rm -f /tmp/proconly.txt
PROCD_VER=`grep -o '^Version: [0-9]*' /rom/usr/lib/opkg/info/procd.control | cut -d' ' -f2`
if [ -n "$PROCD_VER" -a "$PROCD_VER" -lt 2024 ]; then
# workaround procd < 2024 infite loop on resolving rootfs type, e.g. `ubus call system board`
echo "overwrite /proc/$$/mounts for bug on procd v$PROCD_VER" >&2
echo "/dev/root /rom squashfs ro,relatime 0 0" > /tmp/procd_mounts.txt
cat /proc/mounts | grep -v '^tmpfs /tmp tmpfs' | grep -v ' /shadowrt ' >> /tmp/procd_mounts.txt
mount --bind /tmp/procd_mounts.txt /proc/$$/mounts
rm -f /tmp/procd_mounts.txt
fi
# mount openwrt rootfs
mount -o ro,noatime,lowerdir=/tmp/patch/upper:$LOWERDIR,xino=off$OVERLAYFS_UUID \
-t overlay "/dev/root" /rom || exit 1
umount /tmp
mount --bind -o private /overlay $NEWROOT/overlay
$SHAREDMNT && mount --move /mnt $NEWROOT/mnt
mount --move /dev $NEWROOT/dev
mount --move /sys $NEWROOT/sys
mount --move /shadowrt $NEWROOT/tmp/busy
mount --move /proc $NEWROOT/proc
pivot_root $NEWROOT $NEWROOT/tmp/oldroot || exit 1
cd /
exec /tmp/busy/s2-wrtroot.sh "$1" "/tmp/oldroot"
@@ -0,0 +1,19 @@
#!/bin/sh
cd /
umount -R $2 || umount -l $2
umount -l /tmp/busy
if echo "$1" | grep -q '^/dev/' ; then
/bin/sh -i </dev/console >/dev/console 2>&1 &
fi
echo "exec /sbin/init" >&2
export -n TZ SHLVL HOSTNAME OLDPWD PWD USER LOGNAME
unset TZ SHLVL HOSTNAME OLDPWD PWD USER LOGNAME
export HOME=/ TERM=linux PATH=/sbin:/bin
exec /sbin/init </dev/null