forked from pool/compat-usrmerge
Accepting request 898435 from Base:System
OBS-URL: https://build.opensuse.org/request/show/898435 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/compat-usrmerge?expand=0&rev=2
This commit is contained in:
commit
a8180cfcec
@ -1,3 +1,30 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jun 8 12:03:52 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
- early exit in case of overlayfs (boo#1187027)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jun 8 07:37:33 UTC 2021 - Fabian Vogt <fvogt@suse.com>
|
||||||
|
|
||||||
|
- Avoid dependency on mountpoint from util-linux
|
||||||
|
- Also check for availability of find
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Jun 7 09:02:56 UTC 2021 - Ludwig Nussel <lnussel@suse.com>
|
||||||
|
|
||||||
|
- fix conversion with split /usr (boo#1186781)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jun 2 15:29:15 UTC 2021 - Ludwig Nussel <lnussel@suse.com>
|
||||||
|
|
||||||
|
- exit early if one of the affected directories has mountpoint
|
||||||
|
beneath it
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jun 1 23:27:08 UTC 2021 - Niklas Haas <obs@haasn.xyz>
|
||||||
|
|
||||||
|
- add fallback for filesystems without renameat2 (boo#1186637)
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Mar 25 09:50:48 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
Thu Mar 25 09:50:48 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
59
convertfs
59
convertfs
@ -3,28 +3,59 @@
|
|||||||
|
|
||||||
ROOT=
|
ROOT=
|
||||||
|
|
||||||
|
is_usrmerged() {
|
||||||
|
local r=1
|
||||||
|
for dir in bin sbin lib lib64; do
|
||||||
|
[ -d "$ROOT/$dir" ] || continue
|
||||||
|
[ -L "$ROOT/$dir" ] || return 1
|
||||||
|
r=0
|
||||||
|
done
|
||||||
|
return "$r"
|
||||||
|
}
|
||||||
|
|
||||||
|
# check if there's anything to do
|
||||||
|
is_usrmerged && exit 0
|
||||||
|
|
||||||
# the package is installed with AutoReq off, so no guarantee that
|
# the package is installed with AutoReq off, so no guarantee that
|
||||||
# coreutils actually works
|
# coreutils actually works
|
||||||
if ! (cp --help && mountpoint --help && mountpoint --help) > /dev/null; then
|
if ! { cp --help && find --help; } > /dev/null; then
|
||||||
echo "tools not functional, exit"
|
echo "tools not functional, exit"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# clean up after ourselves no matter how we die.
|
# clean up after ourselves no matter how we die.
|
||||||
cleanup() {
|
cleanup() {
|
||||||
echo "Something failed, cleaning up"
|
echo "UsrMerge conversion failed, cleaning up"
|
||||||
for dir in bin sbin lib lib64; do
|
for dir in bin sbin lib lib64; do
|
||||||
rm -rf -- "$ROOT/usr/${dir}.usrmerge"
|
rm -rf -- "$ROOT/usr/${dir}.usrmerge"
|
||||||
done
|
done
|
||||||
|
echo "!!! ATTENTION: Do NOT proceed if you see this message during"
|
||||||
|
echo "!!! distribution upgrade. Chances are high that your system might"
|
||||||
|
echo "!!! break beyond repair if you do."
|
||||||
}
|
}
|
||||||
|
|
||||||
trap 'ret=$?; [[ $ret -ne 0 ]] && cleanup;exit $ret;' EXIT
|
trap 'ret=$?; [[ $ret -ne 0 ]] && cleanup;exit $ret;' EXIT
|
||||||
trap 'exit 1;' SIGINT
|
trap 'exit 1;' SIGINT
|
||||||
|
|
||||||
mountpoint -q "$ROOT/usr" || CP_HARDLINK="-l"
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if [ "$(stat -f -c %T "${ROOT:-/}")" = "overlayfs" ]; then
|
||||||
|
echo "UsrMerge conversion does not work on overlayfs"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CP_HARDLINK="-l"
|
||||||
|
while read dev mp other; do
|
||||||
|
[ "$mp" = "$ROOT/usr" ] && CP_HARDLINK=""
|
||||||
|
for dir in bin sbin lib lib64; do
|
||||||
|
[ -d "$ROOT/$dir" ] || continue
|
||||||
|
if [ "${mp#$ROOT/$dir}" != "$mp" ] || [ "${mp#$ROOT/usr/$dir}" != "$mp" ]; then
|
||||||
|
echo "Please unmount $mp before the conversion"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done < /proc/mounts
|
||||||
|
|
||||||
# merge / and /usr in new dir in /usr
|
# merge / and /usr in new dir in /usr
|
||||||
for dir in bin sbin lib lib64; do
|
for dir in bin sbin lib lib64; do
|
||||||
rm -rf -- "$ROOT/usr/${dir}.usrmerge"
|
rm -rf -- "$ROOT/usr/${dir}.usrmerge"
|
||||||
@ -32,7 +63,7 @@ for dir in bin sbin lib lib64; do
|
|||||||
[[ -d "$ROOT/$dir" ]] || continue
|
[[ -d "$ROOT/$dir" ]] || continue
|
||||||
echo "Make a copy of \`$ROOT/$dir'."
|
echo "Make a copy of \`$ROOT/$dir'."
|
||||||
[[ -d "$ROOT/$dir" ]] \
|
[[ -d "$ROOT/$dir" ]] \
|
||||||
&& cp -ax -l "$ROOT/$dir" "$ROOT/usr/${dir}.usrmerge"
|
&& cp -ax $CP_HARDLINK "$ROOT/$dir" "$ROOT/usr/${dir}.usrmerge"
|
||||||
# cp can't handle copying a dir over non-directories. So move
|
# cp can't handle copying a dir over non-directories. So move
|
||||||
# those away in advance. Happened with /lib/udev existing as
|
# those away in advance. Happened with /lib/udev existing as
|
||||||
# link on older distros
|
# link on older distros
|
||||||
@ -43,7 +74,7 @@ for dir in bin sbin lib lib64; do
|
|||||||
rm -rf "$f.usrmerge~"
|
rm -rf "$f.usrmerge~"
|
||||||
mv "$f" "$f.usrmerge~"
|
mv "$f" "$f.usrmerge~"
|
||||||
fi
|
fi
|
||||||
done < <(find "$ROOT/usr/$dir" -type d -printf "%P\n" )
|
done < <(find "$ROOT/usr/$dir" -xdev -type d -printf "%P\n" )
|
||||||
echo "Merge the copy with \`$ROOT/usr/$dir'."
|
echo "Merge the copy with \`$ROOT/usr/$dir'."
|
||||||
[[ -d "$ROOT/usr/${dir}.usrmerge" ]] \
|
[[ -d "$ROOT/usr/${dir}.usrmerge" ]] \
|
||||||
|| mkdir -p "$ROOT/usr/${dir}.usrmerge"
|
|| mkdir -p "$ROOT/usr/${dir}.usrmerge"
|
||||||
@ -51,14 +82,14 @@ for dir in bin sbin lib lib64; do
|
|||||||
echo "Clean up duplicates in \`$ROOT/usr/$dir'."
|
echo "Clean up duplicates in \`$ROOT/usr/$dir'."
|
||||||
# delete all symlinks that have been backed up. /usr versions
|
# delete all symlinks that have been backed up. /usr versions
|
||||||
# override / ones
|
# override / ones
|
||||||
find "$ROOT/usr/${dir}.usrmerge" -type l -name '*.usrmerge~' -delete || :
|
find "$ROOT/usr/${dir}.usrmerge" -xdev -type l -name '*.usrmerge~' -delete || :
|
||||||
# in rare cases the symlinks may point from /usr to /, so remove
|
# in rare cases the symlinks may point from /usr to /, so remove
|
||||||
# the link in that case
|
# the link in that case
|
||||||
while read file; do
|
while read file; do
|
||||||
o=${file%%.usrmerge~}
|
o=${file%%.usrmerge~}
|
||||||
[ -L "$o" ] && mv -f "$file" "$o"
|
[ -L "$o" ] && mv -f "$file" "$o"
|
||||||
done < <(find "$ROOT/usr/${dir}.usrmerge" \
|
done < <(find "$ROOT/usr/${dir}.usrmerge" \
|
||||||
-name '*.usrmerge~' -type f)
|
-xdev -name '*.usrmerge~' -type f)
|
||||||
done
|
done
|
||||||
# switch over merged dirs in /usr
|
# switch over merged dirs in /usr
|
||||||
for dir in bin sbin lib lib64; do
|
for dir in bin sbin lib lib64; do
|
||||||
@ -72,7 +103,7 @@ done
|
|||||||
for dir in bin sbin lib lib64; do
|
for dir in bin sbin lib lib64; do
|
||||||
if [ ! -L "$ROOT/$dir" -a -d "$ROOT/$dir" ]; then
|
if [ ! -L "$ROOT/$dir" -a -d "$ROOT/$dir" ]; then
|
||||||
echo "Create \`$ROOT/$dir' symlink."
|
echo "Create \`$ROOT/$dir' symlink."
|
||||||
rm -rf "$ROOT/${dir}.usrmerge" || :
|
rm --one-file-system -rf "$ROOT/${dir}.usrmerge" || :
|
||||||
ln -s usr/$dir "$ROOT/${dir}.usrmerge"
|
ln -s usr/$dir "$ROOT/${dir}.usrmerge"
|
||||||
/usr/libexec/xmv "$ROOT/$dir" "$ROOT/${dir}.usrmerge"
|
/usr/libexec/xmv "$ROOT/$dir" "$ROOT/${dir}.usrmerge"
|
||||||
fi
|
fi
|
||||||
@ -88,7 +119,7 @@ for dir in bin sbin lib lib64; do
|
|||||||
if [ -d "$d" ]; then
|
if [ -d "$d" ]; then
|
||||||
echo "$d ..."
|
echo "$d ..."
|
||||||
mv "$d" "$d~"
|
mv "$d" "$d~"
|
||||||
rm -rf "$d~"
|
rm --one-file-system -rf "$d~"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
@ -105,10 +136,4 @@ done
|
|||||||
set +e
|
set +e
|
||||||
|
|
||||||
echo "Run ldconfig."
|
echo "Run ldconfig."
|
||||||
ldconfig -r "$ROOT"
|
ldconfig -r "$ROOT" || :
|
||||||
|
|
||||||
#. $ROOT/etc/selinux/config
|
|
||||||
#if [ -n "$(command -v setfiles)" ] && [ "$SELINUX" != "disabled" ] && [ -f /etc/selinux/${SELINUXTYPE}/contexts/files/file_contexts ]; then
|
|
||||||
# echo "Fixing SELinux labels"
|
|
||||||
# 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 || :
|
|
||||||
#fi
|
|
||||||
|
29
xmv.c
29
xmv.c
@ -31,6 +31,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifndef RENAME_EXCHANGE
|
#ifndef RENAME_EXCHANGE
|
||||||
# define RENAME_EXCHANGE (1 << 1)
|
# define RENAME_EXCHANGE (1 << 1)
|
||||||
@ -66,11 +67,37 @@ int main(int argc, char** argv)
|
|||||||
if (argc-optind < 2)
|
if (argc-optind < 2)
|
||||||
help(argv[0], 1);
|
help(argv[0], 1);
|
||||||
|
|
||||||
r = syscall (SYS_renameat2, AT_FDCWD, argv[optind], AT_FDCWD, argv[optind+1], RENAME_EXCHANGE);
|
const char *source = argv[optind], *target = argv[optind+1];
|
||||||
|
r = syscall (SYS_renameat2, AT_FDCWD, source, AT_FDCWD, target, RENAME_EXCHANGE);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
if (errno != EINVAL) {
|
||||||
perror("renameat2");
|
perror("renameat2");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback for systems without renameat2 support
|
||||||
|
puts("!!! WARNING: rename2 RENAME_EXCHANGE not supported !!!");
|
||||||
|
puts("!!! fallback to unsafe rename !!!");
|
||||||
|
char tmp[PATH_MAX];
|
||||||
|
r = snprintf(tmp, sizeof(tmp), "%s.XXXXXX", target);
|
||||||
|
if (r < 0) {
|
||||||
|
perror("asprintf");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// not intended to be use in /tmp so good enough
|
||||||
|
mktemp(tmp);
|
||||||
|
|
||||||
|
r = renameat(AT_FDCWD, target, AT_FDCWD, tmp);
|
||||||
|
if (!r)
|
||||||
|
r = renameat(AT_FDCWD, source, AT_FDCWD, target);
|
||||||
|
if (!r)
|
||||||
|
r = renameat(AT_FDCWD, tmp, AT_FDCWD, source);
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
perror("renameat");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user