-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathoverctl
executable file
·108 lines (91 loc) · 2.52 KB
/
overctl
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
#!/bin/sh
BOOT=/boot
CMDLINE=cmdline.txt
CMDLINE_RO=cmdline.txt.overlay
CMDLINE_RW=cmdline.txt.orig
print_usage() {
cat <<-TEXT
Usage: ${0##*/} [-h|-r|-s|-t|-w]
-h, --help This message
-r, --ro Set read-only root with overlay fs
-s, --status Show current state
-t, --toggle Toggle between -r and -w
-w, --rw Set read-write root
TEXT
}
# Check whether user requests help
[ "$1" = "--help" -o "$1" = "-h" ] && { print_usage; exit 0; }
# Change to the working directory
cd $BOOT
# Check that the files we need are present and readable
for file in $CMDLINE $CMDLINE_RO $CMDLINE_RW; do
[ -r $file ] || { echo "ERROR: missing file $file" >&2 && exit 1; }
done
# Process arg (if any)
case "$1" in
--ro|-r) action=RO
;;
--rw|-w) action=RW
;;
--status|-s) action=status
;;
--toggle|-t) action=toggle
;;
*) print_usage
exit 1
;;
esac
line_active=$(cat $CMDLINE)
line_ro=$(cat $CMDLINE_RO)
line_rw=$(cat $CMDLINE_RW)
# Check which CMDLINE is in use, this doubles as a sanity check
if [ "$line_active" = "$line_ro" ]; then
state=RO
elif [ "$line_active" = "$line_rw" ]; then
state=RW
else
echo "ERROR: $CMDLINE matches neither $CMDLINE_RO, nor $CMDLINE_RW" >&2
exit 1
fi
check_permission() {
# Check that we are running as root
[ $(id -u) -eq 0 ] || { echo "ERROR: requires root privileges" >&2; exit 1; }
# Check that we can write to CMDLINE, otherwise try to remount BOOT
if ! touch $CMDLINE 2>/dev/null; then
mount -o remount,rw $BOOT 2>/dev/null
[ $? -eq 0 ] || { echo "ERROR: failed to mount $BOOT RW" >&2; exit 1; }
boot_remount=y
fi
return 0
}
# Take action
if [ "$action" = "status" ]; then
str=$(mount | grep ' on / ')
if echo $str | grep -q 'overlay'; then
echo -n "/ is currently mounted RO" >&2
elif echo $str | grep -q 'rw'; then
echo -n "/ is currently mounted RW" >&2
else
echo "ERROR: unable to determine mount options for /" >&2
exit 1
fi
echo " and will be mounted $state on next boot" >&2
exit 0
elif [ "$action" = "$state" ]; then
echo "/ is already set to be mounted $state on next boot" >&2
exit 1
elif [ "$state" = "RO" ]; then
check_permission && cp $CMDLINE_RW $CMDLINE
newstate=RW
elif [ "$state" = "RW" ]; then
check_permission && cp $CMDLINE_RO $CMDLINE
newstate=RO
fi
echo "/ will be mounted $newstate on next boot" >&2
# Remount BOOT read-only if that was the way we found it
if [ "$boot_remount" = "y" ]; then
mount -o remount,ro $BOOT 2>/dev/null
[ $? -eq 0 ] || { echo "failed to mount $BOOT RO" >&2; exit 1; }
fi
# The End
exit 0