I recently found myself needing to upgrade the hard disks in a few PCs to bigger and and faster ones. The thought of having to reinstall Windows from scratch an all of them made my heart sink into the pit of my stomach so I set about seeing what would be involved in “cloning” the contents of the existing disks onto the new replacements. I could have just paid for Acronis Migrate Easy (which seems to be generally well-regarded), but where’s the fun in that ?! In the end, I successfully migrated a number of PCs using free software. This article describes how.
The usual disclaimers apply…this is what worked for me – if you try it and it goes wrong and you haven’t taken the normal sensible precautions before embarking on an endeavour like this then please don’t come crying to me.
Step 1 – Partition the new hard disk
I found it easiest to do this from Windows. I connected the new hard disk to the PC and created the partitions using the normal Disk Management tool. You will save yourself some trouble if you “match up” the partition numbers on the old and new disks (i.e. if your Windows partition is on partition #1 on the old disk, make sure it is on partition #1 on the new disk also). On some of the PCs there was a Dell diagnostics partition present (so the Windows partition was actually the second partition). More about this below.
Step 2 – Delete (or rename) the HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices key in the registry
Doing this now will save you a world of pain later on. The problem is that Windows maintains a mapping of volume IDs to drive letters under this registry key
Here, my new drive was mounted as drive N: when I partitioned it. If I do nothing now, Windows will remount it as drive N: (instead of C:) when I later boot from it, which won’t end well. If I just zap this registry key, Windows will recreate it when it next boots (although it will have forgotten about what drive letters you liked for your USB keys etc.) I guess you could just delete the entries for C: and N:…I didn’t try this.
Step 3 – Reboot into Linux
I variously used Fedora Core 8 and Knoppix 5.1.1…both contained the required NTFS tools and both worked perfectly. At this stage, I have both the old and the new drives attached to the PC. I did this with various combinations to attachment from direct PATA to USB-to-PATA or USB-to-SATA converters and they all worked perfectly.
Step 4 – Dell Diagnostics Partition
One of the candidates was a Dell PC and I wanted to preserve the Dell Diagnostics partition, partly because it is a good thing to have and partly – as I mentioned above – to keep my partition numbering consistent between the old and the new drives (which saves a bunch of trouble). I did this by using the gparted utility to create a new partition on the new disk, similar in size to the original (but rounded up to an even cylinder boundary) with a system ID of ‘de’ (copied from the original). Then I simply did a “dump” sector-by-sector copy of the diagnostics partition from the old to the new:-
# dd if=/dev/sda1 of=/dev/sdb1 bs=32768
This worked a treat. I could then recreate my NTFS partition (again using gparted) as the second partition on the drive. It may seem that this rather wastes the effort of partitioning the disk in Step 1 above, but by doing it this way the standard Microsoft boot code is installed in the MBR. Of course, there are lots of other ways the same thing could be achieved, such as copying the MBR from the original disk to the new disk using the command
# dd if=/dev/sda of=/dev/sdb bs=512 count=1
…and then using gparted to resize the partitions accordingly. Either way, be very careful. If you manage to zap the partition table on your original disk at this stage you are going to have a seriously bad day !
The fun isn’t over yet…see below !
Step 5 – Clone the NTFS parition
The next step is to clone the contents of the old NTFS partition into the new one. This is done using the aptly-named ntflsclone command:-
# ntfsclone -O /dev/sdb2 /dev/sda2
In this form, the command clones /dev/sda2 to /dev/sdb2. Once again, be careful. This command doesn’t ask for any confirmation and if you get your partitions mixed up (e.g. specify them the wrong way around) it will hurt.
Step 6 – Resize the partition
At this point, all of the data is copied from the old disk to the new disk, but the filesystem on the new disk still “thinks” it is the same size as it was on the old disk. If you just reboot at this point you will find – to your dismay – that the new filesystem is no bigger than the old one, even though the partition containing the filesystem is bigger.
To fix this, we run ntfsresize on the new partition
# ntfsresize /dev/sdb2
Step 7 – Fix the number of “hidden sectors” in the NTFS Boot Sector
If the new NTFS partition doesn’t start on the same sector number as the old one, you will need to adjust the number of “hidden sectors” recorded at offset 0x1C in the NTFS boot sector.
TODO: Describe using “hexedit” to complete this job
I did it a different way (kind of by accident). I wound up booting from the Windows Vista installation DVD and selecting “Repair”. This located and repaired the incorrect boot sector for me automatically.
Step 8 – Insert the new disk and reboot
All going well, it will boot up exactly as before – except possibly faster – and you will miraculously have lots of available space
Step 9 – Defragment
If your original disk was heavily fragmented (which it probably was if you were running close to capacity for a good while), then the copy is still heavily fragmented. Now would be an excellent time to defragment the new partition.
In the course of my research I came across a promising tool called XXCLONE. This works a different way, being file-oriented rather than sector/block-oriented. Apparently, it copies individual files from the old to the new. As an experiment, I cloned one of the PCs using this tool rather than using the procedure described above. Initially all seemed well…I could boot from it and everything appeared to work OK. However, a few days later I was trying to install Microsoft.NET Framework 3.5 and found that it simply would not install. I can’t be certain that the problem was with the method used to clone the disk, but when I went back and recloned using the Linux tools I could then install the same .NET Framework without any problems. If the problem was caused by XXCLONE it is a pity…it is very elegant and simple to use. I have sent some feedback to the developers…hopefully it will be helpful to them.
I can’t claim to have worked all of this out from scratch by myself. The most useful online guide I found was Michael Dominok’s at http://www.dominok.net/en/it/en.it.clonexp.html.
Imagine my dismay when my new, fast-everything-dual-core-with-tons-of-RAM PC suddenly started running at around 50% CPU utilisation more-or-less constantly, even when it wasn’t supposed to be doing anything. You just don’t have these problems with Linux . Anyway so began the detective-work.
Most of the CPU utilisation appears to be Kernel-space:-
The obvious place to start is to find out which process(es) are doing the damage:-
Pretty consistently the culprit seems to be svchost with a process ID of 1468…it is running steadily at around 50%.
So what is it doing ? Microsoft’s Knowledgebase article 314056 says:-
The Svchost.exe file is located in the %SystemRoot%\System32 folder. At startup, Svchost.exe checks the services part of the registry to construct a list of services that it must load. Multiple instances of Svchost.exe can run at the same time. Each Svchost.exe session can contain a grouping of services. Therefore, separate services can run, depending on how and where Svchost.exe is started. This grouping of services permits better control and easier debugging.
Easier debugging my ass. Anyway, it goes on to give some information about how to find out what this particular instance of svchost is doing. The command:-
tasklist /svc /fi "pid eq 1468"
shows exactly which services are running under this particular process ID:-
So it only remains to figure out which of these services has gone awry. A little bit of guesswork comes in here, matching the abbreviated names from the output above to services. This isn’t too difficult. All I had to do was stop the services listed one-by-one until the CPU utilisation dropped to zero. At it turned out, the culprit was the “TapiSrv”, the Telephony service. This wouldn’t stop when I asked politely (which was a bad sign all by itself) and when it was the only one remaining the CPU utilisation was still at 50%. When I forcibly killed the svchost process from Task Manager the CPU utilisation finally dropped to 0%.
Hindsight is wonderful. It turned out that the reason the Telephony service wouldn’t stop was because it depended on the Fax service and it was the Fax service that was really stuck. Once I had figured that out it dawned on me that the problem began around the time I was (unsuccessfully) trying to send a Fax to my bank to berate them for their stupidity (but that’s a whole other blog entry). I have worked around the problem for the moment by disabling the Fax service and all is well again (by Windows standards, at any rate). I haven’t yet got around to working out what is wrong with the Fax service (the urgency has passed…I found another way to beat up the bank !)