copyright 1998-2017 by Mark Verboom
ipv6 ready RSS Feed Schakel naar Nederlands

Go back to What's new

Debian inplace 32bit to 64bit upgrade

To blog index

Saturday, 23 October, 2010

Debian inplace 32bit to 64bit upgrade

Based on this great article:

http://teddyb.org/~rlpowell/hobbies/debian_arch_up/

I have done quite a few migrations of debian systems from 32bit to 64 bit without a reinstall. I have made quite a few modifications in the procedure and streamlined it a bit. Below is the base procedure I follow to upgrade.

Beware: this isn't a fool proof procedure! You need to know what you're doing. If you don't, you can easily destroy you system.

To begin, check you have a 64bit kernel installed, which has 32bit binary capability. When doing a

uname -a

it should return x86_64.

Make sure the following packages are installed.

apt-get install libasound2 lsb-release

Also, make sure you have a complete install against your currently defined repository. If you are not sure, run the following commands (these can be quite interesting, even without upgrading to 64bit :) ):

apt-get upgrade
apt-get dist-upgrade

Before starting, we need a script to easily retrieve packages from a debian repository. Using this script saves a lot of time manually downloading packages.

getdeb

Change the parameters in the script to suite your needs.

Now, when the base system is up-to-date, we start with creating some directories. This is done in root's homedir, make sure you have a bit of space there, or choose another directory.

cd /root
mkdir to64
cd to64
dpkg --get-selections > packagelist
mkdir lib32
cd lib32

Now we're going to download some 32bit packages from the 64bit repository.

for name in lib32gcc1 lib32asound2 lib32stdc++6 ia32-libs lib32ncurses5 lib32z1
do
~/getdeb -p amd64 $name
done

And some 64bit packages:

cd /root/to64
mkdir lib64
cd lib64

for name in apt apt-utils binutils bzip2 coreutils cpio debianutils dpkg ed gcc-4.3-base libacl1 libasound2 libattr1 libbz2-1.0 libc6 libdb4.5 libgcc1 libgdbm3 libgpm2 libncurses5 libreadline5 libselinux1 libsepol1 libstdc++6 make ncurses-bin patch perl-base perl sed libc6-i386 perl perl-base libperl5.10
do
~/getdeb -p amd64 $name
done

Just to be clear, these package work at the moment for me, in the unstable repository. I could very well be you need different packages.

We're now going to install the 64bit package version of libc6 32bit:

cd /root/to64/lib64
dpkg --force-depends --force-architecture --force-overwrite -i libc6-i386_*
ln -sf /lib32/ld-linux.so.2 /lib/ld-linux.so.2

And the rest of the 32bit compatablilty packages:

cd /root/to64/lib32
dpkg -i --force-architecture *.deb

ln -sf /lib32/ld-linux.so.2 /lib/ld-linux.so.2

Then we're going to install the base of the 64bit packages:

cd /root/to64/lib64
dpkg --force-architecture -i libc6_*

dpkg --force-architecture -i apt_* dpkg_* apt-utils_* libstdc++6_* libgcc1_*

Now we need to check the following commands still work:

dpkg
apt-get
apt-extracttemplates

If those still work, make sure the current architecture is amd64:

dpkg --print-architecture
amd64

Now we're going to upgrade all packages to 64bit. First, fix some problems with the perl packages:

dpkg -i perl* libperl*

This should give a couple of errors, ignore those. Then we update the packages. This can take quite some time.

apt-get update
apt-get -f install

I usually get a conflict here on the kdb package (you could get other conflicts depending on your install base). The error looks like this:

kbd conflicts with console-utilities
conflicting packages - not installing kbd

I usually resolve it like this:

dpkg --force-depends --purge console-tools

Which will also produce an error :). Just keep going by issueing a:

apt-get -f install

Now we need to build a list of still installed 32bit packages.

cd /root/to64
for package in $(grep '[^e]install' packagelist | awk '{ print $1 }')
do
dpkg -s $package | grep -q 'Architecture: i386' && echo $package
done >reinstall

All these packages need to be reinstalled. This can take quite a while.

for name in `cat reinstall`
do
apt-get -y --reinstall install $name
done

To be sure there aren't any pending packages, issue:

apt-get -f install

Now we need to verify which installed packages are still 32bit. Build a list with the following commands:

for package in $(dpkg -l | grep '^i' | awk '{ print $2 }')
do
dpkg -s $package | grep -q 'Architecture: i386' && echo $package
done > i386packages

Check the 32bit packages

more i386packages

It can be that you have some 32bit packages installed. For example, some old packages that have been phased out and don't have any 64bit install candidates, or kernel packages. If you want to make sure, do the following (example is for the gcc-4.2-base package):

apt-get install gcc-4.2-base
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Couldn't find package gcc-4.2-base

In this case, no package is available.

If all packages are ok, remove the 32bit packages by:

dpkg -r $(cat i386packages | tr ' 12' ' ')

Verify your installation one more time, this should not result in any installs.

apt-get -f install

Just to be sure, it might be usefull to regenerate your kernel's initrd image. It is best to remove the existing and regenerate it. The example below is for a 2.5.32.22-openvz64 kernel:

update-initramfs -d -k 2.6.32.22-openvz64
update-initramfs -c -k 2.6.32.22-openvz64

If you are paranoid there are still important executables out there that need to be upgraded, you can always look for them:

find / -executable | xargs file | grep "ELF 32-bit" | cut -d ':' -f 1

Basically your system should now be converted to 64bit and be able to boot. Give it a try :)