489 lines
21 KiB
Bash
Executable File
489 lines
21 KiB
Bash
Executable File
#!/bin/sh
|
|
set -e
|
|
|
|
type=$1
|
|
preversion=$2
|
|
|
|
kernel_compare_versions () {
|
|
verA=$(($(echo "$1" | sed 's/\([0-9]*\)\.\([0-9]*\).*/\1 \* 100 + \2/')))
|
|
verB=$(($(echo "$3" | sed 's/\([0-9]*\)\.\([0-9]*\).*/\1 \* 100 + \2/')))
|
|
|
|
test $verA -$2 $verB
|
|
}
|
|
|
|
if [ "$type" != abort-upgrade ]
|
|
then
|
|
# Load debconf module if available and usable
|
|
if [ -f /usr/share/debconf/confmodule ] && \
|
|
( [ "$DEBCONF_USE_CDEBCONF" ] || perl -e "" 2>/dev/null ) ; then
|
|
. /usr/share/debconf/confmodule
|
|
USE_DEBCONF=1
|
|
else
|
|
USE_DEBCONF=
|
|
fi
|
|
|
|
# Only change LC_ALL after loading debconf to ensure the debconf templates
|
|
# are properly localized.
|
|
export LC_ALL=C
|
|
|
|
# See if LD_LIBRARY_PATH contains the traditional /lib, but not the
|
|
# multiarch path
|
|
dirs=$(echo $LD_LIBRARY_PATH | sed 's/:/ /g')
|
|
for dir in $dirs ; do
|
|
dir=$(readlink -e $dir || true)
|
|
case "$dir" in
|
|
/lib)
|
|
seen_traditional=1
|
|
;;
|
|
/lib/x86_64-linux-gnu)
|
|
seen_multiarch=1
|
|
;;
|
|
esac
|
|
done
|
|
if test -n "$seen_traditional" && test -z "$seen_multiarch" ; then
|
|
echo
|
|
echo "LD_LIBRARY_PATH contains the traditional /lib directory,"
|
|
echo "but not the multiarch directory /lib/x86_64-linux-gnu."
|
|
echo "It is not safe to upgrade the C library in this situation;"
|
|
echo "please remove the /lib/directory from LD_LIBRARY_PATH and"
|
|
echo "try again."
|
|
echo
|
|
exit 1
|
|
fi
|
|
|
|
# glibc kernel version check
|
|
system=`uname -s`
|
|
if [ "$system" = "Linux" ]
|
|
then
|
|
# sanity checking for the appropriate kernel on each architecture.
|
|
kernel_ver=`uname -r`
|
|
case ${DPKG_MAINTSCRIPT_ARCH} in
|
|
*)
|
|
# The GNU libc requires a >= 3.2 kernel, found in wheezy
|
|
kernel_ver_min=3.2
|
|
kernel_ver_rec=3.2
|
|
;;
|
|
esac
|
|
|
|
if kernel_compare_versions "$kernel_ver" lt $kernel_ver_min
|
|
then
|
|
if [ "$USE_DEBCONF" ]
|
|
then
|
|
db_version 2.0
|
|
db_fset glibc/kernel-too-old seen false
|
|
db_reset glibc/kernel-too-old
|
|
db_subst glibc/kernel-too-old kernel_ver $kernel_ver_rec
|
|
db_input critical glibc/kernel-too-old || true
|
|
db_go
|
|
db_stop
|
|
else
|
|
echo "ERROR: This version of the GNU libc requires kernel version"
|
|
echo "$kernel_ver_rec or later. Please upgrade your kernel and reboot before installing"
|
|
echo 'glibc. You may need to use "apt -f install" after reboot to solve dependencies.'
|
|
echo
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
if kernel_compare_versions "$kernel_ver" lt $kernel_ver_rec
|
|
then
|
|
if [ "$USE_DEBCONF" ]
|
|
then
|
|
db_version 2.0
|
|
db_fset glibc/kernel-not-supported seen false
|
|
db_reset glibc/kernel-not-supported
|
|
db_subst glibc/kernel-not-supported kernel_ver $kernel_ver_rec
|
|
db_input critical glibc/kernel-not-supported || true
|
|
db_go
|
|
db_stop
|
|
else
|
|
echo "WARNING: This version of the GNU libc requires kernel version"
|
|
echo "$kernel_ver_rec or later. Older versions might work but are not officially"
|
|
echo "supported. Please consider upgrading your kernel."
|
|
echo
|
|
fi
|
|
fi
|
|
|
|
elif [ $system = "GNU/kFreeBSD" ]
|
|
then
|
|
kernel_ver=`uname -r`
|
|
kernel_ver_min=8.3
|
|
if kernel_compare_versions "$kernel_ver" lt $kernel_ver_min
|
|
then
|
|
if [ "$USE_DEBCONF" ]
|
|
then
|
|
db_version 2.0
|
|
db_version 2.0
|
|
db_fset glibc/kernel-too-old seen false
|
|
db_reset glibc/kernel-too-old
|
|
db_subst glibc/kernel-too-old kernel_ver $kernel_ver_min
|
|
db_input critical glibc/kernel-too-old || true
|
|
db_go
|
|
db_stop
|
|
else
|
|
echo "ERROR: This version of the GNU libc requires kernel version"
|
|
echo "$kernel_ver_min or later. Please upgrade your kernel and reboot before installing"
|
|
echo 'glibc. You may need to use "apt -f install" after reboot to solve dependencies.'
|
|
echo
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
elif [ $system = "GNU" ]
|
|
then
|
|
kernel_ver=`uname -v | cut -d / -f 1 | cut -d ' ' -f 2`
|
|
kernel_ver_git=${kernel_ver#*+git}
|
|
kernel_ver_git=${kernel_ver_git%%-*}
|
|
kernel_ver=${kernel_ver%+git*}
|
|
kernel_ver_min=1.8
|
|
kernel_ver_git_min=20210923
|
|
if kernel_compare_versions "$kernel_ver" lt $kernel_ver_min || \
|
|
( kernel_compare_versions "$kernel_ver" eq $kernel_ver_min && \
|
|
[ "$kernel_ver_git" -lt $kernel_ver_git_min ] )
|
|
then
|
|
if [ "$USE_DEBCONF" ]
|
|
then
|
|
db_version 2.0
|
|
db_fset glibc/kernel-too-old seen false
|
|
db_reset glibc/kernel-too-old
|
|
db_subst glibc/kernel-too-old kernel_ver $kernel_ver_min+git$kernel_ver_git_min
|
|
db_input critical glibc/kernel-too-old || true
|
|
db_go
|
|
db_stop
|
|
else
|
|
echo "ERROR: This version of the GNU libc requires kernel version"
|
|
echo "$kernel_ver_min+git$kernel_ver_git_min or later."
|
|
echo "Please upgrade your kernel and reboot before installing glibc."
|
|
echo 'You may need to use "apt -f install" after reboot to solve dependencies.'
|
|
echo
|
|
fi
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "$type" = upgrade ]
|
|
then
|
|
if [ -n "$preversion" ] && [ -x "$(command -v ischroot)" ] && ! ischroot; then
|
|
# NSS authentication trouble guard
|
|
if dpkg --compare-versions "$preversion" lt 2.39; then
|
|
if grep -E -q '(^|/)(xscreensaver|xlockmore)' /proc/*/cmdline 2>/dev/null; then
|
|
if [ "$USE_DEBCONF" ] ; then
|
|
db_version 2.0
|
|
db_reset glibc/disable-screensaver
|
|
db_input critical glibc/disable-screensaver || true
|
|
db_go || true
|
|
else
|
|
echo "xscreensaver and xlockmore must be restarted before upgrading"
|
|
echo
|
|
echo "One or more running instances of xscreensaver or xlockmore have been"
|
|
echo "detected on this system. Because of incompatible library changes, the"
|
|
echo "upgrade of the GNU C library will leave you unable to authenticate to"
|
|
echo "these programs. You should arrange for these programs to be restarted"
|
|
echo "or stopped before continuing this upgrade, to avoid locking your users"
|
|
echo "out of their current sessions."
|
|
echo
|
|
frontend=`echo "$DEBIAN_FRONTEND" | tr '[:upper:]' '[:lower:]'`
|
|
if [ "$frontend" = noninteractive ]; then
|
|
echo "Non-interactive mode, upgrade glibc forcibly"
|
|
else
|
|
echo -n "Press a key to continue"
|
|
read answer
|
|
fi
|
|
echo
|
|
fi
|
|
fi
|
|
|
|
check="kdm postgresql xdm"
|
|
# NSS services check:
|
|
echo -n "Checking for services that may need to be restarted..."
|
|
# Only get the ones that are installed, of the same architecture
|
|
# as libc (or arch all) and configured. Restart openssh-server even
|
|
# if only half-configured to continue accepting new connections
|
|
# during the upgrade.
|
|
[ -n "$check" ] && check=$(dpkg-query -W -f='${binary:Package} ${Status} ${Architecture}\n' $check 2> /dev/null | \
|
|
grep -E "(^openssh-server .* unpacked|installed) (all|${DPKG_MAINTSCRIPT_ARCH})$" | sed 's/[: ].*//')
|
|
# some init scripts don't match the package names
|
|
check=$(echo $check | \
|
|
sed -e's/\bat\b/atd/g' \
|
|
-e's/\bdovecot-common\b/dovecot/g' \
|
|
-e's/\bexim4-base\b/exim4/g' \
|
|
-e's/\blpr\b/lpd/g' \
|
|
-e's/\blpr-ppd\b/lpd-ppd/g' \
|
|
-e's/\bmysql-server\b/mysql/g' \
|
|
-e's/\bopenssh-server\b/ssh/g' \
|
|
-e's/\bsasl2-bin\b/saslauthd/g' \
|
|
-e's/\bsamba\b/smbd/g' \
|
|
-e's/\bpostgresql-common\b/postgresql/g' \
|
|
)
|
|
echo
|
|
echo "Checking init scripts..."
|
|
for service in $check; do
|
|
invoke-rc.d ${service} status >/dev/null 2>/dev/null && status=0 || status=$?
|
|
if [ "$status" = "0" ] || [ "$status" = "2" ] ; then
|
|
services="$service $services"
|
|
elif [ "$status" = "100" ] ; then
|
|
echo "WARNING: init script for $service not found."
|
|
fi
|
|
done
|
|
|
|
if [ -n "$services" ]; then
|
|
if [ "$USE_DEBCONF" ] ; then
|
|
db_version 2.0
|
|
db_reset glibc/upgrade
|
|
db_subst glibc/upgrade services $services
|
|
if [ "$RELEASE_UPGRADE_MODE" = desktop ]; then
|
|
db_input medium glibc/upgrade || true
|
|
else
|
|
db_input critical glibc/upgrade || true
|
|
fi
|
|
db_go || true
|
|
db_get glibc/upgrade
|
|
answer=$RET
|
|
else
|
|
echo "Do you want to upgrade glibc now?"
|
|
echo
|
|
echo "Running services and programs that are using NSS need to be restarted,"
|
|
echo "otherwise they might not be able to do lookup or authentication any more."
|
|
echo "The installation process is able to restart some services (such as ssh or"
|
|
echo "telnetd), but other programs cannot be restarted automatically. One such"
|
|
echo "program that needs manual stopping and restart after the glibc upgrade by"
|
|
echo "yourself is xdm - because automatic restart might disconnect your active"
|
|
echo "X11 sessions."
|
|
echo
|
|
echo "This script detected the following installed services which must be"
|
|
echo "stopped before the upgrade: $services"
|
|
echo
|
|
echo "If you want to interrupt the upgrade now and continue later, please"
|
|
echo "answer No to the question below."
|
|
echo
|
|
frontend=`echo "$DEBIAN_FRONTEND" | tr '[:upper:]' '[:lower:]'`
|
|
if [ "$frontend" = noninteractive ]; then
|
|
echo "Non-interactive mode, upgrade glibc forcibly"
|
|
answer=true
|
|
else
|
|
echo -n "Do you want to upgrade glibc now? [Y/n] "
|
|
read answer
|
|
case $answer in
|
|
Y*|y*) answer=true ;;
|
|
N*|n*) answer=false ;;
|
|
*) answer=true ;;
|
|
esac
|
|
fi
|
|
echo
|
|
fi
|
|
|
|
if [ "x$answer" != "xtrue" ]; then
|
|
echo "Stopped glibc upgrade. Please retry the upgrade after you have"
|
|
echo "checked or stopped services by hand."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# As long systemd-logind has not seen any login request since the system has been
|
|
# booted, it has not loaded any NSS module. In that condition if glibc is upgraded
|
|
# (that means with a non session shell or by some automation), the NSS modules are
|
|
# replaced by a new major version which might be incompatible (and definitely are
|
|
# for some versions).
|
|
#
|
|
# The solution implemented for most daemons is to restart them, but unfortunately
|
|
# it is not something supported with systemd-logind (see bug#91950).
|
|
#
|
|
# As a workaround, when detected that the system is using systemd and that the
|
|
# systemd-logind process has not not loaded any NSS module, force systemd-logind to
|
|
# load NSS modules. This is done by disabling lingering on a non-existing user. This
|
|
# has to be done by talking directly to systemd-logind through sd-bus, as loginctl
|
|
# first checks if the user actually exist. The nonexistent uid is chosen as
|
|
# 4294967294, which is reserved by Policy §9.2.2.
|
|
#
|
|
# Note that starting with glibc 2.34, the nss_files is builtin. When glibc >= 2.34
|
|
# ends-up in a stable release, this workaround can therefore be dropped.
|
|
if dpkg --compare-versions "$preversion" lt 2.34 && [ -d /run/systemd/system ]; then
|
|
if ! grep -q -E 'libnss_(compat|db|files)' /proc/$(systemctl show --property MainPID --value systemd-logind.service)/maps >/dev/null 2>&1; then
|
|
echo "Forcing systemd-logind to load NSS modules..."
|
|
busctl call --system org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager \
|
|
SetUserLinger ubb 4294967294 false false >/dev/null 2>&1 || true
|
|
fi
|
|
fi
|
|
|
|
services=""
|
|
check="apache2 apache apache-ssl apache-perl autofs at"
|
|
check="$check boa cucipop courier-authdaemon cron cups exim"
|
|
check="$check exim4-base dovecot-common cucipop incron lprng lpr"
|
|
check="$check lpr-ppd mysql-server nis openbsd-inetd"
|
|
check="$check openldapd postgresql-common proftpd postfix postfix-tls"
|
|
check="$check rsync samba sasl2-bin slapd smail sendmail snmpd ssh"
|
|
check="$check spamassassin vsftpd wu-ftpd wu-ftpd-academ wwwoffle"
|
|
check="$check webmin dropbear gdm gdm3"
|
|
# the following substitution processes the check variable
|
|
# and returns results in the services variable
|
|
# NSS services check:
|
|
echo -n "Checking for services that may need to be restarted..."
|
|
# Only get the ones that are installed, of the same architecture
|
|
# as libc (or arch all) and configured. Restart openssh-server even
|
|
# if only half-configured to continue accepting new connections
|
|
# during the upgrade.
|
|
[ -n "$check" ] && check=$(dpkg-query -W -f='${binary:Package} ${Status} ${Architecture}\n' $check 2> /dev/null | \
|
|
grep -E "(^openssh-server .* unpacked|installed) (all|${DPKG_MAINTSCRIPT_ARCH})$" | sed 's/[: ].*//')
|
|
# some init scripts don't match the package names
|
|
check=$(echo $check | \
|
|
sed -e's/\bat\b/atd/g' \
|
|
-e's/\bdovecot-common\b/dovecot/g' \
|
|
-e's/\bexim4-base\b/exim4/g' \
|
|
-e's/\blpr\b/lpd/g' \
|
|
-e's/\blpr-ppd\b/lpd-ppd/g' \
|
|
-e's/\bmysql-server\b/mysql/g' \
|
|
-e's/\bopenssh-server\b/ssh/g' \
|
|
-e's/\bsasl2-bin\b/saslauthd/g' \
|
|
-e's/\bsamba\b/smbd/g' \
|
|
-e's/\bpostgresql-common\b/postgresql/g' \
|
|
)
|
|
echo
|
|
echo "Checking init scripts..."
|
|
for service in $check; do
|
|
invoke-rc.d ${service} status >/dev/null 2>/dev/null && status=0 || status=$?
|
|
if [ "$status" = "0" ] || [ "$status" = "2" ] ; then
|
|
services="$service $services"
|
|
elif [ "$status" = "100" ] ; then
|
|
echo "WARNING: init script for $service not found."
|
|
fi
|
|
done
|
|
|
|
if [ -n "$services" ] && [ ! -x /usr/lib/needrestart/apt-pinvoke ]; then
|
|
if [ "$USE_DEBCONF" ] ; then
|
|
db_version 2.0
|
|
if [ "$RELEASE_UPGRADE_MODE" = desktop ]; then
|
|
db_input medium libraries/restart-without-asking || true
|
|
else
|
|
db_input critical libraries/restart-without-asking || true
|
|
fi
|
|
db_go || true
|
|
|
|
db_get libraries/restart-without-asking
|
|
if [ "$RET" != true ]; then
|
|
db_reset glibc/restart-services
|
|
db_set glibc/restart-services "$services"
|
|
if [ "$RELEASE_UPGRADE_MODE" = desktop ]; then
|
|
db_input medium glibc/restart-services || true
|
|
else
|
|
db_input critical glibc/restart-services || true
|
|
fi
|
|
db_go || true
|
|
db_get glibc/restart-services
|
|
services="$RET"
|
|
fi
|
|
else
|
|
echo
|
|
echo "Name Service Switch update in the C Library: post-installation question."
|
|
echo
|
|
echo "Running services and programs that are using NSS need to be restarted,"
|
|
echo "otherwise they might not be able to do lookup or authentication any more"
|
|
echo "(for services such as ssh, this can affect your ability to login)."
|
|
echo "Note: restarting sshd/telnetd should not affect any existing connections."
|
|
echo
|
|
echo "The services detected are: "
|
|
echo " $services"
|
|
echo
|
|
echo "If other services have begun to fail mysteriously after this upgrade, it is"
|
|
echo "probably necessary to restart them too. We recommend that you reboot your"
|
|
echo "machine after the upgrade to avoid NSS-related troubles."
|
|
echo
|
|
frontend=`echo "$DEBIAN_FRONTEND" | tr '[:upper:]' '[:lower:]'`
|
|
if [ "$frontend" = noninteractive ]; then
|
|
echo "Non-interactive mode, restarting services"
|
|
answer=yes
|
|
else
|
|
echo -n "Do you wish to restart services? [Y/n] "
|
|
read answer
|
|
case $answer in
|
|
N*|n*) services="" ;;
|
|
*) ;;
|
|
esac
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$services" ]; then
|
|
echo "Stopping some services possibly affected by the upgrade (will be restarted later):"
|
|
for service in $services; do
|
|
case "$service" in
|
|
cron)
|
|
# See bug (LP: #508083)
|
|
echo -n " $service: stopping..."
|
|
if invoke-rc.d ${service} stop > /dev/null 2>&1; then
|
|
echo "done."
|
|
echo "$service" >> /var/run/services.need_start
|
|
else
|
|
echo "FAILED! ($?)"
|
|
echo "$service" >> /var/run/services.need_restart
|
|
fi
|
|
;;
|
|
|
|
*)
|
|
# log service details to allow postinst to handle the
|
|
# restart.
|
|
echo "$service" >> /var/run/services.need_restart
|
|
;;
|
|
esac
|
|
done
|
|
|
|
fi
|
|
echo
|
|
else
|
|
echo "Nothing to restart."
|
|
fi
|
|
fi # end upgrading and $preversion lt Glibc6_VERSION
|
|
fi # Upgrading
|
|
fi
|
|
|
|
# We create the top-level lib symlink on merged-usr systems, so that we can
|
|
# cover cases where for example libc6:amd64 on i386 is installed and then removed
|
|
# (which deletes the symlink too). Note that we only suppor the simplest case,
|
|
# no conversion (moving files) is done here, as that's the job of the usrmerge
|
|
# package. See: https://bugs.debian.org/926699
|
|
# Once all packages install only under /usr, this can be removed, as removing
|
|
# this package will no longer result in the symlink being deleted.
|
|
if [ "$1" = "install" ] || [ "$1" = "upgrade" ]; then
|
|
if [ -L "$DPKG_ROOT/lib" ]; then
|
|
# Has the link already been created?
|
|
# If it has not, is a directory already there? Half-merged systems are
|
|
# the problem of usrmerge, simply ignore them here.
|
|
if [ ! -L "${DPKG_ROOT}/lib64" ] && [ ! -d "${DPKG_ROOT}/lib64" ]; then
|
|
mkdir -p "$DPKG_ROOT/usr/lib64"
|
|
ln -s usr/lib64 "${DPKG_ROOT}/lib64"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# begin-remove-after: released:forky
|
|
# Add DEP17 M4 protective diversions. These should be added by base-files, but
|
|
# we want to avoid Pre-Depends: base-files (>= trixie) and therefore add them
|
|
# for base-files. As bookworm's base-files installs bin lib and sbin, the only
|
|
# directory we may miss is the one containing the runtime linker when it is not
|
|
# /lib.
|
|
if [ "$1" = install -o "$1" = upgrade ] && [ "/lib64" != "/lib" ]; then
|
|
dpkg-divert --quiet --add --no-rename --package base-files --divert "/lib64.usr-is-merged" "/lib64"
|
|
fi
|
|
# end-remove-after
|
|
|
|
# Add DEP17 M8 protective diversions for the runtime dynamic linker. It is
|
|
# installed in both libc (multiarch) and libc-alt (multilib) amounting to a
|
|
# move and thus DEP17 P1 problem. This diversion should be removed by forky's
|
|
# libc.postinst.
|
|
if [ "$1" = install ] || [ "$1" = upgrade ]; then
|
|
dpkg-divert --quiet --add --no-rename --divert "/lib64/ld-linux-x86-64.so.2.usr-is-merged" "/lib64/ld-linux-x86-64.so.2"
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$preversion" ]; then
|
|
if dpkg --compare-versions "$preversion" lt 2.39; then
|
|
# unconditionally wipe ld.so.cache on major version upgrades; this
|
|
# makes those upgrades a bit slower, but is less error-prone than
|
|
# hoping we notice every time the cache format is changed upstream
|
|
rm -f "$DPKG_ROOT/etc/ld.so.cache"
|
|
rm -f "$DPKG_ROOT/var/cache/ldconfig/aux-cache"
|
|
fi
|
|
fi
|
|
|
|
exit 0
|