225 lines
6.7 KiB
Diff
225 lines
6.7 KiB
Diff
From ae8b82e395c9530a66288f7a9e939242137d3f56 Mon Sep 17 00:00:00 2001
|
|
From: Harald Hoyer <harald@redhat.com>
|
|
Date: Thu, 26 Jan 2012 11:33:51 +0100
|
|
Subject: [PATCH] add usrmove module
|
|
|
|
---
|
|
dracut.spec | 1 +
|
|
modules.d/30usrmove/do-usrmove.sh | 7 ++
|
|
modules.d/30usrmove/module-setup.sh | 19 ++++
|
|
modules.d/30usrmove/usrmove-convert.sh | 153 ++++++++++++++++++++++++++++++++
|
|
4 files changed, 180 insertions(+), 0 deletions(-)
|
|
create mode 100755 modules.d/30usrmove/do-usrmove.sh
|
|
create mode 100755 modules.d/30usrmove/module-setup.sh
|
|
create mode 100755 modules.d/30usrmove/usrmove-convert.sh
|
|
|
|
diff --git a/dracut.spec b/dracut.spec
|
|
index 16c8aa3..06533e3 100644
|
|
--- a/dracut.spec
|
|
+++ b/dracut.spec
|
|
@@ -226,6 +226,7 @@ rm -rf $RPM_BUILD_ROOT
|
|
%{dracutlibdir}/modules.d/05busybox
|
|
%{dracutlibdir}/modules.d/10i18n
|
|
%{dracutlibdir}/modules.d/10rpmversion
|
|
+%{dracutlibdir}/modules.d/30usrmove
|
|
%{dracutlibdir}/modules.d/50plymouth
|
|
%{dracutlibdir}/modules.d/90btrfs
|
|
%{dracutlibdir}/modules.d/90crypt
|
|
diff --git a/modules.d/30usrmove/do-usrmove.sh b/modules.d/30usrmove/do-usrmove.sh
|
|
new file mode 100755
|
|
index 0000000..8bdf5ab
|
|
--- /dev/null
|
|
+++ b/modules.d/30usrmove/do-usrmove.sh
|
|
@@ -0,0 +1,7 @@
|
|
+#!/bin/bash
|
|
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
|
+# ex: ts=8 sw=4 sts=4 et filetype=sh
|
|
+
|
|
+if getargbool 0 rd.usrmove; then
|
|
+ usrmove-convert "$NEWROOT" 2>&1 | vinfo
|
|
+fi
|
|
diff --git a/modules.d/30usrmove/module-setup.sh b/modules.d/30usrmove/module-setup.sh
|
|
new file mode 100755
|
|
index 0000000..05b2366
|
|
--- /dev/null
|
|
+++ b/modules.d/30usrmove/module-setup.sh
|
|
@@ -0,0 +1,19 @@
|
|
+#!/bin/bash
|
|
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
|
+# ex: ts=8 sw=4 sts=4 et filetype=sh
|
|
+
|
|
+check() {
|
|
+ [[ $mount_needs ]] && return 1
|
|
+ return 255
|
|
+}
|
|
+
|
|
+depends() {
|
|
+ return 0
|
|
+}
|
|
+
|
|
+install() {
|
|
+ dracut_install bash
|
|
+ inst_hook pre-pivot 99 "$moddir/do-usrmove.sh"
|
|
+ inst "$moddir/usrmove-convert.sh" /usr/bin/usrmove-convert
|
|
+}
|
|
+
|
|
diff --git a/modules.d/30usrmove/usrmove-convert.sh b/modules.d/30usrmove/usrmove-convert.sh
|
|
new file mode 100755
|
|
index 0000000..3295074
|
|
--- /dev/null
|
|
+++ b/modules.d/30usrmove/usrmove-convert.sh
|
|
@@ -0,0 +1,153 @@
|
|
+#!/bin/bash
|
|
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
|
+# ex: ts=8 sw=4 sts=4 et filetype=sh
|
|
+
|
|
+set -x
|
|
+
|
|
+ROOT="$1"
|
|
+
|
|
+if [[ ! -d "$ROOT" ]]; then
|
|
+ echo "Usage: $0 <rootdir>"
|
|
+ exit 1
|
|
+fi
|
|
+
|
|
+if [[ "$ROOT" -ef / ]]; then
|
|
+ echo "Can't convert the running system."
|
|
+ echo "Please boot with 'usrmove' on the kernel command line,"
|
|
+ echo "to update with the help of the initramfs,"
|
|
+ echo "or run this script from a rescue system."
|
|
+ exit 1
|
|
+fi
|
|
+
|
|
+while [[ "$ROOT" != "${ROOT%/}" ]]; do
|
|
+ ROOT=${ROOT%/}
|
|
+done
|
|
+
|
|
+needconvert() {
|
|
+ for dir in "$ROOT/bin" "$ROOT/sbin" "$ROOT/lib" "$ROOT/lib64"; do
|
|
+ if [[ -e "$dir" ]]; then
|
|
+ [[ -L "$dir" ]] || return 0
|
|
+ fi
|
|
+ done
|
|
+ return 1
|
|
+}
|
|
+
|
|
+if ! needconvert; then
|
|
+ echo "Your system is already converted."
|
|
+ exit 0
|
|
+fi
|
|
+
|
|
+testfile="$ROOT/.usrmovecheck$$"
|
|
+rm -f "$testfile"
|
|
+> "$testfile"
|
|
+if [[ ! -e "$testfile" ]]; then
|
|
+ echo "Cannot write to $ROOT/"
|
|
+ exit 1
|
|
+fi
|
|
+rm -f "$testfile"
|
|
+
|
|
+testfile="$ROOT/usr/.usrmovecheck$$"
|
|
+rm -f "$testfile"
|
|
+> "$testfile"
|
|
+if [[ ! -e "$testfile" ]]; then
|
|
+ echo "Cannot write to $ROOT/usr/"
|
|
+ exit 1
|
|
+fi
|
|
+rm -f "$testfile"
|
|
+
|
|
+ismounted() {
|
|
+ while read a m a; do
|
|
+ [[ "$m" = "$1" ]] && return 0
|
|
+ done < /proc/mounts
|
|
+ return 1
|
|
+}
|
|
+
|
|
+# clean up after ourselves no matter how we die.
|
|
+cleanup() {
|
|
+ echo "Something failed. Move back to the original state"
|
|
+ for dir in "$ROOT/bin" "$ROOT/sbin" "$ROOT/lib" "$ROOT/lib64" \
|
|
+ "$ROOT/usr/bin" "$ROOT/usr/sbin" "$ROOT/usr/lib" \
|
|
+ "$ROOT/usr/lib64"; do
|
|
+ [[ -d "${dir}.usrmove-new" ]] && rm -fr "${dir}.usrmove-new"
|
|
+ if [[ -d "${dir}.usrmove-old" ]]; then
|
|
+ mv "$dir" "${dir}.del~"
|
|
+ mv "${dir}.usrmove-old" "$dir"
|
|
+ rm -fr "${dir}.del~"
|
|
+ fi
|
|
+ done
|
|
+}
|
|
+
|
|
+trap 'ret=$?; [[ $ret -ne 0 ]] && cleanup;exit $ret;' EXIT
|
|
+trap 'exit 1;' SIGINT
|
|
+
|
|
+ismounted "$ROOT/usr" || CP_HARDLINK="-l"
|
|
+
|
|
+set -e
|
|
+
|
|
+# merge / and /usr in new dir in /usr
|
|
+for dir in bin sbin lib lib64; do
|
|
+ rm -rf "$ROOT/usr/${dir}.usrmove-new"
|
|
+ [[ -L "$ROOT/$dir" ]] && continue
|
|
+ [[ -d "$ROOT/$dir" ]] || continue
|
|
+ echo "Make a copy of \`$ROOT/usr/$dir'."
|
|
+ [[ -d "$ROOT/usr/$dir" ]] \
|
|
+ && cp -ax $CP_HARDLINK "$ROOT/usr/$dir" "$ROOT/usr/${dir}.usrmove-new"
|
|
+ echo "Merge the copy with \`$ROOT/$dir'."
|
|
+ [[ -d "$ROOT/usr/${dir}.usrmove-new" ]] \
|
|
+ || mkdir -p "$ROOT/usr/${dir}.usrmove-new"
|
|
+ cp -axT $CP_HARDLINK --backup --suffix=.usrmove~ "$ROOT/$dir" "$ROOT/usr/${dir}.usrmove-new"
|
|
+ echo "Clean up duplicates in \`$ROOT/usr/$dir'."
|
|
+ # delete all symlinks that have been backed up
|
|
+ find "$ROOT/usr/${dir}.usrmove-new" -type l -name '*.usrmove~' -delete || :
|
|
+ # replace symlink with backed up binary
|
|
+ find "$ROOT/usr/${dir}.usrmove-new" \
|
|
+ -name '*.usrmove~' \
|
|
+ -type f \
|
|
+ -exec bash -c 'p="{}";o=${p%%%%.usrmove~};
|
|
+ [[ -L "$o" ]] && mv -f "$p" "$o"' ';' || :
|
|
+done
|
|
+# switch over merged dirs in /usr
|
|
+for dir in bin sbin lib lib64; do
|
|
+ [[ -d "$ROOT/usr/${dir}.usrmove-new" ]] || continue
|
|
+ echo "Switch to new \`$ROOT/usr/$dir'."
|
|
+ rm -fr "$ROOT/usr/${dir}.usrmove-old"
|
|
+ mv "$ROOT/usr/$dir" "$ROOT/usr/${dir}.usrmove-old"
|
|
+ mv "$ROOT/usr/${dir}.usrmove-new" "$ROOT/usr/$dir"
|
|
+done
|
|
+
|
|
+# replace dirs in / with links to /usr
|
|
+for dir in bin sbin lib lib64; do
|
|
+ [[ -L "$ROOT/$dir" ]] && continue
|
|
+ [[ -d "$ROOT/$dir" ]] || continue
|
|
+ echo "Create \`$ROOT/$dir' symlink."
|
|
+ rm -rf "$ROOT/${dir}.usrmove-old" || :
|
|
+ mv "$ROOT/$dir" "$ROOT/${dir}.usrmove-old"
|
|
+ ln -sfn usr/$dir "$ROOT/$dir"
|
|
+done
|
|
+
|
|
+echo "Clean up backup files."
|
|
+# everything seems to work; cleanup
|
|
+for dir in bin sbin lib lib64; do
|
|
+ # if we get killed in the middle of "rm -rf", ensure not to leave
|
|
+ # an incomplete directory, which is moved back by cleanup()
|
|
+ [[ -d "$ROOT/usr/${dir}.usrmove-old" ]] \
|
|
+ && mv "$ROOT/usr/${dir}.usrmove-old" "$ROOT/usr/${dir}.usrmove-old~"
|
|
+ [[ -d "$ROOT/${dir}.usrmove-old" ]] \
|
|
+ && mv "$ROOT/${dir}.usrmove-old" "$ROOT/${dir}.usrmove-old~"
|
|
+done
|
|
+
|
|
+for dir in bin sbin lib lib64; do
|
|
+ [[ -d "$ROOT/usr/${dir}.usrmove-old~" ]] \
|
|
+ && rm -rf "$ROOT/usr/${dir}.usrmove-old~" || :
|
|
+ [[ -d "$ROOT/${dir}.usrmove-old~" ]] \
|
|
+ && rm -rf "$ROOT/${dir}.usrmove-old~" || :
|
|
+done
|
|
+
|
|
+set +e
|
|
+
|
|
+echo "Run ldconfig."
|
|
+ldconfig -r "$ROOT"
|
|
+echo "Set autorelabel flag."
|
|
+> "$ROOT/.autorelabel"
|
|
+echo "Done."
|
|
+exit 0
|