initial commit
[glibc.git] / debian / debhelper.in / libc.preinst
1 #!/bin/sh
2 set -e
3
4 type=$1
5 preversion=$2
6
7 kernel_compare_versions () {
8 verA=$(($(echo "$1" | sed 's/\([0-9]*\)\.\([0-9]*\).*/\1 \* 100 + \2/')))
9 verB=$(($(echo "$3" | sed 's/\([0-9]*\)\.\([0-9]*\).*/\1 \* 100 + \2/')))
10
11 test $verA -$2 $verB
12 }
13
14 if [ "$type" != abort-upgrade ]
15 then
16 # Load debconf module if available and usable
17 if [ -f /usr/share/debconf/confmodule ] && \
18 ( [ "$DEBCONF_USE_CDEBCONF" ] || perl -e "" 2>/dev/null ) ; then
19 . /usr/share/debconf/confmodule
20 USE_DEBCONF=1
21 else
22 USE_DEBCONF=
23 fi
24
25 # Only change LC_ALL after loading debconf to ensure the debconf templates
26 # are properly localized.
27 export LC_ALL=C
28
29 # See if LD_LIBRARY_PATH contains the traditional /lib, but not the
30 # multiarch path
31 dirs=$(echo $LD_LIBRARY_PATH | sed 's/:/ /g')
32 for dir in $dirs ; do
33 dir=$(readlink -e $dir || true)
34 case "$dir" in
35 /lib)
36 seen_traditional=1
37 ;;
38 SLIBDIR)
39 seen_multiarch=1
40 ;;
41 esac
42 done
43 if test -n "$seen_traditional" && test -z "$seen_multiarch" ; then
44 echo
45 echo "LD_LIBRARY_PATH contains the traditional /lib directory,"
46 echo "but not the multiarch directory SLIBDIR."
47 echo "It is not safe to upgrade the C library in this situation;"
48 echo "please remove the /lib/directory from LD_LIBRARY_PATH and"
49 echo "try again."
50 echo
51 exit 1
52 fi
53
54 # glibc kernel version check
55 system=`uname -s`
56 if [ "$system" = "Linux" ]
57 then
58 # sanity checking for the appropriate kernel on each architecture.
59 kernel_ver=`uname -r`
60 case ${DPKG_MAINTSCRIPT_ARCH} in
61 *)
62 # The GNU libc requires a >= 3.2 kernel, found in wheezy
63 kernel_ver_min=3.2
64 kernel_ver_rec=3.2
65 ;;
66 esac
67
68 if kernel_compare_versions "$kernel_ver" lt $kernel_ver_min
69 then
70 if [ "$USE_DEBCONF" ]
71 then
72 db_version 2.0
73 db_fset glibc/kernel-too-old seen false
74 db_reset glibc/kernel-too-old
75 db_subst glibc/kernel-too-old kernel_ver $kernel_ver_rec
76 db_input critical glibc/kernel-too-old || true
77 db_go
78 db_stop
79 else
80 echo "ERROR: This version of the GNU libc requires kernel version"
81 echo "$kernel_ver_rec or later. Please upgrade your kernel and reboot before installing"
82 echo 'glibc. You may need to use "apt -f install" after reboot to solve dependencies.'
83 echo
84 fi
85 exit 1
86 fi
87
88 if kernel_compare_versions "$kernel_ver" lt $kernel_ver_rec
89 then
90 if [ "$USE_DEBCONF" ]
91 then
92 db_version 2.0
93 db_fset glibc/kernel-not-supported seen false
94 db_reset glibc/kernel-not-supported
95 db_subst glibc/kernel-not-supported kernel_ver $kernel_ver_rec
96 db_input critical glibc/kernel-not-supported || true
97 db_go
98 db_stop
99 else
100 echo "WARNING: This version of the GNU libc requires kernel version"
101 echo "$kernel_ver_rec or later. Older versions might work but are not officially"
102 echo "supported. Please consider upgrading your kernel."
103 echo
104 fi
105 fi
106
107 elif [ $system = "GNU/kFreeBSD" ]
108 then
109 kernel_ver=`uname -r`
110 kernel_ver_min=8.3
111 if kernel_compare_versions "$kernel_ver" lt $kernel_ver_min
112 then
113 if [ "$USE_DEBCONF" ]
114 then
115 db_version 2.0
116 db_version 2.0
117 db_fset glibc/kernel-too-old seen false
118 db_reset glibc/kernel-too-old
119 db_subst glibc/kernel-too-old kernel_ver $kernel_ver_min
120 db_input critical glibc/kernel-too-old || true
121 db_go
122 db_stop
123 else
124 echo "ERROR: This version of the GNU libc requires kernel version"
125 echo "$kernel_ver_min or later. Please upgrade your kernel and reboot before installing"
126 echo 'glibc. You may need to use "apt -f install" after reboot to solve dependencies.'
127 echo
128 fi
129 exit 1
130 fi
131
132 elif [ $system = "GNU" ]
133 then
134 kernel_ver=`uname -v | cut -d / -f 1 | cut -d ' ' -f 2`
135 kernel_ver_git=${kernel_ver#*+git}
136 kernel_ver_git=${kernel_ver_git%%-*}
137 kernel_ver=${kernel_ver%+git*}
138 kernel_ver_min=1.8
139 kernel_ver_git_min=20210923
140 if kernel_compare_versions "$kernel_ver" lt $kernel_ver_min || \
141 ( kernel_compare_versions "$kernel_ver" eq $kernel_ver_min && \
142 [ "$kernel_ver_git" -lt $kernel_ver_git_min ] )
143 then
144 if [ "$USE_DEBCONF" ]
145 then
146 db_version 2.0
147 db_fset glibc/kernel-too-old seen false
148 db_reset glibc/kernel-too-old
149 db_subst glibc/kernel-too-old kernel_ver $kernel_ver_min+git$kernel_ver_git_min
150 db_input critical glibc/kernel-too-old || true
151 db_go
152 db_stop
153 else
154 echo "ERROR: This version of the GNU libc requires kernel version"
155 echo "$kernel_ver_min+git$kernel_ver_git_min or later."
156 echo "Please upgrade your kernel and reboot before installing glibc."
157 echo 'You may need to use "apt -f install" after reboot to solve dependencies.'
158 echo
159 fi
160 exit 1
161 fi
162 fi
163 fi
164
165 if [ "$type" = upgrade ]
166 then
167 if [ -n "$preversion" ] && [ -x "$(command -v ischroot)" ] && ! ischroot; then
168 # NSS authentication trouble guard
169 if dpkg --compare-versions "$preversion" lt DEB_VERSION_UPSTREAM; then
170 if grep -E -q '(^|/)(xscreensaver|xlockmore)' /proc/*/cmdline 2>/dev/null; then
171 if [ "$USE_DEBCONF" ] ; then
172 db_version 2.0
173 db_reset glibc/disable-screensaver
174 db_input critical glibc/disable-screensaver || true
175 db_go || true
176 else
177 echo "xscreensaver and xlockmore must be restarted before upgrading"
178 echo
179 echo "One or more running instances of xscreensaver or xlockmore have been"
180 echo "detected on this system. Because of incompatible library changes, the"
181 echo "upgrade of the GNU C library will leave you unable to authenticate to"
182 echo "these programs. You should arrange for these programs to be restarted"
183 echo "or stopped before continuing this upgrade, to avoid locking your users"
184 echo "out of their current sessions."
185 echo
186 frontend=`echo "$DEBIAN_FRONTEND" | tr '[:upper:]' '[:lower:]'`
187 if [ "$frontend" = noninteractive ]; then
188 echo "Non-interactive mode, upgrade glibc forcibly"
189 else
190 echo -n "Press a key to continue"
191 read answer
192 fi
193 echo
194 fi
195 fi
196
197 check="kdm postgresql xdm"
198 # NSS services check:
199 __NSS_CHECK__
200 if [ -n "$services" ]; then
201 if [ "$USE_DEBCONF" ] ; then
202 db_version 2.0
203 db_reset glibc/upgrade
204 db_subst glibc/upgrade services $services
205 db_input critical glibc/upgrade || true
206 db_go || true
207 db_get glibc/upgrade
208 answer=$RET
209 else
210 echo "Do you want to upgrade glibc now?"
211 echo
212 echo "Running services and programs that are using NSS need to be restarted,"
213 echo "otherwise they might not be able to do lookup or authentication any more."
214 echo "The installation process is able to restart some services (such as ssh or"
215 echo "telnetd), but other programs cannot be restarted automatically. One such"
216 echo "program that needs manual stopping and restart after the glibc upgrade by"
217 echo "yourself is xdm - because automatic restart might disconnect your active"
218 echo "X11 sessions."
219 echo
220 echo "This script detected the following installed services which must be"
221 echo "stopped before the upgrade: $services"
222 echo
223 echo "If you want to interrupt the upgrade now and continue later, please"
224 echo "answer No to the question below."
225 echo
226 frontend=`echo "$DEBIAN_FRONTEND" | tr '[:upper:]' '[:lower:]'`
227 if [ "$frontend" = noninteractive ]; then
228 echo "Non-interactive mode, upgrade glibc forcibly"
229 answer=true
230 else
231 echo -n "Do you want to upgrade glibc now? [Y/n] "
232 read answer
233 case $answer in
234 Y*|y*) answer=true ;;
235 N*|n*) answer=false ;;
236 *) answer=true ;;
237 esac
238 fi
239 echo
240 fi
241
242 if [ "x$answer" != "xtrue" ]; then
243 echo "Stopped glibc upgrade. Please retry the upgrade after you have"
244 echo "checked or stopped services by hand."
245 exit 1
246 fi
247 fi
248
249 # As long systemd-logind has not seen any login request since the system has been
250 # booted, it has not loaded any NSS module. In that condition if glibc is upgraded
251 # (that means with a non session shell or by some automation), the NSS modules are
252 # replaced by a new major version which might be incompatible (and definitely are
253 # for some versions).
254 #
255 # The solution implemented for most daemons is to restart them, but unfortunately
256 # it is not something supported with systemd-logind (see bug#91950).
257 #
258 # As a workaround, when detected that the system is using systemd and that the
259 # systemd-logind process has not not loaded any NSS module, force systemd-logind to
260 # load NSS modules. This is done by disabling lingering on a non-existing user. This
261 # has to be done by talking directly to systemd-logind through sd-bus, as loginctl
262 # first checks if the user actually exist. The nonexistent uid is chosen as
263 # 4294967294, which is reserved by Policy ยง9.2.2.
264 #
265 # Note that starting with glibc 2.34, the nss_files is builtin. When glibc >= 2.34
266 # ends-up in a stable release, this workaround can therefore be dropped.
267 if dpkg --compare-versions "$preversion" lt 2.34 && [ -d /run/systemd/system ]; then
268 if ! grep -q -E 'libnss_(compat|db|files)' /proc/$(systemctl show --property MainPID --value systemd-logind.service)/maps >/dev/null 2>&1; then
269 echo "Forcing systemd-logind to load NSS modules..."
270 busctl call --system org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager \
271 SetUserLinger ubb 4294967294 false false >/dev/null 2>&1 || true
272 fi
273 fi
274
275 fi # end upgrading and $preversion lt DEB_VERSION_UPSTREAM
276 fi # Upgrading
277
278 # This will keep us from using hwcap libs (optimized) during an
279 # upgrade.
280 touch "$DPKG_ROOT/etc/ld.so.nohwcap"
281 fi
282
283 # We create the top-level lib symlink on merged-usr systems, so that we can
284 # cover cases where for example libc6:amd64 on i386 is installed and then removed
285 # (which deletes the symlink too). Note that we only suppor the simplest case,
286 # no conversion (moving files) is done here, as that's the job of the usrmerge
287 # package. See: https://bugs.debian.org/926699
288 # Once all packages install only under /usr, this can be removed, as removing
289 # this package will no longer result in the symlink being deleted.
290 if [ "$1" = "install" ] || [ "$1" = "upgrade" ]; then
291 if [ -L "$DPKG_ROOT/lib" ]; then
292 # Has the link already been created?
293 # If it has not, is a directory already there? Half-merged systems are
294 # the problem of usrmerge, simply ignore them here.
295 if [ ! -L "${DPKG_ROOT}RTLDDIR" ] && [ ! -d "${DPKG_ROOT}RTLDDIR" ]; then
296 mkdir -p "$DPKG_ROOT/usrRTLDDIR"
297 ln -s usrRTLDDIR "${DPKG_ROOT}RTLDDIR"
298 fi
299 fi
300 fi
301
302 #DEBHELPER#
303
304 if [ -n "$preversion" ]; then
305 if dpkg --compare-versions "$preversion" lt DEB_VERSION_UPSTREAM; then
306 # unconditionally wipe ld.so.cache on major version upgrades; this
307 # makes those upgrades a bit slower, but is less error-prone than
308 # hoping we notice every time the cache format is changed upstream
309 rm -f "$DPKG_ROOT/etc/ld.so.cache"
310 rm -f "$DPKG_ROOT/var/cache/ldconfig/aux-cache"
311 fi
312 fi
313
314 exit 0