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