Linux - upgrade 32-bit to 64-bit? (i[3456]86 to amd64/x86_64) It's a commonly asked question: "Can I upgrade my 32-bit installed Linux distribution to 64-bit?" The answer is: Yes* The more accurate and complete answer is a (much more) qualified yes: *Yes, ... if your distribution has both 32-bit and 64-bit versions, typically significantly to much easier to backup the 32-bit version, saving all data (and meta-data) that might be needed, do a fresh 64-bit installation, then carefully migrate data as wanted onto the 64-bit version. And of course one has to have the appropriate 64-bit capable machine. Similar procedure can also be used migrating to new(er) 64-bit capable hardware. But what if you really want to do an upgrade-in-place operation, from 32-bit to 64-bit? The "worst case" would be highly difficult ... if you really want to go that route. It's Linux, one can dig as necessary to determine precisely what's different and make those changes - but one may need the host to be down when doing that. But if you have a Linux distribution with multiarch support, e.g. current Debian, and at least certain derivatives: http://www.debian.org/News/2013/20130504 http://www.debian.org/News/2011/20110726b https://wiki.debian.org/Multiarch#Current_Status Then doing such an upgrade (or cross-grade) is quite a bit easier, but still quite non-trivial. "in the future will even allow live migrations from 32-bit to 64-bit systems" Yes, in future that may be a comparatively easy procedure, but it is quite doable presently, ... it's just not all that easy to do. So ... thought I'd run the experiment, as I do have some hosts I might want to do such an upgrade (or cross-grade) on. There is also a lot of documentation and the like on how to go about doing it ... but doesn't yet seem to be any simple sure-fire recipe that one can run to do it all. Though there are lots of useful bits and "tools" and procedures information, on how to go about doing it both general, and in a fair bit of specificity. Anyway, I set up a virtual machine (under qemu-kvm), installed Debian GNU/Linux 7.4.0 "Wheezy" i386 on it and upgraded to 7.5.0 (as I'm writing this, the 7.5.0 ISO images aren't out on the mirrors quite yet, but should be very soon - 7.5.0 was released 2014-04-26, and the packages are available). So, the procedure - for Debian (or derivative?) with multiarch support. This is just an outline - I don't cover all the steps in detail: Add 64-bit architecture support: # dpkg --add-architecture amd64 Update apt so it also knows about the 64-bit stuff: I set the Debian CD ISO images: Debian GNU/Linux 7.4.0 "Wheezy" - Official amd64 CD Binary-1 20140208-13:47 Debian GNU/Linux 7.4.0 "Wheezy" - Official i386 CD Binary-1 20140208-12:25 respectively on /dev/sda and /dev/sdb and mounted respectively on /media/cdrom9 and /media/cdrom8 (I did that to avoid all the insert/remove CD stuff, and if I needed packages from either, to generally go much lighter on the mirrors). I then updated my /etc/apt/sources.list so its active lines contained: deb [arch=amd64] file:/media/cdrom9 wheezy main deb [arch=i386] file:/media/cdrom8 wheezy main deb http://http.debian.net/debian/ wheezy main deb-src http://http.debian.net/debian/ wheezy main deb http://security.debian.org/ wheezy/updates main deb-src http://security.debian.org/ wheezy/updates main deb http://http.debian.net/debian/ wheezy-updates main deb-src http://http.debian.net/debian/ wheezy-updates main and then did: # apt-get update One should be sure one's packages are in a clean state before proceeding, e.g. see: http://www.debian.org/releases/wheezy/i386/release-notes/ch-upgrading.en.html#system-status and especially: http://www.debian.org/releases/wheezy/i386/release-notes/ch-upgrading.en.html#package-status Good idea to capture package status before we proceed further, e.g. save the output of: # dpkg --get-selections to a file. Also, many of the "recipes" given make use of such data or portions thereof (e.g. to pick out i386 that's installed, and configure to install amd64). It may also be advisable to capture information regarding the installed packages, if they were specifically requested, or automatically installed to satisfy dependency(/ies). One may later want to similarly mark amd64 packages as they were for their earlier i386 counterparts. One might also want that information for packages who's architecture is "all", as some of those might get upgraded/replaced/reinstalled along the way. Now we're ready to install packages. First, add a 64-bit kernel: # apt-get install linux-image-amd64:amd64 Then reboot using the 64-bit kernel. Presuming that went fine, one can remove the 32-bit kernel So much for the easy portions. I'll just outline the rest. It's mostly a matter of getting things added/replaced/removed in the "right" order - or sufficiently correct order that it all works. Some of the many key bits: dpkg & apt - until these are repladed with the 64-bit versions, the existing versions think the native architecture is 32-bit, and 64-bit is "foreign". There are lots of dependencies - most notably libraries. When dealing with dpkg and apt-get, one can append specific architecture, e.g. appending on package architecture: :i386 for i386 (32-bit), and :amd64 for amd64 (64-bit) - that can be done to be sure one installs/removes/purges the desired package(s), particularly while dpkg and apt still are at 32-bit and treat the native architecture as i386 and treat amd64 as foreign. Beware that the apt package has a lot of dependencies, so it's not one of the easier ones to get from 32-bit to 64-bit, but it is both important and essential. One can also use - and _ suffixes for remove and purge with apt-get, so, e.g. one can add and remove/packages with a single apt-get command. The -s option to apt-get and --simulate option to dpkg will come in very handy. Many/most of the operations you'll want to see first if the dependencies have already been met, or not or if any conflicts or other problems show up. If/when you encounter any predepends, those need to be installed first, not at the same time with dpkg. You'll want to be able to use dpkg fairly well, it's lower-level than apt-get, but you'll need it for some operations, e.g. for making the transition of the apt package from 32-bit to 64-bit, and even dpkg itself. Be very careful with "essential" packages. If you make an error there it may be difficult to recover. The binutils package may come in quite handy on current Debian, notably as it contains ar - and Debian packages (.deb files) are in ar format. If needed, one can use ar(1) to extract contents from a Debian package. E.g. if one breaks findutils, which dpkg -i depends upon (depends upon the find binary). In general you shouldn't have to --force anything. If apt-get is giving you warnings with notification such as: To continue type in the phrase 'Yes, do as I say!' That is probably not the path you want to go down. Package versions need to match. If you're going from 32-bit to 64-bit version of package, in many cases apt-get won't handle that for you (or at least not without forcing it, which will typically break things) and you'll need to use dpkg. E.g. where the version numbers match, one can use dpkg -i to install the 64 bit version, and where it's, e.g. something like a general utility and not a library, it will generally replace the 32-bit version with the 64-bit version - if all the dependencies for the 64-bit version are in place or covered on the dpkg command, and all reverse-dependencies for removing the 32-bit version have been covered. Use of apt-get download can be very handy. One may want to use /var/cache/apt/archives for download location, as that's where apt-get install defaults to caching files it downloads. You'll want to be sure you notice, catch and correct, certain errors that may be critical. E.g. if a package update/installation causes new initramfs to be built for kernel(s) and that throws error(s), be sure to correct those. E.g. one can fix a missing/broken dependency, then reconfigure the dependent package that caused the error to be thrown, e.g.: ... Setting up lvm2 (2.02.95-8) ... Setting up LVM Volume Groups...done. update-initramfs: deferring update (trigger activated) Processing triggers for initramfs-tools ... update-initramfs: Generating /boot/initrd.img-3.2.0-4-amd64 mount: error while loading shared libraries: libmount.so.1: cannot open shared object file: No such file or directory # dpkg -i /media/cdrom9/pool/main/u/util-linux/mount_2.20.1-5.3_amd64.deb ... # dpkg-reconfigure lvm2 ... In the above case, mount was installed, but it was i386 and wasn't happy with its library situation, whereas the libraries for amd64 mount were already installed - so just needed the amd64 mount installed and reconfigure lvm2 to correct the error it encountered in updating the initramfs. And if one does go through with getting rid of all i386 (e.g. if it's not wanted or needed), one can remove the i386 architecture, e.g.: # dpkg --remove-architecture i386 One would also then typically want to remove any i386 specific architecture bits from /etc/apt/sources.list and again update apt: # apt-get update One may want to reboot when all is done, to ensure all is working as expected, and to also ensure no i386 binaries are still in use (e.g. unlinked open files still being executed). Alternatively, one may look for open unlinked files that belong to any removed/purged i386 packages. lsof may be handy for that (or use of find and the proc filesystem), one can see some examples of that for a bit different task on: http://linuxmafia.com/pipermail/sf-lug/2014q2/010408.html And a much cleaner run at it. The files linked below are bzip2(1) -9 compressed from script(1) with -t option. One may want to shorten up some of the longer (idle/waiting/inactive) times in the time file, e.g.: (where here, our leading $ is PS1, and leading > is PS2) $ bzip2 -d < 32to64.time.bz2 | > > 32to64.shorter_wait_times \ > sed -e 's/^[0-9]\{2,\}\.[0-9]\{1,\} /3.000000 /' And uncompress the script file: $ bzip2 -d 32to64.script.bz2 And one can then review it with scriptreplay(1), e.g. to see that at triple speed: $ scriptreplay 32to64.shorter_wait_times 32to64.script 3 That was captured connecting via serial console (virtually), as for terminal type, one would probably want to do that in an 80x24 vt100, or xterm, screen, or ANSI terminal or emulation, for best reproduction/viewing results. {{system:32to64.script.bz2}} {{32to64.time.bz2}} Also, what was captured mostly just shows actual changes done. For the most part I used a separate session for doing things like simulation runs, e.g.: # apt-get -s ... # dpkg --simulate ... downloads: # apt-get download ... and working out various dependencies (typically from the simulations above), and statuses (typically via use of $ COLUMNS=200 dpkg -l and sometimes also: # apt-get -s install and picking over the resultant data). For the most part, when # dpkg --simulate -i ... came back looking clean, the corresponding # dpkg -i ... worked fine, but not always - sometime the latter would expose additional dependencies or other (relatively minor) issues. Most commonly, if not always, such issues were resolved just by bringing in another package to a few packages or so, and then a: # dpkg --configure --pending and all was then fine. Seems the whole process could (almost?) be automated by some higher-level script/program (e.g. perl) to work all that stuff out and implement it. The only part that might be a bit more tricky, is in some cases, there wasn't a precise correspondence between i386 and amd64 packages. E.g., in almost all cases, it was simply matter of same package and version number in i386 architecture being replaced with same from amd64 architecture. But not always - there were some exceptions. But at least where I encountered such, it was easy enough to figure out from the dependencies and/or lack thereof, or from the names and descriptions, etc. And one issue that was found a little bit later (2014-06-13) and corrected, from our [[http://www.archive.balug.org/log.txt|system log]] file: Noticed bug/issue with spell, e.g.: $ echo foo | spell /usr/bin/ispell: Illegal format hash table Tried: # (cd / && umask 022 && dpkg-reconfigure spell) # (cd / && umask 022 && dpkg-reconfigure dictionaries-common) # (cd / && umask 022 && dpkg-reconfigure ispell) Those didn't correct it, but this did: # (cd / && umask 022 && dpkg-reconfigure iamerican) That updated: /var/lib/ispell/american.hash Guessing this may have been issue left over from i386 to amd64 conversion See also: [[https://wiki.debian.org/CrossGrading|CrossGrading]] (a Debian system - on the Debian wiki)