Sync from SUSE:ALP:Source:Standard:1.0 compat-usrmerge revision db3ea9074a430717229ef191e990fb4f
This commit is contained in:
commit
48b0560f90
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
## Default LFS
|
||||||
|
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zst filter=lfs diff=lfs merge=lfs -text
|
72
compat-usrmerge.changes
Normal file
72
compat-usrmerge.changes
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Oct 7 11:57:22 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
- Fix logic for detecting conflicts with directories (boo#1191111)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Aug 27 08:39:30 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
- exit file triggers early if alread usrmerged
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Aug 27 06:35:26 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
- statically link xmv to avoid glibc 2.34 dependency
|
||||||
|
(__libc_start_main@GLIBC_2.34)
|
||||||
|
- turn on filetriggers in main package. Needed for single transaction upgrades
|
||||||
|
(boo#1189788)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jun 15 15:27:41 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
- another fix for split /usr to avoid running out of space (boo#1186781)
|
||||||
|
- unsafe fallback also for ENOSYS on renameat2 as seen on WSL
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
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>
|
||||||
|
|
||||||
|
- catch boolean deps
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Mar 18 12:24:15 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
- cp can't handle copying a dir over non-directories. So move those
|
||||||
|
away in advance. Happened with /lib/udev existing as link on older
|
||||||
|
distros
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Mar 15 17:41:10 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
- update file lists based on current factory data
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Feb 25 10:22:09 UTC 2021 - Ludwig Nussel <lnussel@suse.de>
|
||||||
|
|
||||||
|
- initial package
|
207
compat-usrmerge.spec
Normal file
207
compat-usrmerge.spec
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
#
|
||||||
|
# spec file for package compat-usrmerge
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 SUSE LLC
|
||||||
|
#
|
||||||
|
# All modifications and additions to the file contributed by third parties
|
||||||
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
|
# upon. The license for this file, and modifications and additions to the
|
||||||
|
# file, is the same license as for the pristine package itself (unless the
|
||||||
|
# license for the pristine package is not an Open Source License, in which
|
||||||
|
# case the license is the MIT License). An "Open Source License" is a
|
||||||
|
# license that conforms to the Open Source Definition (Version 1.9)
|
||||||
|
# published by the Open Source Initiative.
|
||||||
|
|
||||||
|
# Please submit bugfixes or comments via https://bugs.opensuse.org/
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
%define nvr %{name}-%{version}-%{release}
|
||||||
|
|
||||||
|
Name: compat-usrmerge
|
||||||
|
Version: 84.87
|
||||||
|
Release: 0
|
||||||
|
Summary: UsrMerge related scripts
|
||||||
|
License: MIT
|
||||||
|
URL: https://en.opensuse.org/openSUSE:Usr_merge
|
||||||
|
Source0: usrmerge.lua
|
||||||
|
# ./usrmergefiles.py --files https://download.opensuse.org/tumbleweed/repo/oss
|
||||||
|
Source1: usrmerge_files.lua
|
||||||
|
Source2: usrmergecheck.c
|
||||||
|
Source3: convertfs
|
||||||
|
Source4: xmv.c
|
||||||
|
Source5: usrmerge.attr
|
||||||
|
# ./usrmergefiles.py --requires https://download.opensuse.org/tumbleweed/repo/oss
|
||||||
|
Source6: usrmerge_binsbindeps.lua
|
||||||
|
Source7: usrmergefiles.py
|
||||||
|
BuildRequires: gcc
|
||||||
|
BuildRequires: glibc-static
|
||||||
|
BuildRequires: pkgconfig(rpm)
|
||||||
|
|
||||||
|
%description
|
||||||
|
Scripts and data files related to UsrMerge
|
||||||
|
(https://en.opensuse.org/openSUSE:Usr_merge). Normally not needd.
|
||||||
|
|
||||||
|
%package tools
|
||||||
|
Summary: UsrMerge tools
|
||||||
|
Requires: (compat-usrmerge if compat-usrmerge)
|
||||||
|
# have to turn requires off this off to avoid pulling in stuff
|
||||||
|
# before filessytem.
|
||||||
|
# xmv has very minimal glibc requirements and could probably be
|
||||||
|
# reduced further. The script runs only in the upgrade case,
|
||||||
|
# assuming that the tools work on the target system anyway.
|
||||||
|
AutoReq: 0
|
||||||
|
|
||||||
|
%description tools
|
||||||
|
Tools related to UsrMerge to check the state of the system and to
|
||||||
|
convert an existing system to UsrMerge.
|
||||||
|
|
||||||
|
%package build
|
||||||
|
Summary: UsrMerge build tools
|
||||||
|
Requires: lua
|
||||||
|
|
||||||
|
%description build
|
||||||
|
Build tools related to UsrMerge. This is required for rpmbuild to
|
||||||
|
generate proper provides tags for packages that used to have
|
||||||
|
binaries in /(s)bin.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -qcT
|
||||||
|
|
||||||
|
%build
|
||||||
|
gcc -Wall %optflags -o usrmergecheck %{SOURCE2} `pkg-config --libs rpm`
|
||||||
|
gcc -Wall %optflags -static -o xmv %{SOURCE4}
|
||||||
|
|
||||||
|
%install
|
||||||
|
install -D -m755 usrmergecheck %{buildroot}%{_bindir}/usrmergecheck
|
||||||
|
mkdir -p %{buildroot}%{_rpmconfigdir}/lua
|
||||||
|
install -m644 %{SOURCE0} %{buildroot}%{_rpmconfigdir}/lua
|
||||||
|
install -m644 %{SOURCE1} %{buildroot}%{_rpmconfigdir}/lua
|
||||||
|
install -D -m755 %{SOURCE3} %{buildroot}%{_libexecdir}/convertfs
|
||||||
|
install -m755 xmv %{buildroot}%{_libexecdir}/xmv
|
||||||
|
install -D -m755 %{SOURCE5} %{buildroot}%{_fileattrsdir}/usrmerge.attr
|
||||||
|
install -m644 %{SOURCE6} %{buildroot}%{_rpmconfigdir}/lua
|
||||||
|
###
|
||||||
|
mkdir -p %{buildroot}/lib
|
||||||
|
mkdir -p %{buildroot}/%{_lib}
|
||||||
|
while read file; do
|
||||||
|
echo "usrmerge_files[\"$file\"] = 1" >> %{buildroot}%{_rpmconfigdir}/lua/usrmerge_files.lua
|
||||||
|
done <<EOF
|
||||||
|
/%{_lib}/libc-`rpm -q --qf "%%{version}" glibc`.so
|
||||||
|
/%{_lib}/libc.so.6
|
||||||
|
%ifarch %arm
|
||||||
|
%ifarch armv6hl armv7hl
|
||||||
|
/%{_lib}/ld-linux-armhf.so.3
|
||||||
|
/%{_lib}/ld-linux.so.3
|
||||||
|
%else
|
||||||
|
/%{_lib}/ld-linux.so.3
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
%ifarch ia64
|
||||||
|
/%{_lib}/ld-linux-ia64.so.2
|
||||||
|
%endif
|
||||||
|
%ifarch ppc s390 mips hppa m68k
|
||||||
|
/%{_lib}/ld.so.1
|
||||||
|
%endif
|
||||||
|
%ifarch ppc64
|
||||||
|
/%{_lib}/ld64.so.1
|
||||||
|
%endif
|
||||||
|
%ifarch ppc64le
|
||||||
|
/%{_lib}/ld64.so.2
|
||||||
|
%endif
|
||||||
|
%ifarch s390x
|
||||||
|
/lib/ld64.so.1
|
||||||
|
/%{_lib}/ld64.so.1
|
||||||
|
%endif
|
||||||
|
%ifarch x86_64
|
||||||
|
/%{_lib}/ld-linux-x86-64.so.2
|
||||||
|
%endif
|
||||||
|
%ifarch %ix86 %sparc
|
||||||
|
/%{_lib}/ld-linux.so.2
|
||||||
|
%endif
|
||||||
|
%ifarch aarch64
|
||||||
|
/lib/ld-linux-aarch64.so.1
|
||||||
|
/%{_lib}/ld-linux-aarch64.so.1
|
||||||
|
%endif
|
||||||
|
%ifarch riscv64
|
||||||
|
/lib/ld-linux-riscv64-lp64d.so.1
|
||||||
|
/%{_lib}/ld-linux-riscv64-lp64d.so.1
|
||||||
|
%endif
|
||||||
|
EOF
|
||||||
|
#
|
||||||
|
%if 0
|
||||||
|
mkdir -p %{buildroot}/{sbin,bin,%{_lib}}
|
||||||
|
while read file; do
|
||||||
|
[ -n "$file" ] || continue
|
||||||
|
ln -s ../usr$file %{buildroot}$file
|
||||||
|
echo "%ghost %config(noreplace) $file"
|
||||||
|
done > files.list << EOF
|
||||||
|
%{lua:
|
||||||
|
package.path = package.path .. string.format(";%s/?.lua", rpm.expand("%{_sourcedir}"))
|
||||||
|
require("usrmerge_files")
|
||||||
|
for rp in pairs(usrmerge_files) do
|
||||||
|
print(rp.."\n")
|
||||||
|
end
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%filetriggerin -p <lua> -- %{_sbindir} %{_bindir} %{_libdir}
|
||||||
|
if posix.stat("/lib", "type") ~= "directory" then return end
|
||||||
|
require("usrmerge")
|
||||||
|
if posix.getenv("VERBOSE_FILETRIGGERS") then
|
||||||
|
usrmerge.debug = "%{nvr}(in)"
|
||||||
|
end
|
||||||
|
file = rpm.next_file()
|
||||||
|
while file do
|
||||||
|
usrmerge.add(file)
|
||||||
|
file = rpm.next_file()
|
||||||
|
end
|
||||||
|
io.flush()
|
||||||
|
|
||||||
|
%filetriggerpostun -p <lua> -- %{_sbindir} %{_bindir} %{_libdir}
|
||||||
|
if posix.stat("/lib", "type") ~= "directory" then return end
|
||||||
|
-- the module is already gone if we get called for ourselves
|
||||||
|
if pcall(require, 'usrmerge') then
|
||||||
|
if posix.getenv("VERBOSE_FILETRIGGERS") then
|
||||||
|
usrmerge.debug = "%{nvr}(postun)"
|
||||||
|
end
|
||||||
|
file = rpm.next_file()
|
||||||
|
while file do
|
||||||
|
usrmerge.remove(file)
|
||||||
|
file = rpm.next_file()
|
||||||
|
end
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
%filetriggerpostun -p <lua> -- /sbin /bin /%{_lib}
|
||||||
|
if posix.stat("/lib", "type") ~= "directory" then return end
|
||||||
|
-- the module is already gone if we get called for ourselves
|
||||||
|
if pcall(require, 'usrmerge') then
|
||||||
|
if posix.getenv("VERBOSE_FILETRIGGERS") then
|
||||||
|
usrmerge.debug = "%{nvr}(postun)"
|
||||||
|
end
|
||||||
|
file = rpm.next_file()
|
||||||
|
while file do
|
||||||
|
usrmerge.add_postun(file)
|
||||||
|
file = rpm.next_file()
|
||||||
|
end
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
%files
|
||||||
|
%dir %{_rpmconfigdir}/lua
|
||||||
|
%{_rpmconfigdir}/lua/usrmerge.lua
|
||||||
|
%{_rpmconfigdir}/lua/usrmerge_files.lua
|
||||||
|
|
||||||
|
%files tools
|
||||||
|
%{_bindir}/usrmergecheck
|
||||||
|
%{_libexecdir}/convertfs
|
||||||
|
%{_libexecdir}/xmv
|
||||||
|
|
||||||
|
%files build
|
||||||
|
%{_fileattrsdir}/usrmerge.attr
|
||||||
|
%dir %{_rpmconfigdir}/lua
|
||||||
|
%{_rpmconfigdir}/lua/usrmerge_binsbindeps.lua
|
||||||
|
|
||||||
|
%changelog
|
139
convertfs
Normal file
139
convertfs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# based on code from dracut convertfs.sh
|
||||||
|
|
||||||
|
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
|
||||||
|
# coreutils actually works
|
||||||
|
if ! { cp --help && find --help; } > /dev/null; then
|
||||||
|
echo "tools not functional, exit"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# clean up after ourselves no matter how we die.
|
||||||
|
cleanup() {
|
||||||
|
echo "UsrMerge conversion failed, cleaning up"
|
||||||
|
for dir in bin sbin lib lib64; do
|
||||||
|
rm -rf -- "$ROOT/usr/${dir}.usrmerge"
|
||||||
|
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 'exit 1;' SIGINT
|
||||||
|
|
||||||
|
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
|
||||||
|
for dir in bin sbin lib lib64; do
|
||||||
|
rm -rf -- "$ROOT/usr/${dir}.usrmerge"
|
||||||
|
[[ -L "$ROOT/$dir" ]] && continue
|
||||||
|
[[ -d "$ROOT/$dir" ]] || continue
|
||||||
|
echo "Make a copy of \`$ROOT/$dir'."
|
||||||
|
[[ -d "$ROOT/$dir" ]] \
|
||||||
|
&& cp -ax $CP_HARDLINK "$ROOT/$dir" "$ROOT/usr/${dir}.usrmerge"
|
||||||
|
# cp can't handle copying a dir over non-directories. So move
|
||||||
|
# those away in advance. Happened with /lib/udev existing as
|
||||||
|
# link on older distros
|
||||||
|
while read d; do
|
||||||
|
f="$ROOT/usr/$dir.usrmerge/$d"
|
||||||
|
if test -L "$f" -o \( -e "$f" -a ! -d "$f" \); then
|
||||||
|
echo "Warning: /$dir/$d conflicts with directory /usr/$dir/$d and will be removed"
|
||||||
|
rm -rf "$f.usrmerge~"
|
||||||
|
mv "$f" "$f.usrmerge~"
|
||||||
|
fi
|
||||||
|
done < <(find "$ROOT/usr/$dir" -xdev -type d -printf "%P\n" )
|
||||||
|
echo "Merge the copy with \`$ROOT/usr/$dir'."
|
||||||
|
[[ -d "$ROOT/usr/${dir}.usrmerge" ]] \
|
||||||
|
|| mkdir -p "$ROOT/usr/${dir}.usrmerge"
|
||||||
|
cp -axT -l --backup --suffix=.usrmerge~ "$ROOT/usr/$dir" "$ROOT/usr/${dir}.usrmerge"
|
||||||
|
echo "Clean up duplicates in \`$ROOT/usr/$dir'."
|
||||||
|
# delete all symlinks that have been backed up. /usr versions
|
||||||
|
# override / ones
|
||||||
|
find "$ROOT/usr/${dir}.usrmerge" -xdev -type l -name '*.usrmerge~' -delete || :
|
||||||
|
# in rare cases the symlinks may point from /usr to /, so remove
|
||||||
|
# the link in that case
|
||||||
|
while read file; do
|
||||||
|
o=${file%%.usrmerge~}
|
||||||
|
[ -L "$o" ] && mv -f "$file" "$o"
|
||||||
|
done < <(find "$ROOT/usr/${dir}.usrmerge" \
|
||||||
|
-xdev -name '*.usrmerge~' -type f)
|
||||||
|
done
|
||||||
|
# switch over merged dirs in /usr
|
||||||
|
for dir in bin sbin lib lib64; do
|
||||||
|
if [ -d "$ROOT/usr/${dir}.usrmerge" ]; then
|
||||||
|
echo "Switch to new \`$ROOT/usr/$dir'."
|
||||||
|
/usr/libexec/xmv "$ROOT/usr/${dir}.usrmerge" "$ROOT/usr/$dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# replace dirs in / with links to /usr
|
||||||
|
for dir in bin sbin lib lib64; do
|
||||||
|
if [ ! -L "$ROOT/$dir" -a -d "$ROOT/$dir" ]; then
|
||||||
|
echo "Create \`$ROOT/$dir' symlink."
|
||||||
|
rm --one-file-system -rf "$ROOT/${dir}.usrmerge" || :
|
||||||
|
ln -s usr/$dir "$ROOT/${dir}.usrmerge"
|
||||||
|
/usr/libexec/xmv "$ROOT/$dir" "$ROOT/${dir}.usrmerge"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Clean up backup files."
|
||||||
|
# everything seems to work; cleanup
|
||||||
|
for dir in bin sbin lib lib64; do
|
||||||
|
for pfx in usr/ /; 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/${pfx}${dir}.usrmerge"
|
||||||
|
if [ -d "$d" ]; then
|
||||||
|
echo "$d ..."
|
||||||
|
mv "$d" "$d~"
|
||||||
|
rm --one-file-system -rf "$d~"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# XXX: confirm this is needed
|
||||||
|
for dir in lib lib64; do
|
||||||
|
[[ -d "$ROOT/$dir" ]] || continue
|
||||||
|
for lib in "$ROOT"/usr/${dir}/lib*.so*.usrmerge~; do
|
||||||
|
[[ -f $lib ]] || continue
|
||||||
|
mv -v $lib ${lib/.so/_so}
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
set +e
|
||||||
|
|
||||||
|
echo "Run ldconfig."
|
||||||
|
ldconfig -r "$ROOT" || :
|
10
usrmerge.attr
Normal file
10
usrmerge.attr
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
%__usrmerge_provides() %{lua:
|
||||||
|
-- XXX: use repo data of actual requires
|
||||||
|
require("usrmerge_binsbindeps")
|
||||||
|
local file = rpm.expand("%1")
|
||||||
|
local pfxlen = string.len(rpm.expand("%buildroot").."/usr")+1
|
||||||
|
if usrmerge_binsbindeps[string.sub(file, pfxlen)] then
|
||||||
|
print(string.sub(file, pfxlen))
|
||||||
|
end
|
||||||
|
}
|
||||||
|
%__usrmerge_path ^/usr/s?bin/.*
|
149
usrmerge.lua
Normal file
149
usrmerge.lua
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
usrmerge = { debug = nil } -- package
|
||||||
|
|
||||||
|
require("usrmerge_files")
|
||||||
|
|
||||||
|
-- for testing outside rpm
|
||||||
|
if posix == nil then
|
||||||
|
posix = require("posix")
|
||||||
|
function _symlink(old, new)
|
||||||
|
os.execute("ln -vs " .. old .. " " .. new)
|
||||||
|
end
|
||||||
|
posix.symlink = _symlink
|
||||||
|
end
|
||||||
|
|
||||||
|
function _log(msg)
|
||||||
|
if usrmerge.debug then
|
||||||
|
print(usrmerge.debug .. ": " .. msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function rootpath(path)
|
||||||
|
_, _, p = string.find(path, "^/usr(/.*)")
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
|
||||||
|
function dirname(path)
|
||||||
|
_, _, d, b = string.find(path, "^(.*)/([^/]*)")
|
||||||
|
return d
|
||||||
|
end
|
||||||
|
|
||||||
|
function usrmerge._add(rp, relpath)
|
||||||
|
if not usrmerge_files[rp] then return end
|
||||||
|
if posix.stat(dirname(rp), "type") ~= "directory" then return end
|
||||||
|
|
||||||
|
createit = false
|
||||||
|
t = posix.stat(rp, "type")
|
||||||
|
if t == nil then
|
||||||
|
createit = true
|
||||||
|
elseif t == "link" then
|
||||||
|
dst = posix.readlink(rp)
|
||||||
|
if dst ~= relpath then
|
||||||
|
_log(rp .. ": fixing incorrect symlink (" .. dst .. " -> " .. relpath)
|
||||||
|
os.remove(rp)
|
||||||
|
createit = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
_log(rp .. " exist but is no link, skipping")
|
||||||
|
end
|
||||||
|
if createit then
|
||||||
|
_log("creating " .. rp .. " -> " .. relpath)
|
||||||
|
posix.symlink(relpath, rp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function usrmerge.add(path)
|
||||||
|
rp = rootpath(path)
|
||||||
|
usrmerge._add(rp, ".." .. path)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if a legacy package with a file in /bin gets upgraded, it would
|
||||||
|
-- remove the link/file in /bin on uninstall. So we have to check
|
||||||
|
-- there and restore.
|
||||||
|
function usrmerge.add_postun(rp)
|
||||||
|
if posix.stat("/usr" .. rp, "type") then
|
||||||
|
usrmerge._add(rp, "../usr" .. rp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- needed for the build system to install all links of packages that got
|
||||||
|
-- installed via rpm2cpio so didn't call triggers
|
||||||
|
function usrmerge.addexisting()
|
||||||
|
for rp in pairs(usrmerge_files) do
|
||||||
|
usrmerge.add_postun(rp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function usrmerge.remove(path)
|
||||||
|
rp = rootpath(path)
|
||||||
|
if not usrmerge_files[rp] then return end
|
||||||
|
if posix.stat(dirname(rp), "type") ~= "directory" then return end
|
||||||
|
|
||||||
|
t = posix.stat(path, "type")
|
||||||
|
if t then
|
||||||
|
_log(path .. " still exists, skipping")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
t = posix.stat(rp, "type")
|
||||||
|
if t == "link" then
|
||||||
|
relpath = ".." .. path
|
||||||
|
dst = posix.readlink(rp)
|
||||||
|
if dst == relpath then
|
||||||
|
_log("remove " .. rp .. " -> " .. relpath)
|
||||||
|
os.remove(rp)
|
||||||
|
else
|
||||||
|
_log(rp .. " incorrect link (".. dst .."), skipping")
|
||||||
|
end
|
||||||
|
elseif t then
|
||||||
|
_log(rp .. " exist but is no link (".. t .."), skipping")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function usrmerge.migrate(d)
|
||||||
|
local errors = 0
|
||||||
|
for i, name in ipairs(posix.dir(d)) do
|
||||||
|
if name ~= '.' and name ~= '..' then
|
||||||
|
local p = d .. "/" .. name
|
||||||
|
local up = "/usr" .. p
|
||||||
|
local t = posix.stat(p, "type")
|
||||||
|
local ut = posix.stat(up, "type")
|
||||||
|
if ut == nil or (ut == "link" and t ~= "link") then
|
||||||
|
local f = posix.link
|
||||||
|
if t == "directory" then
|
||||||
|
-- can't hardlink dirs so move it
|
||||||
|
f = posix.rename
|
||||||
|
end
|
||||||
|
if ut ~= nil then
|
||||||
|
_log(" removing " .. up)
|
||||||
|
posix.unlink(up)
|
||||||
|
end
|
||||||
|
local ok, err, e = f(p, up)
|
||||||
|
if ok == nil then
|
||||||
|
print("FAILED " .. p .. " -> " .. up .. ": " .. err)
|
||||||
|
errors = errors + 1
|
||||||
|
else
|
||||||
|
_log(p .. " -> " .. up)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if t == "directory" then
|
||||||
|
print("BAD " .. p .. " is a directory but " .. up .. "exists")
|
||||||
|
errors = errors + 1
|
||||||
|
else
|
||||||
|
_log("skipped " .. p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if errors > 0 then
|
||||||
|
print("have to continue despire errors")
|
||||||
|
end
|
||||||
|
local ok, err, e = posix.rename(d, d .. ".merged")
|
||||||
|
if ok == nil then
|
||||||
|
print("FAILED to move " .. d .. " out of the way")
|
||||||
|
else
|
||||||
|
ok, err, e = posix.symlink("usr" ..d, d)
|
||||||
|
if ok == nil then
|
||||||
|
print("FAILED to recreate " .. d .. " as link. Now we're in deep shit, sorry :-/")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
99
usrmerge_binsbindeps.lua
Normal file
99
usrmerge_binsbindeps.lua
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
usrmerge_binsbindeps = {
|
||||||
|
-- 2ping 389-ds 389-ds-snmp 4ti2 AppStream ...
|
||||||
|
["/bin/sh"] = 1,
|
||||||
|
-- 4store AppCSXCAD Cadence ComputeLibrary HepMC-devel ...
|
||||||
|
["/bin/bash"] = 1,
|
||||||
|
-- FreeCAD Herwig-libs Mesa Mesa-libEGL1 Mesa-libGL1 ...
|
||||||
|
["/sbin/ldconfig"] = 1,
|
||||||
|
-- aaa_base ctdb cvs yast2-printer
|
||||||
|
["/bin/mktemp"] = 1,
|
||||||
|
-- avrdude os-prober uisp
|
||||||
|
["/sbin/modprobe"] = 1,
|
||||||
|
-- bind
|
||||||
|
["/sbin/start_daemon"] = 1,
|
||||||
|
-- budgie-screensaver xscreensaver
|
||||||
|
["/sbin/unix2_chkpwd"] = 1,
|
||||||
|
-- canna compiz-branding-SLED compiz-branding-openSUSE compiz-branding-upstream ini4j-javadoc ...
|
||||||
|
["/bin/rm"] = 1,
|
||||||
|
-- clamav enscript gpm hplip lsb ...
|
||||||
|
["/bin/sed"] = 1,
|
||||||
|
-- clamav icecream lsb
|
||||||
|
["/bin/tar"] = 1,
|
||||||
|
-- cobbler
|
||||||
|
["/sbin/service"] = 1,
|
||||||
|
-- compiz-branding-SLED compiz-branding-openSUSE compiz-branding-upstream ini4j-javadoc install-initrd-Kubic ...
|
||||||
|
["/bin/ln"] = 1,
|
||||||
|
-- corosync eid-mw postgresql10-server
|
||||||
|
["/sbin/chkconfig"] = 1,
|
||||||
|
-- dds2tar dt fpc-src lua-lmod petsc-devel ...
|
||||||
|
["/bin/csh"] = 1,
|
||||||
|
-- glibc-locale-base jfbterm lsb uisp
|
||||||
|
["/bin/cat"] = 1,
|
||||||
|
-- hplip os-prober
|
||||||
|
["/bin/grep"] = 1,
|
||||||
|
-- kdevplatform
|
||||||
|
["/bin/zsh"] = 1,
|
||||||
|
-- ksh lsb twin
|
||||||
|
["/bin/true"] = 1,
|
||||||
|
-- libgtop-doc
|
||||||
|
["/sbin/install-info"] = 1,
|
||||||
|
-- logdigest lsb
|
||||||
|
["/bin/chmod"] = 1,
|
||||||
|
-- logdigest lsb sound-theme-freedesktop tei_4
|
||||||
|
["/bin/touch"] = 1,
|
||||||
|
-- lsb
|
||||||
|
["/bin/chgrp"] = 1,
|
||||||
|
["/bin/chown"] = 1,
|
||||||
|
["/bin/dd"] = 1,
|
||||||
|
["/bin/df"] = 1,
|
||||||
|
["/bin/echo"] = 1,
|
||||||
|
["/bin/false"] = 1,
|
||||||
|
["/bin/kill"] = 1,
|
||||||
|
["/bin/mknod"] = 1,
|
||||||
|
["/bin/more"] = 1,
|
||||||
|
["/bin/mount"] = 1,
|
||||||
|
["/bin/mv"] = 1,
|
||||||
|
["/bin/ps"] = 1,
|
||||||
|
["/bin/pwd"] = 1,
|
||||||
|
["/bin/rmdir"] = 1,
|
||||||
|
["/bin/sleep"] = 1,
|
||||||
|
["/bin/sort"] = 1,
|
||||||
|
["/bin/sync"] = 1,
|
||||||
|
["/bin/umount"] = 1,
|
||||||
|
["/bin/uname"] = 1,
|
||||||
|
["/sbin/shutdown"] = 1,
|
||||||
|
-- lsb lynx
|
||||||
|
["/bin/cp"] = 1,
|
||||||
|
-- lsb mariadb openwsman-server patch2mail xorg-x11-Xvnc ...
|
||||||
|
["/bin/hostname"] = 1,
|
||||||
|
-- lsb nagios nagios-www ntp sca-appliance-common ...
|
||||||
|
["/bin/logger"] = 1,
|
||||||
|
-- lsb perl-Term-ReadKey
|
||||||
|
["/bin/stty"] = 1,
|
||||||
|
-- lsb sendmail
|
||||||
|
["/bin/fuser"] = 1,
|
||||||
|
-- lsb texlive-cjk-latex-extras
|
||||||
|
["/bin/mkdir"] = 1,
|
||||||
|
-- lsb vnstat
|
||||||
|
["/bin/ls"] = 1,
|
||||||
|
["/bin/su"] = 1,
|
||||||
|
-- mdadm
|
||||||
|
["/sbin/mkinitrd"] = 1,
|
||||||
|
-- memtest86+
|
||||||
|
["/sbin/update-bootloader"] = 1,
|
||||||
|
-- sca-appliance-common
|
||||||
|
["/bin/ping"] = 1,
|
||||||
|
-- setserial
|
||||||
|
["/sbin/isserial"] = 1,
|
||||||
|
-- sgml-skel xorg-x11-Xvnc
|
||||||
|
["/bin/awk"] = 1,
|
||||||
|
-- sysconfig
|
||||||
|
["/sbin/ifup"] = 1,
|
||||||
|
["/sbin/netconfig"] = 1,
|
||||||
|
-- sysconfig-netconfig
|
||||||
|
["/bin/gawk"] = 1,
|
||||||
|
-- vpnc
|
||||||
|
["/sbin/ip"] = 1,
|
||||||
|
-- xdm
|
||||||
|
["/sbin/startproc"] = 1,
|
||||||
|
}
|
655
usrmerge_files.lua
Normal file
655
usrmerge_files.lua
Normal file
@ -0,0 +1,655 @@
|
|||||||
|
usrmerge_files = {
|
||||||
|
-- aaa_base
|
||||||
|
["/sbin/refresh_initrd"] = 1,
|
||||||
|
["/sbin/service"] = 1,
|
||||||
|
["/sbin/smart_agetty"] = 1,
|
||||||
|
-- apparmor-parser
|
||||||
|
["/sbin/apparmor_parser"] = 1,
|
||||||
|
["/sbin/rcapparmor"] = 1,
|
||||||
|
-- audit
|
||||||
|
["/sbin/audispd"] = 1,
|
||||||
|
["/sbin/auditctl"] = 1,
|
||||||
|
["/sbin/auditd"] = 1,
|
||||||
|
["/sbin/augenrules"] = 1,
|
||||||
|
["/sbin/aureport"] = 1,
|
||||||
|
["/sbin/ausearch"] = 1,
|
||||||
|
["/sbin/autrace"] = 1,
|
||||||
|
-- aws-efs-utils
|
||||||
|
["/sbin/mount.efs"] = 1,
|
||||||
|
-- bash
|
||||||
|
["/bin/bash"] = 1,
|
||||||
|
["/bin/sh"] = 1,
|
||||||
|
-- biosdevname
|
||||||
|
["/sbin/biosdevname"] = 1,
|
||||||
|
-- blktrace
|
||||||
|
["/bin/blkparse"] = 1,
|
||||||
|
["/bin/blktrace"] = 1,
|
||||||
|
["/bin/btrace"] = 1,
|
||||||
|
-- blog
|
||||||
|
["/sbin/blogctl"] = 1,
|
||||||
|
["/sbin/blogd"] = 1,
|
||||||
|
["/sbin/blogger"] = 1,
|
||||||
|
["/sbin/isserial"] = 1,
|
||||||
|
["/sbin/setconsole"] = 1,
|
||||||
|
["/sbin/showconsole"] = 1,
|
||||||
|
-- btrfsprogs
|
||||||
|
["/sbin/btrfs"] = 1,
|
||||||
|
["/sbin/btrfs-convert"] = 1,
|
||||||
|
["/sbin/btrfs-image"] = 1,
|
||||||
|
["/sbin/btrfsck"] = 1,
|
||||||
|
["/sbin/btrfstune"] = 1,
|
||||||
|
["/sbin/fsck.btrfs"] = 1,
|
||||||
|
["/sbin/mkfs.btrfs"] = 1,
|
||||||
|
-- ceph-common
|
||||||
|
["/sbin/mount.ceph"] = 1,
|
||||||
|
-- cifs-utils
|
||||||
|
["/sbin/mount.cifs"] = 1,
|
||||||
|
["/sbin/mount.smb3"] = 1,
|
||||||
|
-- coreutils coreutils-single
|
||||||
|
["/bin/arch"] = 1,
|
||||||
|
["/bin/basename"] = 1,
|
||||||
|
["/bin/cat"] = 1,
|
||||||
|
["/bin/chgrp"] = 1,
|
||||||
|
["/bin/chmod"] = 1,
|
||||||
|
["/bin/chown"] = 1,
|
||||||
|
["/bin/cp"] = 1,
|
||||||
|
["/bin/date"] = 1,
|
||||||
|
["/bin/dd"] = 1,
|
||||||
|
["/bin/df"] = 1,
|
||||||
|
["/bin/echo"] = 1,
|
||||||
|
["/bin/false"] = 1,
|
||||||
|
["/bin/ln"] = 1,
|
||||||
|
["/bin/ls"] = 1,
|
||||||
|
["/bin/md5sum"] = 1,
|
||||||
|
["/bin/mkdir"] = 1,
|
||||||
|
["/bin/mknod"] = 1,
|
||||||
|
["/bin/mktemp"] = 1,
|
||||||
|
["/bin/mv"] = 1,
|
||||||
|
["/bin/pwd"] = 1,
|
||||||
|
["/bin/readlink"] = 1,
|
||||||
|
["/bin/rm"] = 1,
|
||||||
|
["/bin/rmdir"] = 1,
|
||||||
|
["/bin/sleep"] = 1,
|
||||||
|
["/bin/sort"] = 1,
|
||||||
|
["/bin/stat"] = 1,
|
||||||
|
["/bin/stty"] = 1,
|
||||||
|
["/bin/sync"] = 1,
|
||||||
|
["/bin/touch"] = 1,
|
||||||
|
["/bin/true"] = 1,
|
||||||
|
["/bin/uname"] = 1,
|
||||||
|
-- cpio
|
||||||
|
["/bin/cpio"] = 1,
|
||||||
|
-- crda
|
||||||
|
["/sbin/crda"] = 1,
|
||||||
|
["/sbin/regdbdump"] = 1,
|
||||||
|
-- cryptsetup
|
||||||
|
["/sbin/cryptsetup"] = 1,
|
||||||
|
-- dash
|
||||||
|
["/bin/dash"] = 1,
|
||||||
|
-- davfs2
|
||||||
|
["/sbin/mount.davfs"] = 1,
|
||||||
|
["/sbin/umount.davfs"] = 1,
|
||||||
|
-- dbus-1
|
||||||
|
["/bin/dbus-cleanup-sockets"] = 1,
|
||||||
|
["/bin/dbus-daemon"] = 1,
|
||||||
|
["/bin/dbus-monitor"] = 1,
|
||||||
|
["/bin/dbus-send"] = 1,
|
||||||
|
["/bin/dbus-test-tool"] = 1,
|
||||||
|
["/bin/dbus-update-activation-environment"] = 1,
|
||||||
|
["/bin/dbus-uuidgen"] = 1,
|
||||||
|
-- dd_rescue
|
||||||
|
["/bin/dd_rescue"] = 1,
|
||||||
|
-- dd_rhelp
|
||||||
|
["/bin/dd_rhelp"] = 1,
|
||||||
|
-- device-mapper
|
||||||
|
["/sbin/dmsetup"] = 1,
|
||||||
|
-- dhcp-client
|
||||||
|
["/sbin/dhclient"] = 1,
|
||||||
|
["/sbin/dhclient-script"] = 1,
|
||||||
|
["/sbin/dhclient6"] = 1,
|
||||||
|
-- diod
|
||||||
|
["/sbin/mount.diod"] = 1,
|
||||||
|
-- dmraid
|
||||||
|
["/sbin/dmevent_tool"] = 1,
|
||||||
|
["/sbin/dmraid"] = 1,
|
||||||
|
-- dosfstools
|
||||||
|
["/sbin/dosfsck"] = 1,
|
||||||
|
["/sbin/dosfslabel"] = 1,
|
||||||
|
["/sbin/fsck.fat"] = 1,
|
||||||
|
["/sbin/fsck.msdos"] = 1,
|
||||||
|
["/sbin/fsck.vfat"] = 1,
|
||||||
|
["/sbin/mkdosfs"] = 1,
|
||||||
|
["/sbin/mkfs.fat"] = 1,
|
||||||
|
["/sbin/mkfs.msdos"] = 1,
|
||||||
|
["/sbin/mkfs.vfat"] = 1,
|
||||||
|
-- dracut
|
||||||
|
["/sbin/installkernel"] = 1,
|
||||||
|
["/sbin/mkinitrd"] = 1,
|
||||||
|
-- drbd-utils
|
||||||
|
["/sbin/drbdadm"] = 1,
|
||||||
|
["/sbin/drbdmeta"] = 1,
|
||||||
|
["/sbin/drbdmon"] = 1,
|
||||||
|
["/sbin/drbdsetup"] = 1,
|
||||||
|
-- e2fsprogs
|
||||||
|
["/sbin/badblocks"] = 1,
|
||||||
|
["/sbin/debugfs"] = 1,
|
||||||
|
["/sbin/dumpe2fs"] = 1,
|
||||||
|
["/sbin/e2fsck"] = 1,
|
||||||
|
["/sbin/e2image"] = 1,
|
||||||
|
["/sbin/e2label"] = 1,
|
||||||
|
["/sbin/e2mmpstatus"] = 1,
|
||||||
|
["/sbin/e2undo"] = 1,
|
||||||
|
["/sbin/fsck.ext2"] = 1,
|
||||||
|
["/sbin/fsck.ext3"] = 1,
|
||||||
|
["/sbin/fsck.ext4"] = 1,
|
||||||
|
["/sbin/logsave"] = 1,
|
||||||
|
["/sbin/mke2fs"] = 1,
|
||||||
|
["/sbin/mkfs.ext2"] = 1,
|
||||||
|
["/sbin/mkfs.ext3"] = 1,
|
||||||
|
["/sbin/mkfs.ext4"] = 1,
|
||||||
|
["/sbin/resize2fs"] = 1,
|
||||||
|
["/sbin/tune2fs"] = 1,
|
||||||
|
-- ecryptfs-utils
|
||||||
|
["/sbin/mount.ecryptfs"] = 1,
|
||||||
|
["/sbin/mount.ecryptfs_private"] = 1,
|
||||||
|
["/sbin/umount.ecryptfs"] = 1,
|
||||||
|
["/sbin/umount.ecryptfs_private"] = 1,
|
||||||
|
-- ed
|
||||||
|
["/bin/ed"] = 1,
|
||||||
|
-- elilo
|
||||||
|
["/sbin/elilo"] = 1,
|
||||||
|
["/sbin/eliloalt"] = 1,
|
||||||
|
-- exfat-utils
|
||||||
|
["/sbin/dumpexfat"] = 1,
|
||||||
|
["/sbin/exfatfsck"] = 1,
|
||||||
|
["/sbin/exfatlabel"] = 1,
|
||||||
|
["/sbin/fsck.exfat"] = 1,
|
||||||
|
["/sbin/mkexfatfs"] = 1,
|
||||||
|
["/sbin/mkfs.exfat"] = 1,
|
||||||
|
-- f2fs-tools-compat
|
||||||
|
["/sbin/defrag.f2fs"] = 1,
|
||||||
|
["/sbin/dump.f2fs"] = 1,
|
||||||
|
["/sbin/f2fstat"] = 1,
|
||||||
|
["/sbin/fibmap.f2fs"] = 1,
|
||||||
|
["/sbin/fsck.f2fs"] = 1,
|
||||||
|
["/sbin/mkfs.f2fs"] = 1,
|
||||||
|
["/sbin/parse.f2fs"] = 1,
|
||||||
|
["/sbin/resize.f2fs"] = 1,
|
||||||
|
["/sbin/sload.f2fs"] = 1,
|
||||||
|
-- fedfs-utils-client
|
||||||
|
["/sbin/mount.fedfs"] = 1,
|
||||||
|
-- fillup
|
||||||
|
["/bin/fillup"] = 1,
|
||||||
|
-- findutils
|
||||||
|
["/bin/find"] = 1,
|
||||||
|
-- fuse
|
||||||
|
["/sbin/mount.fuse"] = 1,
|
||||||
|
-- fuse-exfat
|
||||||
|
["/sbin/mount.exfat"] = 1,
|
||||||
|
["/sbin/mount.exfat-fuse"] = 1,
|
||||||
|
-- fxload
|
||||||
|
["/sbin/fxload"] = 1,
|
||||||
|
-- gawk
|
||||||
|
["/bin/gawk"] = 1,
|
||||||
|
-- gawk mawk
|
||||||
|
["/bin/awk"] = 1,
|
||||||
|
-- glibc
|
||||||
|
["/sbin/ldconfig"] = 1,
|
||||||
|
-- glusterfs
|
||||||
|
["/sbin/mount.glusterfs"] = 1,
|
||||||
|
-- grep
|
||||||
|
["/bin/egrep"] = 1,
|
||||||
|
["/bin/fgrep"] = 1,
|
||||||
|
["/bin/grep"] = 1,
|
||||||
|
-- grubby
|
||||||
|
["/sbin/grubby"] = 1,
|
||||||
|
["/sbin/new-kernel-pkg"] = 1,
|
||||||
|
-- gzip
|
||||||
|
["/bin/gunzip"] = 1,
|
||||||
|
["/bin/gzip"] = 1,
|
||||||
|
["/bin/zcat"] = 1,
|
||||||
|
-- hdparm
|
||||||
|
["/sbin/hdparm"] = 1,
|
||||||
|
["/sbin/wiper.sh"] = 1,
|
||||||
|
-- hostname
|
||||||
|
["/bin/dnsdomainname"] = 1,
|
||||||
|
["/bin/domainname"] = 1,
|
||||||
|
["/bin/hostname"] = 1,
|
||||||
|
["/bin/nisdomainname"] = 1,
|
||||||
|
["/bin/ypdomainname"] = 1,
|
||||||
|
-- info
|
||||||
|
["/sbin/install-info"] = 1,
|
||||||
|
-- info4
|
||||||
|
["/sbin/install-info4"] = 1,
|
||||||
|
-- initviocons
|
||||||
|
["/bin/initviocons"] = 1,
|
||||||
|
-- insserv-compat
|
||||||
|
["/sbin/chkconfig"] = 1,
|
||||||
|
["/sbin/insserv"] = 1,
|
||||||
|
-- iproute2
|
||||||
|
["/bin/ip"] = 1,
|
||||||
|
["/sbin/ip"] = 1,
|
||||||
|
-- iputils
|
||||||
|
["/bin/arping"] = 1,
|
||||||
|
["/bin/clockdiff"] = 1,
|
||||||
|
["/bin/ping"] = 1,
|
||||||
|
["/bin/ping6"] = 1,
|
||||||
|
["/bin/tracepath"] = 1,
|
||||||
|
["/bin/tracepath6"] = 1,
|
||||||
|
["/sbin/rdisc"] = 1,
|
||||||
|
-- ipvsadm
|
||||||
|
["/sbin/ipvsadm"] = 1,
|
||||||
|
["/sbin/ipvsadm-restore"] = 1,
|
||||||
|
["/sbin/ipvsadm-save"] = 1,
|
||||||
|
-- iscsiuio
|
||||||
|
["/sbin/brcm_iscsiuio"] = 1,
|
||||||
|
["/sbin/iscsiuio"] = 1,
|
||||||
|
-- jfsutils
|
||||||
|
["/sbin/fsck.jfs"] = 1,
|
||||||
|
["/sbin/jfs_debugfs"] = 1,
|
||||||
|
["/sbin/jfs_fsck"] = 1,
|
||||||
|
["/sbin/jfs_fscklog"] = 1,
|
||||||
|
["/sbin/jfs_logdump"] = 1,
|
||||||
|
["/sbin/jfs_mkfs"] = 1,
|
||||||
|
["/sbin/jfs_tune"] = 1,
|
||||||
|
["/sbin/mkfs.jfs"] = 1,
|
||||||
|
-- kbd
|
||||||
|
["/bin/chvt"] = 1,
|
||||||
|
["/bin/clrunimap"] = 1,
|
||||||
|
["/bin/deallocvt"] = 1,
|
||||||
|
["/bin/dumpkeys"] = 1,
|
||||||
|
["/bin/fgconsole"] = 1,
|
||||||
|
["/bin/getkeycodes"] = 1,
|
||||||
|
["/bin/getunimap"] = 1,
|
||||||
|
["/bin/kbd_mode"] = 1,
|
||||||
|
["/bin/kbdinfo"] = 1,
|
||||||
|
["/bin/kbdrate"] = 1,
|
||||||
|
["/bin/loadkeys"] = 1,
|
||||||
|
["/bin/loadunimap"] = 1,
|
||||||
|
["/bin/mapscrn"] = 1,
|
||||||
|
["/bin/openvt"] = 1,
|
||||||
|
["/bin/outpsfheader"] = 1,
|
||||||
|
["/bin/psfaddtable"] = 1,
|
||||||
|
["/bin/psfgettable"] = 1,
|
||||||
|
["/bin/psfstriptable"] = 1,
|
||||||
|
["/bin/psfxtable"] = 1,
|
||||||
|
["/bin/resizecons"] = 1,
|
||||||
|
["/bin/screendump"] = 1,
|
||||||
|
["/bin/setfont"] = 1,
|
||||||
|
["/bin/setkeycodes"] = 1,
|
||||||
|
["/bin/setleds"] = 1,
|
||||||
|
["/bin/setlogcons"] = 1,
|
||||||
|
["/bin/setmetamode"] = 1,
|
||||||
|
["/bin/setpalette"] = 1,
|
||||||
|
["/bin/setvesablank"] = 1,
|
||||||
|
["/bin/setvtrgb"] = 1,
|
||||||
|
["/bin/showconsolefont"] = 1,
|
||||||
|
["/bin/showkey"] = 1,
|
||||||
|
["/bin/spawn_console"] = 1,
|
||||||
|
["/bin/spawn_login"] = 1,
|
||||||
|
["/bin/unicode_start"] = 1,
|
||||||
|
["/bin/unicode_stop"] = 1,
|
||||||
|
["/sbin/fbtest"] = 1,
|
||||||
|
-- kexec-tools
|
||||||
|
["/sbin/kexec"] = 1,
|
||||||
|
-- keyutils
|
||||||
|
["/bin/keyctl"] = 1,
|
||||||
|
["/sbin/key.dns_resolver"] = 1,
|
||||||
|
["/sbin/request-key"] = 1,
|
||||||
|
-- klogd
|
||||||
|
["/sbin/klogd"] = 1,
|
||||||
|
-- kmod
|
||||||
|
["/bin/lsmod"] = 1,
|
||||||
|
["/sbin/depmod"] = 1,
|
||||||
|
["/sbin/insmod"] = 1,
|
||||||
|
["/sbin/lsmod"] = 1,
|
||||||
|
["/sbin/modinfo"] = 1,
|
||||||
|
["/sbin/modprobe"] = 1,
|
||||||
|
["/sbin/rmmod"] = 1,
|
||||||
|
-- kpartx
|
||||||
|
["/sbin/kpartx"] = 1,
|
||||||
|
-- ksh
|
||||||
|
["/bin/ksh93"] = 1,
|
||||||
|
-- ksh mksh
|
||||||
|
["/bin/ksh"] = 1,
|
||||||
|
-- libewf-tools
|
||||||
|
["/sbin/mount.ewf"] = 1,
|
||||||
|
["/sbin/umount.ewf"] = 1,
|
||||||
|
-- live-net-installer
|
||||||
|
["/bin/extend"] = 1,
|
||||||
|
-- lvm2
|
||||||
|
["/sbin/lvchange"] = 1,
|
||||||
|
["/sbin/lvconvert"] = 1,
|
||||||
|
["/sbin/lvcreate"] = 1,
|
||||||
|
["/sbin/lvdisplay"] = 1,
|
||||||
|
["/sbin/lvextend"] = 1,
|
||||||
|
["/sbin/lvm"] = 1,
|
||||||
|
["/sbin/lvmconfig"] = 1,
|
||||||
|
["/sbin/lvmdiskscan"] = 1,
|
||||||
|
["/sbin/lvmdump"] = 1,
|
||||||
|
["/sbin/lvmpolld"] = 1,
|
||||||
|
["/sbin/lvmsadc"] = 1,
|
||||||
|
["/sbin/lvmsar"] = 1,
|
||||||
|
["/sbin/lvreduce"] = 1,
|
||||||
|
["/sbin/lvremove"] = 1,
|
||||||
|
["/sbin/lvrename"] = 1,
|
||||||
|
["/sbin/lvresize"] = 1,
|
||||||
|
["/sbin/lvs"] = 1,
|
||||||
|
["/sbin/lvscan"] = 1,
|
||||||
|
["/sbin/pvchange"] = 1,
|
||||||
|
["/sbin/pvck"] = 1,
|
||||||
|
["/sbin/pvcreate"] = 1,
|
||||||
|
["/sbin/pvdisplay"] = 1,
|
||||||
|
["/sbin/pvmove"] = 1,
|
||||||
|
["/sbin/pvremove"] = 1,
|
||||||
|
["/sbin/pvresize"] = 1,
|
||||||
|
["/sbin/pvs"] = 1,
|
||||||
|
["/sbin/pvscan"] = 1,
|
||||||
|
["/sbin/vgcfgbackup"] = 1,
|
||||||
|
["/sbin/vgcfgrestore"] = 1,
|
||||||
|
["/sbin/vgchange"] = 1,
|
||||||
|
["/sbin/vgck"] = 1,
|
||||||
|
["/sbin/vgconvert"] = 1,
|
||||||
|
["/sbin/vgcreate"] = 1,
|
||||||
|
["/sbin/vgdisplay"] = 1,
|
||||||
|
["/sbin/vgexport"] = 1,
|
||||||
|
["/sbin/vgextend"] = 1,
|
||||||
|
["/sbin/vgimport"] = 1,
|
||||||
|
["/sbin/vgimportclone"] = 1,
|
||||||
|
["/sbin/vgmerge"] = 1,
|
||||||
|
["/sbin/vgmknodes"] = 1,
|
||||||
|
["/sbin/vgreduce"] = 1,
|
||||||
|
["/sbin/vgremove"] = 1,
|
||||||
|
["/sbin/vgrename"] = 1,
|
||||||
|
["/sbin/vgs"] = 1,
|
||||||
|
["/sbin/vgscan"] = 1,
|
||||||
|
["/sbin/vgsplit"] = 1,
|
||||||
|
-- mailutils mailx
|
||||||
|
["/bin/mail"] = 1,
|
||||||
|
-- makedev
|
||||||
|
["/sbin/MAKEDEV"] = 1,
|
||||||
|
-- mawk
|
||||||
|
["/bin/mawk"] = 1,
|
||||||
|
-- mcstrans
|
||||||
|
["/sbin/mcstransd"] = 1,
|
||||||
|
-- mdadm
|
||||||
|
["/sbin/mdadm"] = 1,
|
||||||
|
["/sbin/mdmon"] = 1,
|
||||||
|
-- mingetty
|
||||||
|
["/sbin/mingetty"] = 1,
|
||||||
|
-- mksh
|
||||||
|
["/bin/lksh"] = 1,
|
||||||
|
["/bin/mksh"] = 1,
|
||||||
|
["/bin/pdksh"] = 1,
|
||||||
|
-- multipath-tools
|
||||||
|
["/sbin/mpathpersist"] = 1,
|
||||||
|
["/sbin/multipath"] = 1,
|
||||||
|
["/sbin/multipathd"] = 1,
|
||||||
|
-- munin
|
||||||
|
["/sbin/rcmunin-cgi-graph"] = 1,
|
||||||
|
["/sbin/rcmunin-cgi-html"] = 1,
|
||||||
|
-- munin-node
|
||||||
|
["/sbin/rcmunin-node"] = 1,
|
||||||
|
-- net-tools
|
||||||
|
["/sbin/ether-wake"] = 1,
|
||||||
|
["/sbin/nameif"] = 1,
|
||||||
|
["/sbin/plipconfig"] = 1,
|
||||||
|
["/sbin/slattach"] = 1,
|
||||||
|
-- net-tools-deprecated
|
||||||
|
["/bin/ifconfig"] = 1,
|
||||||
|
["/bin/netstat"] = 1,
|
||||||
|
["/bin/route"] = 1,
|
||||||
|
["/sbin/arp"] = 1,
|
||||||
|
["/sbin/ipmaddr"] = 1,
|
||||||
|
["/sbin/iptunnel"] = 1,
|
||||||
|
-- netconsole-tools
|
||||||
|
["/sbin/netconsole-server"] = 1,
|
||||||
|
-- nfs-client
|
||||||
|
["/sbin/mount.nfs"] = 1,
|
||||||
|
["/sbin/mount.nfs4"] = 1,
|
||||||
|
["/sbin/umount.nfs"] = 1,
|
||||||
|
["/sbin/umount.nfs4"] = 1,
|
||||||
|
-- nfs-kernel-server
|
||||||
|
["/sbin/nfsdcltrack"] = 1,
|
||||||
|
-- nilfs-utils
|
||||||
|
["/sbin/mkfs.nilfs2"] = 1,
|
||||||
|
["/sbin/mount.nilfs2"] = 1,
|
||||||
|
["/sbin/nilfs_cleanerd"] = 1,
|
||||||
|
["/sbin/umount.nilfs2"] = 1,
|
||||||
|
-- ntfs-3g
|
||||||
|
["/sbin/mount.lowntfs-3g"] = 1,
|
||||||
|
["/sbin/mount.ntfs"] = 1,
|
||||||
|
["/sbin/mount.ntfs-3g"] = 1,
|
||||||
|
-- ntfsprogs
|
||||||
|
["/sbin/mkfs.ntfs"] = 1,
|
||||||
|
-- ocfs2-tools
|
||||||
|
["/sbin/fsck.ocfs2"] = 1,
|
||||||
|
["/sbin/mkfs.ocfs2"] = 1,
|
||||||
|
["/sbin/mount.ocfs2"] = 1,
|
||||||
|
["/sbin/mounted.ocfs2"] = 1,
|
||||||
|
["/sbin/o2cluster"] = 1,
|
||||||
|
["/sbin/ocfs2_hb_ctl"] = 1,
|
||||||
|
["/sbin/tunefs.ocfs2"] = 1,
|
||||||
|
-- ocfs2-tools-o2cb
|
||||||
|
["/sbin/o2cb"] = 1,
|
||||||
|
["/sbin/o2cb.init"] = 1,
|
||||||
|
["/sbin/o2cb_ctl"] = 1,
|
||||||
|
["/sbin/ocfs2.init"] = 1,
|
||||||
|
-- ooRexx
|
||||||
|
["/sbin/rcooRexx"] = 1,
|
||||||
|
-- open-iscsi
|
||||||
|
["/sbin/iscsi-gen-initiatorname"] = 1,
|
||||||
|
["/sbin/iscsi-iname"] = 1,
|
||||||
|
["/sbin/iscsi_discovery"] = 1,
|
||||||
|
["/sbin/iscsi_fw_login"] = 1,
|
||||||
|
["/sbin/iscsi_offload"] = 1,
|
||||||
|
["/sbin/iscsiadm"] = 1,
|
||||||
|
["/sbin/iscsid"] = 1,
|
||||||
|
["/sbin/iscsistart"] = 1,
|
||||||
|
-- open-vm-tools
|
||||||
|
["/sbin/mount.vmhgfs"] = 1,
|
||||||
|
-- pam
|
||||||
|
["/sbin/faillock"] = 1,
|
||||||
|
["/sbin/mkhomedir_helper"] = 1,
|
||||||
|
["/sbin/pam_namespace_helper"] = 1,
|
||||||
|
["/sbin/pam_timestamp_check"] = 1,
|
||||||
|
["/sbin/pwhistory_helper"] = 1,
|
||||||
|
["/sbin/unix2_chkpwd"] = 1,
|
||||||
|
["/sbin/unix_chkpwd"] = 1,
|
||||||
|
["/sbin/unix_update"] = 1,
|
||||||
|
-- pam-deprecated
|
||||||
|
["/sbin/pam_tally2"] = 1,
|
||||||
|
-- pam_mount
|
||||||
|
["/sbin/mount.crypt"] = 1,
|
||||||
|
["/sbin/mount.crypt_LUKS"] = 1,
|
||||||
|
["/sbin/umount.crypt"] = 1,
|
||||||
|
["/sbin/umount.crypt_LUKS"] = 1,
|
||||||
|
-- pciutils
|
||||||
|
["/sbin/lspci"] = 1,
|
||||||
|
["/sbin/setpci"] = 1,
|
||||||
|
-- pcmciautils
|
||||||
|
["/sbin/lspcmcia"] = 1,
|
||||||
|
["/sbin/pccardctl"] = 1,
|
||||||
|
-- perl-Bootloader
|
||||||
|
["/sbin/pbl"] = 1,
|
||||||
|
["/sbin/update-bootloader"] = 1,
|
||||||
|
-- plymouth
|
||||||
|
["/bin/plymouth"] = 1,
|
||||||
|
-- policycoreutils
|
||||||
|
["/sbin/restorecon"] = 1,
|
||||||
|
["/sbin/restorecon_xattr"] = 1,
|
||||||
|
["/sbin/setfiles"] = 1,
|
||||||
|
-- polkit-default-privs
|
||||||
|
["/sbin/chkstat-polkit"] = 1,
|
||||||
|
["/sbin/set_polkit_default_privs"] = 1,
|
||||||
|
-- powerd
|
||||||
|
["/sbin/detectups"] = 1,
|
||||||
|
["/sbin/powerd"] = 1,
|
||||||
|
-- procps
|
||||||
|
["/bin/pgrep"] = 1,
|
||||||
|
["/bin/pkill"] = 1,
|
||||||
|
["/bin/ps"] = 1,
|
||||||
|
["/sbin/sysctl"] = 1,
|
||||||
|
-- psmisc
|
||||||
|
["/bin/fuser"] = 1,
|
||||||
|
-- rarpd
|
||||||
|
["/sbin/rarpd"] = 1,
|
||||||
|
-- rash
|
||||||
|
["/bin/rash"] = 1,
|
||||||
|
-- reiserfs
|
||||||
|
["/sbin/debugfs.reiserfs"] = 1,
|
||||||
|
["/sbin/debugreiserfs"] = 1,
|
||||||
|
["/sbin/fsck.reiserfs"] = 1,
|
||||||
|
["/sbin/mkfs.reiserfs"] = 1,
|
||||||
|
["/sbin/mkreiserfs"] = 1,
|
||||||
|
["/sbin/reiserfsck"] = 1,
|
||||||
|
["/sbin/reiserfstune"] = 1,
|
||||||
|
["/sbin/resize_reiserfs"] = 1,
|
||||||
|
["/sbin/tunefs.reiserfs"] = 1,
|
||||||
|
-- rpcbind
|
||||||
|
["/bin/rpcinfo"] = 1,
|
||||||
|
["/sbin/pmap_set2"] = 1,
|
||||||
|
["/sbin/rpcbind"] = 1,
|
||||||
|
["/sbin/rpcinfo"] = 1,
|
||||||
|
-- rpm
|
||||||
|
["/bin/rpm"] = 1,
|
||||||
|
-- rsyslog
|
||||||
|
["/sbin/rsyslogd"] = 1,
|
||||||
|
-- rungetty
|
||||||
|
["/sbin/rungetty"] = 1,
|
||||||
|
-- scsh
|
||||||
|
["/bin/scsh"] = 1,
|
||||||
|
-- scsirastools
|
||||||
|
["/sbin/getmd"] = 1,
|
||||||
|
["/sbin/mdevt"] = 1,
|
||||||
|
["/sbin/sgdefects"] = 1,
|
||||||
|
["/sbin/sgdiag"] = 1,
|
||||||
|
["/sbin/sgdiskmon"] = 1,
|
||||||
|
["/sbin/sgdskfl"] = 1,
|
||||||
|
["/sbin/sgevt"] = 1,
|
||||||
|
["/sbin/sgmode"] = 1,
|
||||||
|
["/sbin/sgraidmon"] = 1,
|
||||||
|
["/sbin/sgsafte"] = 1,
|
||||||
|
-- sdparm
|
||||||
|
["/sbin/sas_disk_blink"] = 1,
|
||||||
|
["/sbin/scsi_ch_swp"] = 1,
|
||||||
|
["/sbin/sdparm"] = 1,
|
||||||
|
-- sed
|
||||||
|
["/bin/sed"] = 1,
|
||||||
|
-- supportutils
|
||||||
|
["/sbin/analyzevmcore"] = 1,
|
||||||
|
["/sbin/chkbin"] = 1,
|
||||||
|
["/sbin/getappcore"] = 1,
|
||||||
|
["/sbin/supportconfig"] = 1,
|
||||||
|
-- sysconfig
|
||||||
|
["/sbin/ifuser"] = 1,
|
||||||
|
["/sbin/rcnetwork"] = 1,
|
||||||
|
-- sysconfig-netconfig
|
||||||
|
["/sbin/netconfig"] = 1,
|
||||||
|
-- syslog-ng
|
||||||
|
["/sbin/syslog-ng"] = 1,
|
||||||
|
-- syslogd
|
||||||
|
["/sbin/syslogd"] = 1,
|
||||||
|
-- systemd-sysvinit
|
||||||
|
["/sbin/halt"] = 1,
|
||||||
|
["/sbin/init"] = 1,
|
||||||
|
["/sbin/poweroff"] = 1,
|
||||||
|
["/sbin/reboot"] = 1,
|
||||||
|
["/sbin/runlevel"] = 1,
|
||||||
|
["/sbin/shutdown"] = 1,
|
||||||
|
["/sbin/telinit"] = 1,
|
||||||
|
-- sysvinit-tools
|
||||||
|
["/bin/fsync"] = 1,
|
||||||
|
["/bin/usleep"] = 1,
|
||||||
|
["/sbin/checkproc"] = 1,
|
||||||
|
["/sbin/fstab-decode"] = 1,
|
||||||
|
["/sbin/killall5"] = 1,
|
||||||
|
["/sbin/killproc"] = 1,
|
||||||
|
["/sbin/mkill"] = 1,
|
||||||
|
["/sbin/pidofproc"] = 1,
|
||||||
|
["/sbin/rvmtab"] = 1,
|
||||||
|
["/sbin/start_daemon"] = 1,
|
||||||
|
["/sbin/startproc"] = 1,
|
||||||
|
["/sbin/vhangup"] = 1,
|
||||||
|
-- tar
|
||||||
|
["/bin/tar"] = 1,
|
||||||
|
-- tcsh
|
||||||
|
["/bin/csh"] = 1,
|
||||||
|
["/bin/tcsh"] = 1,
|
||||||
|
-- tomoyo-tools
|
||||||
|
["/sbin/tomoyo-init"] = 1,
|
||||||
|
-- tunctl
|
||||||
|
["/sbin/tunctl"] = 1,
|
||||||
|
-- udhcp
|
||||||
|
["/sbin/udhcpc"] = 1,
|
||||||
|
-- util-linux
|
||||||
|
["/bin/dmesg"] = 1,
|
||||||
|
["/bin/kill"] = 1,
|
||||||
|
["/bin/login"] = 1,
|
||||||
|
["/bin/more"] = 1,
|
||||||
|
["/bin/mount"] = 1,
|
||||||
|
["/bin/su"] = 1,
|
||||||
|
["/bin/umount"] = 1,
|
||||||
|
["/sbin/agetty"] = 1,
|
||||||
|
["/sbin/blkid"] = 1,
|
||||||
|
["/sbin/blockdev"] = 1,
|
||||||
|
["/sbin/cfdisk"] = 1,
|
||||||
|
["/sbin/chcpu"] = 1,
|
||||||
|
["/sbin/ctrlaltdel"] = 1,
|
||||||
|
["/sbin/fdisk"] = 1,
|
||||||
|
["/sbin/findfs"] = 1,
|
||||||
|
["/sbin/fsck"] = 1,
|
||||||
|
["/sbin/fsck.cramfs"] = 1,
|
||||||
|
["/sbin/fsck.minix"] = 1,
|
||||||
|
["/sbin/fsfreeze"] = 1,
|
||||||
|
["/sbin/fstrim"] = 1,
|
||||||
|
["/sbin/hwclock"] = 1,
|
||||||
|
["/sbin/losetup"] = 1,
|
||||||
|
["/sbin/mkfs"] = 1,
|
||||||
|
["/sbin/mkfs.bfs"] = 1,
|
||||||
|
["/sbin/mkfs.cramfs"] = 1,
|
||||||
|
["/sbin/mkfs.minix"] = 1,
|
||||||
|
["/sbin/mkswap"] = 1,
|
||||||
|
["/sbin/nologin"] = 1,
|
||||||
|
["/sbin/pivot_root"] = 1,
|
||||||
|
["/sbin/raw"] = 1,
|
||||||
|
["/sbin/sfdisk"] = 1,
|
||||||
|
["/sbin/swaplabel"] = 1,
|
||||||
|
["/sbin/swapoff"] = 1,
|
||||||
|
["/sbin/swapon"] = 1,
|
||||||
|
["/sbin/switch_root"] = 1,
|
||||||
|
["/sbin/wipefs"] = 1,
|
||||||
|
-- util-linux-systemd
|
||||||
|
["/bin/findmnt"] = 1,
|
||||||
|
["/bin/logger"] = 1,
|
||||||
|
["/bin/lsblk"] = 1,
|
||||||
|
-- vim
|
||||||
|
["/bin/ex"] = 1,
|
||||||
|
["/bin/vi"] = 1,
|
||||||
|
["/bin/vim"] = 1,
|
||||||
|
-- virtualbox
|
||||||
|
["/sbin/vboxconfig"] = 1,
|
||||||
|
-- virtualbox-guest-tools
|
||||||
|
["/sbin/mount.vboxsf"] = 1,
|
||||||
|
-- virtualbox-qt
|
||||||
|
["/sbin/vbox-fix-usb-rules.sh"] = 1,
|
||||||
|
-- vlan
|
||||||
|
["/sbin/vconfig"] = 1,
|
||||||
|
-- wicked-service
|
||||||
|
["/sbin/ifdown"] = 1,
|
||||||
|
["/sbin/ifprobe"] = 1,
|
||||||
|
["/sbin/ifstatus"] = 1,
|
||||||
|
["/sbin/ifup"] = 1,
|
||||||
|
-- xfsdump
|
||||||
|
["/sbin/xfsdump"] = 1,
|
||||||
|
["/sbin/xfsrestore"] = 1,
|
||||||
|
-- xfsprogs
|
||||||
|
["/sbin/fsck.xfs"] = 1,
|
||||||
|
["/sbin/mkfs.xfs"] = 1,
|
||||||
|
["/sbin/xfs_repair"] = 1,
|
||||||
|
-- yast2
|
||||||
|
["/sbin/yast"] = 1,
|
||||||
|
["/sbin/yast2"] = 1,
|
||||||
|
-- zsh
|
||||||
|
["/bin/zsh"] = 1,
|
||||||
|
}
|
351
usrmergecheck.c
Normal file
351
usrmergecheck.c
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2019,2020 SUSE LLC
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
|
||||||
|
#include <rpm/rpmts.h>
|
||||||
|
#include <rpm/rpmdb.h>
|
||||||
|
#include <rpm/rpmlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <rpm/rpmcli.h>
|
||||||
|
#include <rpm/header.h>
|
||||||
|
#include <rpm/rpmfiles.h>
|
||||||
|
|
||||||
|
static int verbose = 0;
|
||||||
|
|
||||||
|
const char *dirs[] = {
|
||||||
|
"/usr/bin",
|
||||||
|
"/usr/lib",
|
||||||
|
#if __WORDSIZE == 64
|
||||||
|
"/usr/lib64",
|
||||||
|
#endif
|
||||||
|
"/usr/sbin",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
// rpmdb stores dirs with slash
|
||||||
|
const char *rpmdirs[] = {
|
||||||
|
"/bin/",
|
||||||
|
"/lib/",
|
||||||
|
#if __WORDSIZE == 64
|
||||||
|
"/lib64/",
|
||||||
|
#endif
|
||||||
|
"/sbin/",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static inline int startswith(const char* s, const char* pfx) {
|
||||||
|
return strncmp(s, pfx, strlen(pfx)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char stm(mode_t m) {
|
||||||
|
switch (m & S_IFMT) {
|
||||||
|
case S_IFBLK: return 'b';
|
||||||
|
case S_IFCHR: return 'c';
|
||||||
|
case S_IFDIR: return 'd';
|
||||||
|
case S_IFIFO: return 'p';
|
||||||
|
case S_IFLNK: return 'l';
|
||||||
|
case S_IFREG: return 'f';
|
||||||
|
case S_IFSOCK: return 'S';
|
||||||
|
}
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_directory(const char* dir);
|
||||||
|
|
||||||
|
int check_entry(const char* p)
|
||||||
|
{
|
||||||
|
struct stat st, stu;
|
||||||
|
const char* rp = p+strlen("/usr");
|
||||||
|
// if the file doesn't exist in /usr we're safe
|
||||||
|
if(lstat(p, &stu)) {
|
||||||
|
if (errno != ENOENT) {
|
||||||
|
perror(p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (verbose > 1) printf("%s unique\n", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(lstat(rp, &st)) {
|
||||||
|
perror(rp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// differnt file type, check if one is link and can be dropped
|
||||||
|
if ((st.st_mode & S_IFMT) != (stu.st_mode & S_IFMT) || (S_ISLNK(st.st_mode) && S_ISLNK(stu.st_mode))) {
|
||||||
|
if (S_ISLNK(st.st_mode) || S_ISLNK(stu.st_mode)) {
|
||||||
|
struct stat sb1, sb2;
|
||||||
|
// if the link in / points to the file in /usr it's fine
|
||||||
|
// XXX: in theory there could be a weird
|
||||||
|
// chain of links pointing back and forth
|
||||||
|
// between /usr and /, we ignore that here
|
||||||
|
if(!stat(rp, &sb1) && !stat(p, &sb2) && sb1.st_ino == sb2.st_ino) {
|
||||||
|
if (verbose) printf("%s same file, ok\n", rp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s mode mismatch %c vs %c\n", rp, stm(st.st_mode), stm(stu.st_mode));
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
if (S_ISLNK(st.st_mode)) {
|
||||||
|
char t1[PATH_MAX] = {0};
|
||||||
|
char t2[PATH_MAX] = {0};
|
||||||
|
if(readlink(rp, t1, sizeof(t1)) == -1) {
|
||||||
|
perror(rp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(readlink(p, t2, sizeof(t2)) == -1) {
|
||||||
|
perror(p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(t1, t2)) {
|
||||||
|
if (verbose) {
|
||||||
|
printf("%s and %s both point %s, ok\n", rp, p, t1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s link mismatch %s vs %s\n", rp, t1, t2);
|
||||||
|
}
|
||||||
|
} else if (!S_ISDIR(st.st_mode)) {
|
||||||
|
fprintf(stderr, "%s duplicated\n", rp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// both are directories, check recursive
|
||||||
|
return check_directory(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_directory(const char* dir)
|
||||||
|
{
|
||||||
|
DIR* dh;
|
||||||
|
struct dirent* d;
|
||||||
|
unsigned failed = 0;
|
||||||
|
|
||||||
|
dh = opendir(dir+strlen("/usr"));
|
||||||
|
if (!dh) {
|
||||||
|
perror(dir);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
while ((d = readdir(dh))) {
|
||||||
|
char p[PATH_MAX] = {0};
|
||||||
|
|
||||||
|
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
stpcpy(stpcpy(stpcpy(p, dir), "/"), d->d_name);
|
||||||
|
|
||||||
|
failed += check_entry(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_filesystem(const char* rootdir)
|
||||||
|
{
|
||||||
|
unsigned failed = 0;
|
||||||
|
if (rootdir) {
|
||||||
|
if (chroot(rootdir)) {
|
||||||
|
perror("chroot");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; dirs[i]; ++i) {
|
||||||
|
struct stat st;
|
||||||
|
const char* d = dirs[i]+strlen("/usr");
|
||||||
|
if (lstat(d, &st)) {
|
||||||
|
if (errno != ENOENT)
|
||||||
|
perror(d);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
failed += check_directory(dirs[i]);
|
||||||
|
} else if (S_ISLNK(st.st_mode)) {
|
||||||
|
char buf[PATH_MAX] = {0};
|
||||||
|
if(readlink(d, buf, sizeof(buf)) == -1) {
|
||||||
|
perror(d);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(buf, dirs[i]+1)) {
|
||||||
|
fprintf(stderr, "wrong link %s: %s should be %s\n", d, buf, dirs[i]+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (failed) {
|
||||||
|
fprintf(stderr, ngettext("%u file prevents usrmerge\n", "%u files prevent usrmerge\n", failed), failed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return failed == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rpm_findusrfile(rpmts ts, Header hdr, rpmfi orig_fi)
|
||||||
|
{
|
||||||
|
char fn[PATH_MAX] = "/usr";
|
||||||
|
strcpy(fn+strlen(fn), rpmfiFN(orig_fi));
|
||||||
|
|
||||||
|
rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_INSTFILENAMES, fn, 0);
|
||||||
|
if (mi) {
|
||||||
|
Header h;
|
||||||
|
int conflict = 1;
|
||||||
|
while ((h = rpmdbNextIterator(mi)) != NULL) {
|
||||||
|
rpmfiles files = rpmfilesNew(NULL, hdr, 0, 0);
|
||||||
|
rpmfi fi = rpmfilesIter(files, 0);
|
||||||
|
|
||||||
|
int fx = rpmfiFindFN(fi, fn);
|
||||||
|
if (fx != -1) {
|
||||||
|
rpmfiSetFX(fi, fx);
|
||||||
|
if (S_ISDIR(rpmfiFMode(fi)) && S_ISDIR(rpmfiFMode(orig_fi))) {
|
||||||
|
conflict = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rpmfiFree(fi);
|
||||||
|
rpmfilesFree(files);
|
||||||
|
}
|
||||||
|
// we just look at the first one. If there's a
|
||||||
|
// second match and that is somewhow conflicting the
|
||||||
|
// system was screwed already.
|
||||||
|
rpmdbFreeIterator(mi);
|
||||||
|
return conflict;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_rpmdb(char* rootdir)
|
||||||
|
{
|
||||||
|
unsigned failed = 0;
|
||||||
|
|
||||||
|
rpmcliConfigured();
|
||||||
|
|
||||||
|
rpmts ts = rpmtsCreate();
|
||||||
|
if (!ts) {
|
||||||
|
fprintf(stderr, "failed to create RPM transaction\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rootdir)
|
||||||
|
rpmtsSetRootDir(ts, rootdir);
|
||||||
|
|
||||||
|
if (rpmtsOpenDB(ts, O_RDONLY) != 0) {
|
||||||
|
fprintf(stderr, "failed to open RPM database\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpmdbMatchIterator iter = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
|
||||||
|
Header hdr;
|
||||||
|
while ((hdr = rpmdbNextIterator(iter)) != NULL) {
|
||||||
|
rpmfiles files = rpmfilesNew(NULL, hdr, 0, 0);
|
||||||
|
rpmfi fi = rpmfilesIter(files, 0);
|
||||||
|
char skipdir[PATH_MAX] = {0};
|
||||||
|
int conflict = 0;
|
||||||
|
while (rpmfiNext(fi) >= 0) {
|
||||||
|
if (skipdir[0] && startswith(rpmfiFN(fi), skipdir)) {
|
||||||
|
if (verbose > 2)
|
||||||
|
printf("skipping %s as %s is known\n", rpmfiFN(fi), skipdir);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
skipdir[0] = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; rpmdirs[i]; ++i) {
|
||||||
|
if(startswith(rpmfiODN(fi), rpmdirs[i])) {
|
||||||
|
rpm_mode_t m = rpmfiFMode(fi);
|
||||||
|
conflict = rpm_findusrfile(ts, hdr, fi);
|
||||||
|
if (conflict) {
|
||||||
|
if (conflict == 2) {
|
||||||
|
if (verbose > 2) {
|
||||||
|
fprintf(stderr, "directory %s ok\n", rpmfiFN(fi));
|
||||||
|
}
|
||||||
|
conflict = 0;
|
||||||
|
} else if (verbose > 1) {
|
||||||
|
char* n = headerGetAsString(hdr, RPMTAG_NEVRA);
|
||||||
|
fprintf(stderr, "%s: %s conflict\n", n, rpmfiFN(fi));
|
||||||
|
free(n);
|
||||||
|
}
|
||||||
|
} else if (S_ISDIR(m)) {
|
||||||
|
// an optimization so we don't have to check hundreds
|
||||||
|
// of kernel modules. If the file at hand is a directory
|
||||||
|
// and does not exist in /usr we can just skip the rest.
|
||||||
|
strcpy(skipdir, rpmfiFN(fi));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rpmfiFree(fi);
|
||||||
|
rpmfilesFree(files);
|
||||||
|
|
||||||
|
if (conflict) {
|
||||||
|
++failed;
|
||||||
|
if (verbose == 1) {
|
||||||
|
char* n = headerGetAsString(hdr, RPMTAG_NEVRA);
|
||||||
|
printf("%s breaks\n", n);
|
||||||
|
free(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
fprintf(stderr, ngettext("%u package prevents usrmerge\n", "%u packages prevent usrmerge\n", failed), failed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return failed == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
enum { fs, rpmdb } mode = fs;
|
||||||
|
int c;
|
||||||
|
char* rootdir = NULL;
|
||||||
|
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"verbose", no_argument, 0, 'v' },
|
||||||
|
{"rpmdb", no_argument, 0, 128 },
|
||||||
|
{"root", required_argument, 0, 129 },
|
||||||
|
{0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
while ((c = getopt_long(argc, argv, "v", long_options, NULL)) != -1) {
|
||||||
|
switch(c) {
|
||||||
|
case 'v': ++verbose; break;
|
||||||
|
case 128: mode = rpmdb; break;
|
||||||
|
case 129: rootdir=strdup(optarg); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == rpmdb)
|
||||||
|
return check_rpmdb(rootdir) == 0;
|
||||||
|
|
||||||
|
return check_filesystem(rootdir) == 0;
|
||||||
|
}
|
158
usrmergefiles.py
Normal file
158
usrmergefiles.py
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# Copyright (c) 2021 SUSE LLC
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
from itertools import filterfalse, chain, islice
|
||||||
|
from lxml import etree as ET
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
import argparse
|
||||||
|
import gzip
|
||||||
|
import hashlib
|
||||||
|
import io
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def parse_repomd(baseurl, what, code):
|
||||||
|
url = urljoin(baseurl, 'repodata/repomd.xml')
|
||||||
|
repomd = requests.get(url)
|
||||||
|
if repomd.status_code != requests.codes.ok:
|
||||||
|
return False
|
||||||
|
|
||||||
|
ns = {'r': 'http://linux.duke.edu/metadata/repo'}
|
||||||
|
root = ET.fromstring(repomd.content)
|
||||||
|
filelists = root.find('.//r:data[@type="{}"]'.format(what), ns)
|
||||||
|
location = filelists.find('r:location', ns).get('href')
|
||||||
|
sha256_expected = filelists.find('r:checksum[@type="sha256"]', ns).text
|
||||||
|
|
||||||
|
url = urljoin(baseurl, location)
|
||||||
|
with requests.get(url, stream=True) as res:
|
||||||
|
if res.status_code != requests.codes.ok:
|
||||||
|
raise Exception(url + ' does not exist')
|
||||||
|
sha256 = hashlib.sha256(res.content).hexdigest()
|
||||||
|
if sha256 != sha256_expected:
|
||||||
|
raise Exception('checksums do not match {} != {}'.format(sha256, sha256_expected))
|
||||||
|
|
||||||
|
content = gzip.GzipFile(fileobj=io.BytesIO(res.content))
|
||||||
|
|
||||||
|
root = ET.fromstring(content.read())
|
||||||
|
code(root)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def ignored(package):
|
||||||
|
# busybox has stuff in / that is normally not there
|
||||||
|
return package.startswith('busybox-') or package.endswith("-32bit")
|
||||||
|
|
||||||
|
def ddd(a, l):
|
||||||
|
if len(a) < l:
|
||||||
|
return a
|
||||||
|
|
||||||
|
return chain(islice(a, l), ['...'])
|
||||||
|
|
||||||
|
|
||||||
|
def printaslua(files, name):
|
||||||
|
pkgs = dict()
|
||||||
|
for fn in sorted(files.keys()):
|
||||||
|
pkgs.setdefault(' '.join(ddd(sorted(files[fn]), 5)), set()).add(fn)
|
||||||
|
print('{} = {{'.format(name))
|
||||||
|
for p in sorted(pkgs.keys()):
|
||||||
|
print("-- "+p)
|
||||||
|
for fn in sorted(pkgs[p]):
|
||||||
|
print('["{}"] = 1,'.format(fn))
|
||||||
|
|
||||||
|
print('}')
|
||||||
|
|
||||||
|
|
||||||
|
def handle_filelists(root):
|
||||||
|
files = dict()
|
||||||
|
# umr = re.compile(r'^\/(s?bin|lib(?:64)?)/([^/]+)')
|
||||||
|
umr = re.compile(r'^\/(s?bin)/([^/]+)')
|
||||||
|
ns = {'r': 'http://linux.duke.edu/metadata/filelists'}
|
||||||
|
for pn in root.findall(".//r:package", ns):
|
||||||
|
package = pn.get('name')
|
||||||
|
if ignored(package):
|
||||||
|
continue
|
||||||
|
for fn in pn.findall("r:file", ns):
|
||||||
|
m = umr.match(fn.text)
|
||||||
|
if m:
|
||||||
|
# print("{}: {} {}".format(package, m.group(1), m.group(2)))
|
||||||
|
files.setdefault(fn.text, set()).add(package)
|
||||||
|
|
||||||
|
printaslua(files, 'usrmerge_files')
|
||||||
|
|
||||||
|
|
||||||
|
def handle_requires(root):
|
||||||
|
files = dict()
|
||||||
|
umr = re.compile(r'^\/(s?bin)/([^/]+)')
|
||||||
|
ns = {'c': 'http://linux.duke.edu/metadata/common',
|
||||||
|
'r': 'http://linux.duke.edu/metadata/rpm' }
|
||||||
|
for pn in root.findall(".//c:package", ns):
|
||||||
|
package = pn.find('c:name', ns).text
|
||||||
|
if ignored(package):
|
||||||
|
continue
|
||||||
|
for rn in pn.findall(".//r:requires", ns):
|
||||||
|
for fn in rn.findall(".//r:entry", ns):
|
||||||
|
r = fn.get('name')
|
||||||
|
m = umr.match(r)
|
||||||
|
if m:
|
||||||
|
files.setdefault(r,set()).add(package)
|
||||||
|
|
||||||
|
printaslua(files, 'usrmerge_binsbindeps')
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
|
||||||
|
# do some work here
|
||||||
|
logger = logging.getLogger("usrmergefiles")
|
||||||
|
logger.info("main")
|
||||||
|
|
||||||
|
if args.files:
|
||||||
|
parse_repomd(args.url[0], "filelists", handle_filelists)
|
||||||
|
|
||||||
|
if args.requires:
|
||||||
|
parse_repomd(args.url[0], "primary", handle_requires)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(description='boilerplate python commmand line program')
|
||||||
|
parser.add_argument("--dry", action="store_true", help="dry run")
|
||||||
|
parser.add_argument("--debug", action="store_true", help="debug output")
|
||||||
|
parser.add_argument("--verbose", action="store_true", help="verbose")
|
||||||
|
parser.add_argument("--files", action="store_true", help="dump /bin and /sbin files")
|
||||||
|
parser.add_argument("--requires", action="store_true", help="dump requires of /bin and /sbin")
|
||||||
|
parser.add_argument("url", nargs='*', help="some file name")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.debug:
|
||||||
|
level = logging.DEBUG
|
||||||
|
elif args.verbose:
|
||||||
|
level = logging.INFO
|
||||||
|
else:
|
||||||
|
level = None
|
||||||
|
|
||||||
|
logging.basicConfig(level = level)
|
||||||
|
|
||||||
|
sys.exit(main(args))
|
||||||
|
|
||||||
|
# vim: sw=4 et
|
105
xmv.c
Normal file
105
xmv.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2020 SUSE LLC
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#ifndef RENAME_EXCHANGE
|
||||||
|
# define RENAME_EXCHANGE (1 << 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int verbose;
|
||||||
|
|
||||||
|
void help(const char* prog, int ret)
|
||||||
|
{
|
||||||
|
printf("Usage: %s SOURCE TARGET\n", prog);
|
||||||
|
puts("Exchange names of SOURCE and TARGET");
|
||||||
|
exit(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"verbose", no_argument, 0, 'v' },
|
||||||
|
{"help", no_argument, 0, 255 },
|
||||||
|
{0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
while ((c = getopt_long(argc, argv, "v", long_options, NULL)) != -1) {
|
||||||
|
switch(c) {
|
||||||
|
case 'v': ++verbose; break;
|
||||||
|
case 255: help(argv[0], 0); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc-optind < 2)
|
||||||
|
help(argv[0], 1);
|
||||||
|
|
||||||
|
const char *source = argv[optind], *target = argv[optind+1];
|
||||||
|
r = syscall (SYS_renameat2, AT_FDCWD, source, AT_FDCWD, target, RENAME_EXCHANGE);
|
||||||
|
if (r < 0) {
|
||||||
|
// FS not supporting RENAME_EXCHANGE -> EINVAL
|
||||||
|
// No renameat2 syscall -> ENOSYS (eg WSL)
|
||||||
|
if (errno != EINVAL && errno != ENOSYS) {
|
||||||
|
perror("renameat2");
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user