mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-30 08:15:13 +08:00
🌴 Sync 2026-03-05 23:51:42
This commit is contained in:
1 parent
97c049ed0a
commit
0acff03804
14253 files changed
+3893239
No files matched your search
+267
@@ -0,0 +1,267 @@
|
||||
#!/bin/sh
|
||||
# Author jjm2473@gmail.com
|
||||
|
||||
ACTION="${1}"
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local id="`uci get shadowrt.@instance[0].id 2>/dev/null`"
|
||||
local data="`uci get shadowrt.@instance[0].data 2>/dev/null`"
|
||||
local mnt="`uci get shadowrt.@instance[0].mnt 2>/dev/null`"
|
||||
local proto=`uci get shadowrt.@instance[0].proto 2>/dev/null`
|
||||
local address=`uci get shadowrt.@instance[0].address 2>/dev/null`
|
||||
local gateway=`uci get shadowrt.@instance[0].gateway 2>/dev/null`
|
||||
local dns="`uci get shadowrt.@instance[0].dns 2>/dev/null`"
|
||||
local dhcp_server=`uci get shadowrt.@instance[0].dhcp_server 2>/dev/null`
|
||||
local ports="`uci get shadowrt.@instance[0].ports 2>/dev/null`"
|
||||
|
||||
if [ -z "$data" ]; then
|
||||
echo "data path is empty!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -s /rom/etc/openwrt_release ] || {
|
||||
echo "/rom is not a openwrt rootfs!" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ "$proto" = "static" ]; then
|
||||
if [ -z "$address" ]; then
|
||||
echo "static ip requires address!" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
/etc/init.d/docker-lan start || {
|
||||
echo "create docker-lan bridge failed!" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
local alpine_image="alpine:3.22.2"
|
||||
if ! docker image inspect -f '{}' "$alpine_image" >/dev/null 2>&1; then
|
||||
echo "pulling alpine image $alpine_image ..."
|
||||
docker pull "$alpine_image" || exit 1
|
||||
fi
|
||||
|
||||
if [ -d "$data/$id" ]; then
|
||||
echo "WARNING: $data/$id already exists, may use old data." >&2
|
||||
fi
|
||||
|
||||
local config="{\"id\":\"$id\",\"data\":\"$data\",\"mnt\":\"$mnt\",\"proto\":\"$proto\",\"address\":\"$address\",\"gateway\":\"$gateway\",\"dns\":\"$dns\",\"dhcp_server\":\"$dhcp_server\",\"ports\":\"$ports\"}"
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d \
|
||||
--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 \
|
||||
--network docker-lan \
|
||||
-v /usr/share/shadowrt/container:/shadowrt:ro \
|
||||
--entrypoint /shadowrt/entrypoint.sh \
|
||||
-v /dev/net:/dev/net \
|
||||
--device /dev/fuse:/dev/fuse \
|
||||
-v /rom:/rom:ro \
|
||||
--label creator=shadowrt \
|
||||
--name '$id' \
|
||||
--hostname '$id' \
|
||||
--label 'com.shadowrt.config=$config' \
|
||||
-v '$data/$id/overlay:/overlay:rw' "
|
||||
|
||||
[ -n "$proto" ] && cmd="$cmd -e IP_PROTO=$proto"
|
||||
if [ "$proto" = "static" ]; then
|
||||
[ -n "$address" ] && cmd="$cmd -e IP_ADDRESS=$address"
|
||||
[ -n "$gateway" ] && cmd="$cmd -e IP_GATEWAY=$gateway"
|
||||
[ -n "$dns" ] && cmd="$cmd -e 'IP_DNS=$dns'"
|
||||
fi
|
||||
[ "$dhcp_server" = "1" -o "$dhcp_server" = "on" ] && cmd="$cmd -e DHCP_SERVER=on"
|
||||
if [ -n "$ports" ]; then
|
||||
for p in $ports; do
|
||||
cmd="$cmd -p $p:$p"
|
||||
done
|
||||
fi
|
||||
if [ -n "$dns" ]; then
|
||||
for d in $dns; do
|
||||
cmd="$cmd --dns $d"
|
||||
done
|
||||
fi
|
||||
|
||||
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
if [ "$mnt" = "1" -o "$mnt" = "on" ]; then
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rshared"
|
||||
fi
|
||||
cmd="$cmd $alpine_image"
|
||||
|
||||
echo "stopping existing container..."
|
||||
docker stop "$id" >/dev/null 2>&1
|
||||
docker rm -f "$id"
|
||||
|
||||
echo "starting shadowrt instance $id..."
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
}
|
||||
|
||||
do_ls() {
|
||||
local name state ip
|
||||
|
||||
echo "["
|
||||
docker ps -a -f 'label=creator=shadowrt' --format '{{.Names}} {{.State}}' | sort -n | while read name state; do
|
||||
ip=
|
||||
if [ "$state" = "running" ]; then
|
||||
ip=`docker exec "$name" ip addr show dev br-lan | grep -m1 'inet ' | head -1 | sed -nE 's#.*inet ([0-9\.]*)/([0-9]*) .*#\1#p'`
|
||||
if [ -z "$ip" ]; then
|
||||
docker exec "$name" test -e /etc/openwrt_release -a ! -e /rom/note || state="starting"
|
||||
fi
|
||||
fi
|
||||
echo '{"name":"'"$name"'","status":"'"$state"'","ip":"'"$ip"'"},'
|
||||
#docker container inspect -f '{"name":"'"$name"'","status":"'"$state"'","config":{{index .Config.Labels "com.shadowrt.config"}},"ip":"'"$ip"'"},' "$name"
|
||||
done | head -c -2
|
||||
echo ""
|
||||
echo "]"
|
||||
}
|
||||
|
||||
do_clone() {
|
||||
local config_json="`docker container inspect -f '{{index .Config.Labels "com.shadowrt.config"}}' "$1"`"
|
||||
[ -z "$config_json" ] && {
|
||||
echo "container $1 not found!" >&2
|
||||
return 1
|
||||
}
|
||||
{
|
||||
echo "delete shadowrt.@instance[0]"
|
||||
echo "add shadowrt instance"
|
||||
echo "$config_json" | jsonfilter -e 'id=$.id' \
|
||||
-e 'data=$.data' \
|
||||
-e 'mnt=$.mnt' \
|
||||
-e 'proto=$.proto' \
|
||||
-e 'address=$.address' \
|
||||
-e 'gateway=$.gateway' \
|
||||
-e 'dns=$.dns' \
|
||||
-e 'dhcp_server=$.dhcp_server' \
|
||||
-e 'ports=$.ports' | sed -e 's/; /\n/g' | sed -e 's/^export /set shadowrt.@instance[0]./g'
|
||||
echo "commit shadowrt"
|
||||
} | uci batch
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
do_reset_network() {
|
||||
local name="$1"
|
||||
local running=false
|
||||
local shell
|
||||
|
||||
docker exec "$name" test -e /etc/openwrt_release -a ! -e /rom/note >/dev/null 2>&1 && running=true
|
||||
if $running; then
|
||||
shell="exec docker exec -i -w / '$name' /bin/sh"
|
||||
else
|
||||
docker stop "$name" >/dev/null 2>&1
|
||||
local data="`docker container inspect -f '{{index .Config.Labels "com.shadowrt.config"}}' "$name" | jsonfilter -e '$.data'`"
|
||||
local dir="$data/$name/overlay/upper"
|
||||
[ -d "$dir" ] || return 0
|
||||
shell="cd '$dir' && exec /bin/sh"
|
||||
fi
|
||||
{
|
||||
cat <<-EOF
|
||||
for f in etc/config/network etc/board.json; do
|
||||
rm -f "\$f"
|
||||
done
|
||||
EOF
|
||||
if $running; then
|
||||
cat <<-EOF
|
||||
/bin/board_detect
|
||||
/bin/config_generate
|
||||
/bin/sh -c ". /rom/etc/uci-defaults/zzz-dockerenv"
|
||||
/bin/sh -c '. /rom/etc/uci-defaults/12_network-generate-ula'
|
||||
/etc/init.d/network restart
|
||||
sleep 2
|
||||
EOF
|
||||
else
|
||||
echo 'rm -f etc/uci-defaults/zzz-dockerenv etc/uci-defaults/12_network-generate-ula'
|
||||
fi
|
||||
} | sh -c "$shell"
|
||||
}
|
||||
|
||||
check_all_ready() {
|
||||
local names="$1"
|
||||
local name
|
||||
local ret=0
|
||||
for name in $names; do
|
||||
if ! docker exec "$name" test -e /etc/openwrt_release -a ! -e /rom/note; then
|
||||
ret=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
return $ret
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install/Replace a instance"
|
||||
echo " ls List all instances"
|
||||
echo " rm/start/stop/restart {ID} Remove/Start/Stop/Restart the instance"
|
||||
echo " clone {ID} Clone an existing instance to uci"
|
||||
echo " rmd {ID} Remove an existing instance and its data"
|
||||
echo " reset_network {ID} Reset network configuration inside the instance"
|
||||
echo " status Dummy status for taskd"
|
||||
|
||||
}
|
||||
|
||||
case "${ACTION}" in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"rm" | "rmd")
|
||||
if [ -n "$1" ]; then
|
||||
docker stop "$1" >/dev/null 2>&1
|
||||
if [ "$ACTION" = "rmd" ]; then
|
||||
data="`docker container inspect -f '{{index .Config.Labels "com.shadowrt.config"}}' "$1" | jsonfilter -e '$.data'`"
|
||||
[ -n "$data" ] && rm -rf "$data/$1"
|
||||
fi
|
||||
docker rm -f "$1"
|
||||
fi
|
||||
;;
|
||||
"reset_network")
|
||||
if [ -n "$1" ]; then
|
||||
do_reset_network "$1"
|
||||
fi
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
if [ -n "$1" ]; then
|
||||
docker "${ACTION}" $1
|
||||
if [ "$ACTION" = "start" -o "$ACTION" = "restart" ]; then
|
||||
sleep 2
|
||||
for i in $(seq 1 5); do
|
||||
check_all_ready "$1" && break
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
"clone")
|
||||
if [ -n "$1" ]; then
|
||||
do_clone "$1" || exit 1
|
||||
fi
|
||||
;;
|
||||
"status")
|
||||
# hack, return empty string, so lib-taskd thinks container is not installed
|
||||
exit 0
|
||||
;;
|
||||
"ls")
|
||||
do_ls
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-shadowrt": {
|
||||
"description": "Grant UCI access for luci-app-shadowrt",
|
||||
"read": {
|
||||
"uci": [ "shadowrt" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "shadowrt" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -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.
+32
@@ -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
|
||||
|
||||
+38
@@ -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
|
||||
+4
@@ -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
|
||||
Whitespace-only changes.
Whitespace-only changes.
Executable
+127
@@ -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
|
||||
}
|
||||
+98
@@ -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
|
||||
+1
@@ -0,0 +1 @@
|
||||
/sbin/firstboot
|
||||
+549
@@ -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
|
||||
|
||||
Reference in new issue
Block a user