« Previous | Next»

Migration Debian from i386 to amd64 without reinstall (Cross Grading)

Posted by coldtobi | 2 Nov, 2013, 14:53

Well, I just started the adventure to upgrade my NAS server from i386 to amd64.. Why? I want to enable flash-cache, which is currently not compatible with 32-bit kernels.

For this I am using the "Cross Grading"

Note: This is dangerous stuff. If you are not really deep into Debian you should prefer reinsalling! Backups are mandatory.

Modern Debian's >wheezy supports MultiArch, that is that you can more than one arch at the same time. Of course the hardware needs to support both archs. And with a recent dpkg you can also "cross grade", switching a live system.

Note: Make sure your system supports amd64!

grep -q '^flags.* lm ' < /proc/cpuinfo && echo yes

should say "Yes"

Okay, lets start.

Before really starting you should update your installation as much as possible, because you will end up with "actual" packages which might brake stuff. Better sort that before :)

Backups wont hurt either -- especially I backuped /etc and the output of dpkg --get-selections.

The first steps in this Debian Wiki "Cross Grading" works as advertised

# dpkg --print-architecture  i386  

# dpkg --add-architecture amd64

# dpkg --print-foreign-architectures amd64

# apt-get update

# apt-get install linux-image-amd64:amd64

# reboot

Now you need to make sure to boot the amd64 kernel. Verify with

uname -a

Now get the amd64 versions of dpkg and apt.(Note: pwd is /var/cache/apt/archives. You might also remove all *_amd64.deb files before from this directory)

# apt-get --download-only install dpkg:amd64 apt:amd64
# dpkg --install /var/cache/apt/archives/*_amd64.deb
# dpkg --print-architecture
amd64
# dpkg --print-foreign-architectures
i386

So basic bootstrap done...  lets continue with that tutorial:

apt-get install $(grep-status --field=Status "install ok installed" | grep-dctrl --field=Multi-Arch same
--show-field=Package --no-field-names | sed 's/\(.*\)/\1:amd64/')

should pull in several packages. At my box it complained about some packages which it could not resolve, but as apt-get remove won't work at this point, you need to dpkg --remove every complaining package and if necessary its dependencies too. However, my result was not satisfing..

After that, I did an

apt-get install -f --download-only

to retrieve all package. Note that "install" did lead to errors, so I installed them manually with

dpkg -i /var/cache/apt/archives/sed*_amd64.deb

dpkg -i /var/cache/apt/archives/*_amd64.deb

(note that I installed sed first as it has vanished before, when doing the apt-get install -f)

Some package will not install due to dependencies, but you can either manually install them or just run the above line again. If after some iterations nothing improved, you probably need to resolve manually. In my case for example I had to purge exim4-daemon-light to make progress.

Then the fun begins. As in the second tutorial link, apt-get install -f just barked out with many errors, unable to correct the dependencies. So you need manually install the missing dependencies.

Use

apt-get install -f --download-only 2>&1 | less

to get a clue whats missing and resolve them by

apt-get download <package>

and

dpkg -i <package>

Hint: a apt-cache clean in between helps to clean up the package cache -- then a dpkg -i *_amd64.deb will install only new ones. Rinse repeat. However, I first tried to "reduce" that list a little:

One thing I did to aid in resolving the dependencies was also to use the above line, but only one package per invocation:

for files in $(grep-status --field=Status "install ok installed" | grep-dctrl --field=Multi-Arch same --show-field=Package --no-field-names | sed 's/\(.*\)/\1:amd64/'); do apt-get download $files; done

(Also you can remove config-files for removed i386 packages with:)

dpkg --list | grep :i386 | grep ^rc | awk '{print $2} ' | xargs dpkg --purge

dpkg-query -W --showformat='${Package}\t${Priority}\n' | grep "required$" | awk '{print $1}' | sort | uniq

will list all required packages.Lets install them first. Repeat dpkg -i as required on failed packages, it might also be that you need to download some packages manually, even if that should not happen :)

apt-get clean

list=$(dpkg-query -W --showformat='${Package}\t${Priority}\n' | grep "required$" | awk '{print $1}' | sort | uniq);

apt-get download $list ;

dpkg -i *_amd64.deb

I did also a reinstall of all libraries that were :i386 and installed (as the first script did not as intended). This snipped shows a list of canidates , which can be refined e.g with an addtiional grep on lib

dpkg --list | grep :i386 | grep ^ii | awk '{print $2} ' | awk -F: '{print $1} '

After that, lets retry apt-get install -f again... Well, still no luck. But as in the list are some interpreter languages like perl and pyhton, lets update those manually first

apt-get clean

apt-get download perl python python3

for f in $(dpkg --list | grep i386 | grep ^ii | awk '{print $2} ' | awk -F: '{print $1} ' | grep python); do apt-get download $f; done

dpkg -i *.deb

Well, the resolver is still not working. So lets go through the error list from apt-get install -f by hand and install packages it says it is missing. But lets try to download the packages which are broken and have i386 in their arch. This two-liner did it for me by first removing (or trying to) the offending packages and then installing the amd64 version

apt-cache clean

apt-get download $(apt-get install -f 2>&1 | grep ":i386 :" | awk -F: '{print $1}')

dpkg -i *.deb

Strike :) Now apt-get install -f gives a solution. However in my case it seems to remove a tons of packages and also installed apache , but that is easily fixable later -- with the backup of the dpkg --get-selections

#remove the :i386 from our backup

cat dpkg-selections | sed "s/:i386//" >dpkg-selections_noarch

dpkg --set-selections <dpkg-selections_noarch

You will get errors like

dpkg: error: illegal package name at line 157: ambiguous package name 'gcc-4.8-base' with more than one installed instance

That means you need to uninstall the offending package with the suffix :i386 (but you can immediatly install it with amd64, if not already pulled in)

apt-get remove gcc-4.8-base:i386

Note: The above example showed to be not so bright -- it removed too many systems packages, including apt. Fortunatly I saw this, stopped apt by Ctrl+C and manually installed apt again (luckily it was still in a package cache. So you should maybe do not apt-cleans above, but move them to a tempoary directory above. And always keep at least wget, apt, dpkg and dependencies around.(dpkg should be also available unpacked as a last resort)

At the moment this little script is running to purge all :i386 conflicts in the selections file. It will brute-force install the amd64 version of the package (it should be already there -- but I am in paranoid mode. It can happen that there are only config files for both archs -- in this case it will install the previously removed package) and then will purge package and the configuration files for i386. However, you better watch it to avoid any surprised.

while (/bin/true); do dpkg --set-selections <dpkg-selections_noarch; pack=$(dpkg --set-selections <dpkg-selections_noarch 2>&1 | awk -F \' '{print $2}'); apt-get install $pack; apt-get remove --purge -y $pack:i386; done

Eventually it will complete and then the dpkg --set-selections <dpkg-selections_noarch will work. To apply the selections, execute  apt-get dselect-upgrade. However, mine did wanted to pull in i386 packages... Not what I want.

I found this workaround: In /var/lib/dpkg/arch remove the "i386". Then apt-get dselect-upgrade does what I expect from it... (I did also an apt-get update)

After apt-get finished, you should restore /var/lib/dpkg/arch and take a look about remaining packages. dpkg --list | grep i386 should give a list and is a good starting point for updating.For example I used aptitude to schedule the updates:

list=$(dpkg --list | grep i386 | awk '{print $2}')
list2=$(for files in $list; do echo -n "$files:i386 " ; done)
aptitude remove  --schedule-only $list2
aptitude install  --schedule-only $list
aptitude install

After that, there were only a few pacakges left which where packages with only config files present. I purged them manually. Finally you can remove the old arch. 

dpkg --list | grep i386 | wc -l

0

dpkg --remove-architecture i386


Keep fingers crossed fo the reboot..

(Done, everything works fine)

General, Linux / Debian | Comments (0) | Trackbacks (0)

Related Articles:

0 Comments | "Migration Debian from i386 to amd64 without reinstall (Cross Grading)" »