]>
Commit | Line | Data |
---|---|---|
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 |
5 | ROOT="$1" |
6 | ||
7 | if [[ ! -d "$ROOT" ]]; then | |
8 | echo "Usage: $0 <rootdir>" | |
9 | exit 1 | |
10 | fi | |
11 | ||
12 | if [[ "$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 | |
18 | fi | |
19 | ||
20 | while [[ "$ROOT" != "${ROOT%/}" ]]; do | |
21 | ROOT=${ROOT%/} | |
22 | done | |
23 | ||
95268ffe | 24 | if [ ! -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 | |
28 | fi | |
29 | ||
95268ffe | 30 | if [ ! -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 | |
34 | fi | |
35 | ||
ae8b82e3 HH |
36 | needconvert() { |
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 |
45 | if ! [ -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 | |
50 | fi | |
51 | ||
52 | ||
ae8b82e3 HH |
53 | if ! needconvert; then |
54 | echo "Your system is already converted." | |
55 | exit 0 | |
56 | fi | |
57 | ||
58 | testfile="$ROOT/.usrmovecheck$$" | |
32bd2fbb | 59 | rm -f -- "$testfile" |
ae8b82e3 HH |
60 | > "$testfile" |
61 | if [[ ! -e "$testfile" ]]; then | |
62 | echo "Cannot write to $ROOT/" | |
63 | exit 1 | |
64 | fi | |
32bd2fbb | 65 | rm -f -- "$testfile" |
ae8b82e3 HH |
66 | |
67 | testfile="$ROOT/usr/.usrmovecheck$$" | |
32bd2fbb | 68 | rm -f -- "$testfile" |
ae8b82e3 HH |
69 | > "$testfile" |
70 | if [[ ! -e "$testfile" ]]; then | |
71 | echo "Cannot write to $ROOT/usr/" | |
72 | exit 1 | |
73 | fi | |
32bd2fbb | 74 | rm -f -- "$testfile" |
ae8b82e3 | 75 | |
42116050 HH |
76 | find_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> | |
87 | if command -v findmnt >/dev/null; then | |
88 | ismounted() { | |
89 | findmnt "$1" > /dev/null 2>&1 | |
90 | } | |
91 | else | |
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 | } | |
103 | fi | |
104 | ||
ae8b82e3 HH |
105 | # clean up after ourselves no matter how we die. |
106 | cleanup() { | |
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 | ||
120 | trap 'ret=$?; [[ $ret -ne 0 ]] && cleanup;exit $ret;' EXIT | |
121 | trap 'exit 1;' SIGINT | |
122 | ||
123 | ismounted "$ROOT/usr" || CP_HARDLINK="-l" | |
124 | ||
125 | set -e | |
126 | ||
127 | # merge / and /usr in new dir in /usr | |
128 | for 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"' ';' || : | |
148 | done | |
149 | # switch over merged dirs in /usr | |
150 | for 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" | |
156 | done | |
157 | ||
158 | # replace dirs in / with links to /usr | |
159 | for 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" | |
166 | done | |
167 | ||
168 | echo "Clean up backup files." | |
169 | # everything seems to work; cleanup | |
170 | for 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~" | |
177 | done | |
178 | ||
179 | for 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 |
184 | done |
185 | ||
5ebad51b HH |
186 | for 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 | |
192 | done | |
193 | ||
ae8b82e3 HH |
194 | set +e |
195 | ||
196 | echo "Run ldconfig." | |
197 | ldconfig -r "$ROOT" | |
2cf328ad HH |
198 | |
199 | . $ROOT/etc/selinux/config | |
ce18bc4e | 200 | if [ -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 |
203 | fi |
204 | ||
ae8b82e3 HH |
205 | echo "Done." |
206 | exit 0 |