[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#632682: base-files: please provide a /lib64 -> /lib symlink on 64-bit systems



On 2011-08-10 22:03 +0200, Aurelien Jarno wrote:

> On Wed, Aug 10, 2011 at 08:35:39PM +0200, Sven Joachim wrote:
>> 
>> I'll have a look at it in the next few days if nobody beats me to it.
>> Just to confirm that my ideas were the same as yours, AFAICS the
>> following needs to be done in the preinst (on amd64), if /lib64 is a
>> symlink:
>> 
>> 1) remove /lib64
>> 2) create /lib64 directory
>> 3) symlink $(readlink -e /lib/ld-linux-x86-64.so.2) to /lib64/ld-linux-x86-64.so.2
>> 
>> 2) and 3) are a bit difficult after the path to the ELF interpreter has
>> just disappeared.  I guess you still want to stick to shell nonetheless
>> (as opposed to doing these steps in perl, say) ?
>> 
>
> This is basically what we have in mind, though it has not been tested.
> For step 2 and 3, you can call the ELF interpreter directly, that is 
> "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 mkdir /lib64".

Almost right, you have use /bin/mkdir though since the interpreter knows
nothing about PATH:

,----
| # /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 mkdir /lib64
| mkdir: error while loading shared libraries: mkdir: cannot open shared object file
`----

> The whole operation is still not atomic, but so far it's the best way to
> do it. We might want to insert a call to sync as steps 0 and 4, to
> minimize the possible time with ELF interpreter, and to make sure the
> data is written to the disk as soon as possible (otherwise if the
> machine crashes, the system can't boot).

After getting the necessary minimal grasp of the packaging system, I
have come up with a first shot towards a solution, see the attached
patch set.

Upgrade from and downgrade to 2.13-16 has been tested in a minimal amd64
sid chroot.  Also, I have tested upgrades from and downgrades to 2.13-10
in an i386/amd64 chroot with a multiarch-capable dpkg and i386 as
primary architecture.  I haven't yet checked or analyzed the
consequences of unpacking failures during upgrade or downgrade.

Known problems:

- Multiarch systems with multiple libc6 versions shipping the /lib64
  symlink will be hosed if the native libc6 is not unpacked first.
  Since this involves at least one unofficial architecture and an 
  unofficial dpkg, it is probably ignorable.

- Installing packages that ship files under /lib64 and then downgrading
  to a libc6 that ships the symlink breaks those packages.  Should maybe
  give a warning on downgrades if any files beside the ELF interpreter
  are found in /lib64.

- The lsb-core package installs symlinks /lib64/ld-lsb-x86-64.so.[23] to
  /lib/ld-linux-x86-64.so.2 that get broken.  Nothing dramatic and
  solvable in a few ways.

Cheers,
       Sven

-- 
I still say "/lib64" is one of the nastiest pieces of shit I've ever
heard of.
-- Branden Robinson


>From 6ead53c51dac3ef8aa77b96b8c8f1a647f654a6d Mon Sep 17 00:00:00 2001
From: Sven Joachim <svenjoac@gmx.de>
Date: Thu, 11 Aug 2011 17:15:03 +0200
Subject: [PATCH 1/6] Don't create /lib64 and /usr/lib64 symlinks

---
 debian/sysdeps/amd64.mk          |    3 ---
 debian/sysdeps/kfreebsd-amd64.mk |    6 ------
 debian/sysdeps/ppc64.mk          |    6 ------
 debian/sysdeps/s390x.mk          |    6 ------
 debian/sysdeps/sparc64.mk        |    6 ------
 5 files changed, 0 insertions(+), 27 deletions(-)

diff --git a/debian/sysdeps/amd64.mk b/debian/sysdeps/amd64.mk
index c99dea4..67000a5 100644
--- a/debian/sysdeps/amd64.mk
+++ b/debian/sysdeps/amd64.mk
@@ -1,10 +1,7 @@
 libc_rtlddir = /lib64
 extra_config_options = --enable-multi-arch
 
-# /lib64 and /usr/lib64 are provided by glibc instead base-files: #259302.
 define libc6_extra_pkg_install
-ln -sf /lib debian/$(curpass)/lib64
-ln -sf lib debian/$(curpass)/usr/lib64
 
 make -C debian/local/memcpy-wrapper
 install -m 755 -o root -g root -d debian/libc6/$(libdir)/libc
diff --git a/debian/sysdeps/kfreebsd-amd64.mk b/debian/sysdeps/kfreebsd-amd64.mk
index 261cbda..635b72d 100644
--- a/debian/sysdeps/kfreebsd-amd64.mk
+++ b/debian/sysdeps/kfreebsd-amd64.mk
@@ -1,12 +1,6 @@
 # Main library
 extra_config_options = --disable-compatible-utmp --disable-multi-arch
 
-# /lib64 and /usr/lib64 are provided by glibc instead base-files: #259302.
-define libc0.1_extra_pkg_install
-ln -sf /lib debian/$(curpass)/lib64
-ln -sf lib debian/$(curpass)/usr/lib64
-endef
-
 # build 32-bit (i386) alternative library
 EGLIBC_PASSES += i386
 DEB_ARCH_REGULAR_PACKAGES += libc0.1-i386 libc0.1-dev-i386
diff --git a/debian/sysdeps/ppc64.mk b/debian/sysdeps/ppc64.mk
index 98cea4b..c8d2509 100644
--- a/debian/sysdeps/ppc64.mk
+++ b/debian/sysdeps/ppc64.mk
@@ -1,12 +1,6 @@
 libc_rtlddir = /lib64
 extra_config_options = --enable-multi-arch
 
-# /lib64 and /usr/lib64 are provided as symlinks 
-define libc6_extra_pkg_install
-ln -sf /lib debian/$(curpass)/lib64
-ln -sf lib debian/$(curpass)/usr/lib64
-endef
-
 # build 32-bit (powerpc) alternative library
 EGLIBC_PASSES += powerpc
 DEB_ARCH_REGULAR_PACKAGES += libc6-powerpc libc6-dev-powerpc
diff --git a/debian/sysdeps/s390x.mk b/debian/sysdeps/s390x.mk
index acb5c41..b3707cd 100644
--- a/debian/sysdeps/s390x.mk
+++ b/debian/sysdeps/s390x.mk
@@ -1,11 +1,5 @@
 libc_rtlddir = /lib64
 
-# /lib64 and /usr/lib64 are provided by glibc instead base-files: #259302.
-define libc6_extra_pkg_install
-ln -sf /lib debian/$(curpass)/lib64
-ln -sf lib debian/$(curpass)/usr/lib64
-endef
-
 # build 32-bit (s390) alternative library
 EGLIBC_PASSES += s390
 DEB_ARCH_REGULAR_PACKAGES += libc6-s390 libc6-dev-s390
diff --git a/debian/sysdeps/sparc64.mk b/debian/sysdeps/sparc64.mk
index 3b6771b..b224abb 100644
--- a/debian/sysdeps/sparc64.mk
+++ b/debian/sysdeps/sparc64.mk
@@ -1,9 +1,3 @@
 extra_config_options = --disable-multi-arch
 libc_rtlddir = /lib64
 libc_extra_cflags = -mcpu=ultrasparc
-
-# /lib64 and /usr/lib64 are provided by glibc instead base-files: #259302.
-define libc6_extra_pkg_install
-ln -sf lib debian/$(curpass)/lib64
-ln -sf lib debian/$(curpass)/usr/lib64
-endef
-- 
1.7.5.4

>From 83aa5a0bb6c2697712036b419565803771d46b23 Mon Sep 17 00:00:00 2001
From: Sven Joachim <svenjoac@gmx.de>
Date: Thu, 11 Aug 2011 18:28:37 +0200
Subject: [PATCH 2/6] Install the dynamic linker into RTLDDIR rather than /lib

---
 debian/debhelper.in/libc.install |    2 +-
 debian/rules.d/build.mk          |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/debian/debhelper.in/libc.install b/debian/debhelper.in/libc.install
index e377d64..78eabf0 100644
--- a/debian/debhelper.in/libc.install
+++ b/debian/debhelper.in/libc.install
@@ -1,4 +1,4 @@
-TMPDIR/lib/*.so* /lib
+TMPDIR/RTLDDIR/*.so* /lib
 TMPDIR/SLIBDIR/*.so* SLIBDIR
 TMPDIR/LIBDIR/gconv/* LIBDIR/gconv
 
diff --git a/debian/rules.d/build.mk b/debian/rules.d/build.mk
index 18f1800..36d7ee7 100644
--- a/debian/rules.d/build.mk
+++ b/debian/rules.d/build.mk
@@ -196,8 +196,9 @@ $(stamp)install_%: $(stamp)check_%
 	if [ $(curpass) = libc ]; then \
 	  rtld_so="$$(LANG=C LC_ALL=C readelf -l debian/tmp-$(curpass)/usr/bin/iconv | grep 'interpreter' | sed -e 's/.*interpreter: \(.*\)]/\1/g')" ; \
 	  rtld_so="$$(basename $$rtld_so)" ; \
-	  link_name="debian/tmp-$(curpass)/lib/$$rtld_so" ; \
+	  link_name="debian/tmp-$(curpass)/$(call xx,rtlddir)/$$rtld_so" ; \
 	  target="$(call xx,slibdir)/$$(readlink debian/tmp-$(curpass)/$(call xx,slibdir)/$$rtld_so)" ; \
+	  mkdir -p debian/tmp-$(curpass)/$(call xx,rtlddir); \
 	  ln -s $$target $$link_name ;  \
 	fi
 	
-- 
1.7.5.4

>From daed389bc55dae373e3aa0ed40fad5c729d8d8d9 Mon Sep 17 00:00:00 2001
From: Sven Joachim <svenjoac@gmx.de>
Date: Sat, 13 Aug 2011 10:22:21 +0200
Subject: [PATCH 3/6] Remove the /lib64 symlink on upgrades

Only necessary on amd64, ppc64, sparc64 and s390x.
---
 debian/debhelper.in/libc.preinst |   29 ++++++++++++++++++++++++++++-
 1 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/debian/debhelper.in/libc.preinst b/debian/debhelper.in/libc.preinst
index 1a6d5aa..2e3e946 100644
--- a/debian/debhelper.in/libc.preinst
+++ b/debian/debhelper.in/libc.preinst
@@ -118,6 +118,27 @@ check_dir () {
     done
 }
 
+remove_lib64_symlink() {
+    ldfile=$(readlink -e RTLD_SO)
+    # Test if libc is of the same architecture as coreutils
+    # If not, they almost surely have a multiarch system and we can use
+    # the native ELF interpreter
+    if ! $ldfile /bin/true 2>/dev/null; then
+	interpreter=
+    else
+	interpreter=$ldfile
+    fi
+
+    # sync before and after the operation to reduce the danger of hosing
+    # the system
+    sync
+    rm -f /lib64
+    $interpreter /bin/mkdir /lib64
+    $interpreter /bin/ln -s $ldfile RTLD_SO
+    sync
+}
+
+
 if [ "$type" = upgrade ]
 then
     # Remove old /etc/init.d/glibc.sh init script
@@ -220,7 +241,6 @@ then
 
     # Try to detect copies of the libc library in the various places
     # the dynamic linker uses.
-    ldfile=$(readlink -e RTLD_SO)
     ldbytes=$(head -c 20 RTLD_SO | od -c)
     libcfiles=$(dpkg-query -L LIBC 2>/dev/null)
 
@@ -384,6 +404,13 @@ fi
 #DEBHELPER#
 
 if [ -n "$preversion" ]; then
+    if test -L /lib64; then
+	case ${DPKG_MAINTSCRIPT_ARCH:-$(dpkg --print-architecture)} in
+	    amd64 | ppc64 | sparc64 | s390x)
+		remove_lib64_symlink ;;
+	esac
+    fi
+
     if dpkg --compare-versions "$preversion" lt 2.13-5; then
        # upgrading from a pre-multiarch libc to a multiarch libc; we have
        # to blow away /etc/ld.so.cache, otherwise the old unpacked libc
-- 
1.7.5.4

>From 9c45923df4f6b97233398118850885048744b8ce Mon Sep 17 00:00:00 2001
From: Sven Joachim <svenjoac@gmx.de>
Date: Thu, 11 Aug 2011 22:36:52 +0200
Subject: [PATCH 4/6] Restore multiarch support on all architectures

---
 debian/rules.d/debhelper.mk |   14 +-------------
 1 files changed, 1 insertions(+), 13 deletions(-)

diff --git a/debian/rules.d/debhelper.mk b/debian/rules.d/debhelper.mk
index 1f21083..4d6d07d 100644
--- a/debian/rules.d/debhelper.mk
+++ b/debian/rules.d/debhelper.mk
@@ -109,19 +109,7 @@ endif
 
 	dh_installdeb -p$(curpass)
 	dh_shlibdeps -p$(curpass)
-
-	#
-	# Disable multiarch support on some architectures until we fix the /lib64 -> /lib issue
-	#
-	case $(curpass)/$(DEB_HOST_ARCH) in \
-	libc6/amd64 | libc0.1/kfreebsd-amd64 | libc6/ppc64 | libc6/s390x | libc6/sparc64) \
-		dh_gencontrol -p$(curpass) -- -UMulti-Arch \
-		;; \
-	*) \
-		dh_gencontrol -p$(curpass) \
-		;; \
-	esac
-
+	dh_gencontrol -p$(curpass)
 	if [ $(curpass) = nscd ] ; then \
 		sed -i -e "s/\(Depends:.*libc[0-9.]\+\)-[a-z0-9]\+/\1/" debian/nscd/DEBIAN/control ; \
 	fi
-- 
1.7.5.4

>From 34e32b8b1b8ff8716308edb39429cb6d6da840c9 Mon Sep 17 00:00:00 2001
From: Sven Joachim <svenjoac@gmx.de>
Date: Fri, 12 Aug 2011 17:48:24 +0200
Subject: [PATCH 5/6] Install the dynamic linker into /lib as well

This makes it a little easier to support downgrades.
---
 debian/debhelper.in/libc.install |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/debian/debhelper.in/libc.install b/debian/debhelper.in/libc.install
index 78eabf0..8c9e0bf 100644
--- a/debian/debhelper.in/libc.install
+++ b/debian/debhelper.in/libc.install
@@ -1,3 +1,4 @@
+TMPDIR/RTLDDIR/*.so* RTLDDIR
 TMPDIR/RTLDDIR/*.so* /lib
 TMPDIR/SLIBDIR/*.so* SLIBDIR
 TMPDIR/LIBDIR/gconv/* LIBDIR/gconv
-- 
1.7.5.4

>From 808e3534815c1f628964ad03f0bfeacc18dc5b77 Mon Sep 17 00:00:00 2001
From: Sven Joachim <svenjoac@gmx.de>
Date: Sat, 13 Aug 2011 17:36:14 +0200
Subject: [PATCH 6/6] Restore the /lib64 symlink on downgrades

It would be more prudent to prevent the downgrade from happening, but
if we fail the prerm script, the one from the previous version kicks
in and succeeds.  After that there is no way to stop the machinery
which leads to the loss of the dynamic linker.
---
 debian/debhelper.in/libc.prerm |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/debian/debhelper.in/libc.prerm b/debian/debhelper.in/libc.prerm
index 6f1a7db..3866d40 100644
--- a/debian/debhelper.in/libc.prerm
+++ b/debian/debhelper.in/libc.prerm
@@ -7,9 +7,45 @@ if [ "x$2" != "xin-favour" ]; then
     preversion=$2
 fi
 
+restore_lib64_symlink() {
+#Downgrading from a version with a /lib64 directory to a version with
+# a /lib64 symlink is extremely dangerous.  We need to blow away the
+# directory and restore the symlink, otherwise the dynamic linker gets
+# lost after unpacking the replacing version.
+
+    ldfile=$(readlink -e RTLD_SO)
+    # Test if libc is of the same architecture as coreutils
+    # If not, they almost surely have a multiarch system and we can use
+    # the native ELF interpreter
+    if ! $ldfile /bin/true 2>/dev/null; then
+	interpreter=
+    else
+	interpreter=$ldfile
+    fi
+
+    # sync before and after the operation to reduce the danger of hosing
+    # the system
+    sync
+    rm -rf /lib64
+    $interpreter /bin/ln -s /lib /lib64
+    sync
+}
+
+
+
 #DEBHELPER#
 
 if [ -n "$preversion" ]; then
+    if dpkg --compare-versions "$preversion" lt 2.13-17; then
+	# downgrading from 
+	if ! test -L /lib64; then
+	    case ${DPKG_MAINTSCRIPT_ARCH:-$(dpkg --print-architecture)} in
+		amd64 | ppc64 | sparc64 | s390x)
+		    restore_lib64_symlink ;;
+	    esac
+	fi
+    fi
+
     if dpkg --compare-versions "$preversion" lt 2.13-5; then
         # downgrading from a multiarch libc to a pre-multiarch libc; we have
         # to blow away /etc/ld.so.cache, otherwise the old unpacked libc
-- 
1.7.5.4


Reply to: