summaryrefslogtreecommitdiff
path: root/package/base-files/files/bin/firstboot
blob: 8453b300966902a2832e23eb8d396c5a0776bd53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/bin/sh
. /etc/functions.sh

partname="rootfs_data"
mtdpart="$(find_mtd_part $partname)"

rom=$(awk '/squashfs/ {print $2}' /proc/mounts)
jffs=$(awk '/jffs2/ {print $2}' /proc/mounts)

dupe() { # <new_root> <old_root>
	cd $1
	echo -n "creating directories... "
	{
		cd $2 
		find . -xdev -type d
		echo "./dev ./jffs ./mnt ./proc ./tmp"
		# xdev skips mounted directories
		cd $1 
	} | xargs mkdir -p
	echo "done"

	echo -n "setting up symlinks... "
	for file in $(cd $2; find . -xdev -type f;); do
		case "$file" in
		./rom/note) ;; #nothing
		./etc/config*|\
		./usr/lib/opkg/info/*) cp -af $2/$file $file;;
		*) ln -sf /rom/${file#./*} $file;;
		esac
	done
	for file in $(cd $2; find . -xdev -type l;); do
		cp -af $2/${file#./*} $file
	done
	echo "done"
}

pivot() { # <new_root> <old_root>
	mount -o move /proc $1/proc && \
	pivot_root $1 $1$2 && {
		mount -o move $2/dev /dev
		mount -o move $2/tmp /tmp
		mount -o move $2/sys /sys 2>&-
		mount -o move $2/jffs /jffs 2>&-
		return 0
	}
}

fopivot() { # <rw_root> <ro_root> <dupe?>
	root=$1
	{
		mount -t mini_fo -o base=/,sto=$1 "mini_fo:$1" /mnt 2>&- && root=/mnt
	} || {
		[ "$3" = "1" ] && {
		mount | grep "on $1 type" 2>&- 1>&- || mount -o bind $1 $1
		dupe $1 $rom
		}
	}
	pivot $root $2
}

ramoverlay() {
	mkdir -p /tmp/root
	fopivot /tmp/root /rom 1
}

# invoked as an executable
[ "${0##*/}" = "firstboot" ] && {

	[ -z "$mtdpart" ] && {
		echo "MTD partition not found."
		exit 1
	}

	[ -z "$rom" ] && {
		echo "You do not have a squashfs partition; aborting"
		echo "(firstboot cannot be run on jffs2 based firmwares)"
		exit 1
	}

	[ "$1" = "switch2jffs" ] && {
		mount "$mtdpart" /rom/jffs -t jffs2 || exit

		# try to avoid fs changing while copying
		mount -o remount,ro none / 2>&-

		# copy ramoverlay to jffs2
		echo -n "copying files ... "
		cp -a /tmp/root/* /rom/jffs 2>&-
		echo "done"

		# switch back to squashfs (temporarily)
		# and park the ramdisk ontop of /tmp/root
		pivot /rom /mnt
		mount -o move /mnt /tmp/root

		# /jffs is the overlay
		# /rom is the readonly
		fopivot /jffs /rom

		# try to get rid of /tmp/root
		# this will almost always fail
		umount /tmp/root 2>&-

		exit 0
	}

	# script run manually
	[ \! -z "$jffs" ] && {
		echo "firstboot has already been run"
		echo "jffs2 partition is mounted, only resetting files"
		grep mini_fo /proc/filesystems >&-
		[ $? != 0 ] && {
			dupe $jffs $rom
			exit 0
		} || { 
			rm -rf $jffs/* 2>&-
			mount -o remount $jffs / 2>&-
			exit 0
		}
	}

	mtd erase "$partname"
	mount "$mtdpart" /jffs -t jffs2
	fopivot /jffs /rom 1
}