]> git.ipfire.org Git - thirdparty/dracut.git/blame - modules.d/30convertfs/convertfs.sh
use "rm --" to guard against filenames beginning with "-"
[thirdparty/dracut.git] / modules.d / 30convertfs / convertfs.sh
CommitLineData
ae8b82e3
HH
1#!/bin/bash
2# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3# ex: ts=8 sw=4 sts=4 et filetype=sh
4
ae8b82e3
HH
5ROOT="$1"
6
7if [[ ! -d "$ROOT" ]]; then
8 echo "Usage: $0 <rootdir>"
9 exit 1
10fi
11
12if [[ "$ROOT" -ef / ]]; then
13 echo "Can't convert the running system."
2cf328ad 14 echo "Please boot with 'rd.convertfs' on the kernel command line,"
ae8b82e3
HH
15 echo "to update with the help of the initramfs,"
16 echo "or run this script from a rescue system."
17 exit 1
18fi
19
20while [[ "$ROOT" != "${ROOT%/}" ]]; do
21 ROOT=${ROOT%/}
22done
23
95268ffe 24if [ ! -L $ROOT/var/run -a -e $ROOT/var/run ]; then
9d5e3ed7
HH
25 echo "Converting /var/run to symlink"
26 mv -f $ROOT/var/run $ROOT/var/run.runmove~
27 ln -sfn ../run $ROOT/var/run
28fi
29
95268ffe 30if [ ! -L $ROOT/var/lock -a -e $ROOT/var/lock ]; then
9d5e3ed7
HH
31 echo "Converting /var/lock to symlink"
32 mv -f $ROOT/var/lock $ROOT/var/lock.lockmove~
33 ln -sfn ../run/lock $ROOT/var/lock
34fi
35
ae8b82e3
HH
36needconvert() {
37 for dir in "$ROOT/bin" "$ROOT/sbin" "$ROOT/lib" "$ROOT/lib64"; do
38 if [[ -e "$dir" ]]; then
39 [[ -L "$dir" ]] || return 0
40 fi
41 done
42 return 1
43}
44
95268ffe
HH
45if ! [ -e "$ROOT/usr/bin" ]; then
46 echo "$ROOT/usr/bin does not exist!"
47 echo "Make sure, the kernel command line has enough information"
48 echo "to mount /usr (man dracut.cmdline)"
49 exit 1
50fi
51
52
ae8b82e3
HH
53if ! needconvert; then
54 echo "Your system is already converted."
55 exit 0
56fi
57
58testfile="$ROOT/.usrmovecheck$$"
32bd2fbb 59rm -f -- "$testfile"
ae8b82e3
HH
60> "$testfile"
61if [[ ! -e "$testfile" ]]; then
62 echo "Cannot write to $ROOT/"
63 exit 1
64fi
32bd2fbb 65rm -f -- "$testfile"
ae8b82e3
HH
66
67testfile="$ROOT/usr/.usrmovecheck$$"
32bd2fbb 68rm -f -- "$testfile"
ae8b82e3
HH
69> "$testfile"
70if [[ ! -e "$testfile" ]]; then
71 echo "Cannot write to $ROOT/usr/"
72 exit 1
73fi
32bd2fbb 74rm -f -- "$testfile"
ae8b82e3 75
42116050
HH
76find_mount() {
77 local dev mnt etc wanted_dev
78 wanted_dev="$(readlink -e -q $1)"
79 while read dev mnt etc; do
80 [ "$dev" = "$wanted_dev" ] && echo "$dev" && return 0
ae8b82e3
HH
81 done < /proc/mounts
82 return 1
83}
84
42116050
HH
85# usage: ismounted <mountpoint>
86# usage: ismounted /dev/<device>
87if command -v findmnt >/dev/null; then
88 ismounted() {
89 findmnt "$1" > /dev/null 2>&1
90 }
91else
92 ismounted() {
93 if [ -b "$1" ]; then
94 find_mount "$1" > /dev/null && return 0
95 return 1
96 fi
97
98 while read a m a; do
99 [ "$m" = "$1" ] && return 0
100 done < /proc/mounts
101 return 1
102 }
103fi
104
ae8b82e3
HH
105# clean up after ourselves no matter how we die.
106cleanup() {
107 echo "Something failed. Move back to the original state"
108 for dir in "$ROOT/bin" "$ROOT/sbin" "$ROOT/lib" "$ROOT/lib64" \
109 "$ROOT/usr/bin" "$ROOT/usr/sbin" "$ROOT/usr/lib" \
110 "$ROOT/usr/lib64"; do
32bd2fbb 111 [[ -d "${dir}.usrmove-new" ]] && rm -fr -- "${dir}.usrmove-new"
ae8b82e3
HH
112 if [[ -d "${dir}.usrmove-old" ]]; then
113 mv "$dir" "${dir}.del~"
114 mv "${dir}.usrmove-old" "$dir"
32bd2fbb 115 rm -fr -- "${dir}.del~"
ae8b82e3
HH
116 fi
117 done
118}
119
120trap 'ret=$?; [[ $ret -ne 0 ]] && cleanup;exit $ret;' EXIT
121trap 'exit 1;' SIGINT
122
123ismounted "$ROOT/usr" || CP_HARDLINK="-l"
124
125set -e
126
127# merge / and /usr in new dir in /usr
128for dir in bin sbin lib lib64; do
32bd2fbb 129 rm -rf -- "$ROOT/usr/${dir}.usrmove-new"
ae8b82e3
HH
130 [[ -L "$ROOT/$dir" ]] && continue
131 [[ -d "$ROOT/$dir" ]] || continue
132 echo "Make a copy of \`$ROOT/usr/$dir'."
133 [[ -d "$ROOT/usr/$dir" ]] \
b6f0dcbd 134 && cp -ax -l "$ROOT/usr/$dir" "$ROOT/usr/${dir}.usrmove-new"
ae8b82e3
HH
135 echo "Merge the copy with \`$ROOT/$dir'."
136 [[ -d "$ROOT/usr/${dir}.usrmove-new" ]] \
137 || mkdir -p "$ROOT/usr/${dir}.usrmove-new"
138 cp -axT $CP_HARDLINK --backup --suffix=.usrmove~ "$ROOT/$dir" "$ROOT/usr/${dir}.usrmove-new"
139 echo "Clean up duplicates in \`$ROOT/usr/$dir'."
140 # delete all symlinks that have been backed up
141 find "$ROOT/usr/${dir}.usrmove-new" -type l -name '*.usrmove~' -delete || :
142 # replace symlink with backed up binary
143 find "$ROOT/usr/${dir}.usrmove-new" \
144 -name '*.usrmove~' \
145 -type f \
146 -exec bash -c 'p="{}";o=${p%%%%.usrmove~};
147 [[ -L "$o" ]] && mv -f "$p" "$o"' ';' || :
148done
149# switch over merged dirs in /usr
150for dir in bin sbin lib lib64; do
151 [[ -d "$ROOT/usr/${dir}.usrmove-new" ]] || continue
152 echo "Switch to new \`$ROOT/usr/$dir'."
32bd2fbb 153 rm -fr -- "$ROOT/usr/${dir}.usrmove-old"
ae8b82e3
HH
154 mv "$ROOT/usr/$dir" "$ROOT/usr/${dir}.usrmove-old"
155 mv "$ROOT/usr/${dir}.usrmove-new" "$ROOT/usr/$dir"
156done
157
158# replace dirs in / with links to /usr
159for dir in bin sbin lib lib64; do
160 [[ -L "$ROOT/$dir" ]] && continue
161 [[ -d "$ROOT/$dir" ]] || continue
162 echo "Create \`$ROOT/$dir' symlink."
32bd2fbb 163 rm -fr -- "$ROOT/${dir}.usrmove-old" || :
ae8b82e3
HH
164 mv "$ROOT/$dir" "$ROOT/${dir}.usrmove-old"
165 ln -sfn usr/$dir "$ROOT/$dir"
166done
167
168echo "Clean up backup files."
169# everything seems to work; cleanup
170for dir in bin sbin lib lib64; do
171 # if we get killed in the middle of "rm -rf", ensure not to leave
172 # an incomplete directory, which is moved back by cleanup()
173 [[ -d "$ROOT/usr/${dir}.usrmove-old" ]] \
174 && mv "$ROOT/usr/${dir}.usrmove-old" "$ROOT/usr/${dir}.usrmove-old~"
175 [[ -d "$ROOT/${dir}.usrmove-old" ]] \
176 && mv "$ROOT/${dir}.usrmove-old" "$ROOT/${dir}.usrmove-old~"
177done
178
179for dir in bin sbin lib lib64; do
180 [[ -d "$ROOT/usr/${dir}.usrmove-old~" ]] \
32bd2fbb 181 && rm -rf -- "$ROOT/usr/${dir}.usrmove-old~" || :
ae8b82e3 182 [[ -d "$ROOT/${dir}.usrmove-old~" ]] \
32bd2fbb 183 && rm -rf -- "$ROOT/${dir}.usrmove-old~" || :
ae8b82e3
HH
184done
185
5ebad51b
HH
186for dir in lib lib64; do
187 [[ -d "$ROOT/$dir" ]] || continue
188 for lib in "$ROOT"/usr/${dir}/lib*.so*.usrmove~; do
189 [[ -f $lib ]] || continue
190 mv $lib ${lib/.so/_so}
191 done
192done
193
ae8b82e3
HH
194set +e
195
196echo "Run ldconfig."
197ldconfig -r "$ROOT"
2cf328ad
HH
198
199. $ROOT/etc/selinux/config
ce18bc4e 200if [ -n "$(command -v setfiles)" ] && [ "$SELINUX" != "disabled" ] && [ -f /etc/selinux/${SELINUXTYPE}/contexts/files/file_contexts ]; then
2cf328ad 201 echo "Fixing SELinux labels"
ce18bc4e 202 setfiles -r $ROOT -p /etc/selinux/${SELINUXTYPE}/contexts/files/file_contexts $ROOT/sbin $ROOT/bin $ROOT/lib $ROOT/lib64 $ROOT/usr/lib $ROOT/usr/lib64 $ROOT/etc/ld.so.cache $ROOT/var/cache/ldconfig || :
2cf328ad
HH
203fi
204
ae8b82e3
HH
205echo "Done."
206exit 0