Debian i386 to amd64 conversion

After doing this two times, I finally conclude that it *is* possible to convert an i386 debian installation to an amd64 one. At the end of the procedure most of the system will work. Here is how:

NOTE: Don’t do anything that is mentioned here unless you fully understand what you are doing. You will most probably need to customize this procedure a bit!

You’ll need enough free space for the procedure to work.

While you still have a working system, print this document and download the latest debian netinst image. This can be used as a rescue disk if something goes wrong. It is trivial to restore your system using a rescue CD since we will not delete anything at all.

Step 1: Backup

I cannot stress this enough. Backup all your data, especially databases and anything binary that needs an executable file to be accessed. Most probably files at your home directory don’t risk at all but better be safe than sorry.

It is absolutely essential to backup your PostgreSQL database if you have one. The i386 and amd64 disk formats are not compatible (bad postgre… bad bad) and you’ll need to restore the database. This most probably comes to:

# # Backup:
# su - postgres
$ pg_dumpall > mydump
# # Restore
$ cat mydump | psql template0

I’ve done this procedure twice without backing up anything 🙂 except from the PostgreSQL database which is required. The reason I didn’t backed-up anything is that I was sure I could rollback to my old system using a rescue CD. If you don’t know how just backup.

Step 2: Install an amd64 kernel
You’ll need to boot your i386 with an amd64 kernel. Do:

# apt-get install libc6-amd64 linux-image-2.6-amd64
# # Most probably you would like to have X working while you run this procedure so install your favorite closed-source modules too:
# apt-get install nvidia-kernel-2.6-amd64

and reboot

Step 3: Install a base amd64 system.

# mkdir /amd64
# dpkg --get-selections '*' > /amd64/sel1
# debootstrap --arch=amd64 lenny /amd64 http://myproxy/

(NOTE: The above code was corrected to include “–arch=amd64” which I forgot to include. Thanks to Slawek Wernikowski)

Step 4: Install an identical amd64 system
Since this is a time consuming procedure and many things can go bad, I suggest you run this under “screen”. This way, if the X server crashes you will not loose what you’ve done.

# chroot /amd64 /bin/bash
# vi /etc/apt/sources.list
# # Add all sources.list entries that exist in your main system but not the CDs
# vi /etc/apt/apt.conf
# # Add the line: APT::Default-Release "your-release";
# # if needed
# apt-get install locales
# mount /proc
# mount /sys
# mount -t devpts none /dev/pts
# export TERM=xterm
# dpkg --set-selections < /sel1

Now run the following lines until everything is installed. Most probably parts of the installation may fail and you'll need to rerun those commands. It should be OK. At the end there can be some packages that will not be configured. Just ignore them for now.

# apt-get -o 'Dpkg::Options={"--force-confdef";"--force-confnew"};' dselect-upgrade
# dpkg --configure --force-confdef --force-confnew -a

I repeat: You'll have to repeat the above commands until everything is installed. If you have trouble just fix it yourself. Don't forget that you're working in a chrooted amd64 system.

Step 5: Change the system
This is the part that I don't have written so there might be some this missing. Key points are here and you should be able to figure what you need to do if something goes wrong. It is really a very simple procedure:

# init 1
# mkdir /i386

# # Move /usr
# mv /usr /i386
# mv /amd64/usr /

# # Backup etc
# cp -pR /etc /i386

# # Move /lib32 and /lib64 away if they exist
# mv /lib32 /i386
# mv /lib64 /i386

# # Create links
# ln -s /lib /lib64
# ln -s /emul/ia32-linux/lib /lib32

## Move other dirs
# mv /amd64/emul /
# mv /sbin /i386
# mv /amd64/sbin /

Now is the tricky part where you move /lib and /bin:

# # /bin is easy
# mv /bin /i386
# /i386/bin/mv /amd64/bin /
# # Don't forget that you can only run commands from /i386 from now on until /lib is replaced.
# # So, to do ls just write: /i386/bin/ls

# # Time for /lib
# mv /lib /i386
# # At this point you cannot execute anything at all but don't panic. Just run everything using the runtime linker. This is what happens whenever you run a command.
# export LD_LIBRARY_PATH=/i386/lib
# /i386/lib/ld-2.7.so /i386/bin/mv /amd64/lib /
# # TATA! Welcome to your amd64 system!
# ls

Step 6: Fix /var
This step is highly dependent on what you have installed. Most probably you can remove old /var and keep the new one. If you'd like to keep the old one there are some dirs that you need to replace:

# cd /var
# mv cache cache.i386
# mv /amd64/var/cache .
# # I suggest that you replace the whole /var/lib tree:
# mv lib lib.i386
# mv /amd64/var/lib .

Whatever you do you should know that you should replace /var/lib/dpkg and /var/cache/apt with the new one.

Step 7: Make system bootable
Finally you should ensure that your system is bootable. A nice approach is to clean your /boot from whatever kernel is installed (don't forget that with your new system, no package will own existing kernels) and force-reinstall your current kernel:

# cd /boot
# mkdir i386
# mv System* initrd* vmlinuz* config* i386
# apt-get install --reinstal linux-image-2.6.26-amd64
# # Replace linux-image-2.6.26-amd64 with your current kernel

This is it. Unless I've forgotten something you should just reboot to your know system. After rebooting you will have to fix the unconfigured packages and possible rerun dselect-upgrade:

# dpkg --configure -a
# apt-get dselect-upgrade

Finally, restore your PostgreSQL database and you're done.
MySQL doesn't need dump and restore but wou'll have to copy/move old files from /var/lib.i386/myslq to /var/lib/mysql.