Jump to content

Migrating Windows Between Disks


incripshin
 Share

Recommended Posts

SOLVED See my third comment. I don't know if it's possible to change the topic title, so I am just adding this note here.

ONLY SORT OF Apparently I can boot, but it still doesn't work for shit. See last message. I have had it with this.

I recently bought a new hard disk and I was having trouble transferring my Windows 7 partition, and I don't know what I'm missing. The trouble is that it won't boot, though I got all the data across fine (seemingly). When I select Windows in GRUB, it just hangs. The steps I took were pretty simple:

1) use Linux fdisk to create a larger partition on the target disk, setting partition ID to HPFS/NTFS and enabling the boot flag

2) the following (sda: target, sdb: source) from a Gparted live disk (Anglican spelling; deal with it):

# ntfsclone --overwrite /dev/sda1 /dev/sdb1
# ntfsresize /dev/sda1

I also tried using dd the first time.

3) install grub on /dev/sda with same configuration

4) attempt repair with Windows 7 install disk; nothing doing

And that's it. /dev/sdb1 is 75 GB while /dev/sda1 is 100 GB. Mounting /dev/sda1 shows that it did resize the filesystem to fill the partition:

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
...
/dev/sda1            104857596  60125040  44732556  58% /media/c
...

Here are relevant excerpts from fdisk:

# fdisk -l /dev/sda
Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00008f19

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1       13055   104857600    7  HPFS/NTFS
...

# fdisk -l /dev/sdb
Disk /dev/sdb: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
...
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *           1        9791    78646176    7  HPFS/NTFS
...

(Yeah, it's a minor upgrade, but I also have another computer which could really use the 466 GB drive). Here's my grub config, but there's nothing strange about it; I'm just trying to head off a request for it:

default 0
timeout 8

title Gentoo Linux
root (hd0,1)
kernel /boot/vmlinuz ro root=/dev/sda2 vga=794 splash=verbose,theme:livecd-2007.0 fbcon=scrollback:128K

title Windows 7 Professional
rootnoverify (hd0,0)
chainloader +1

Edited by incripshin
Link to comment
Share on other sites

Is it just windows that GRUB doesn't boot or does it fail on Linux as well?

Looking at the man page for ntfs-clone shows that you may not be able to get windows booting easily on the new disk.

Windows Cloning

If you want to copy, move or restore a system or boot partition to another computer, or to a different disk or partition (e.g. hda1->hda2, hda1->hdb1 or to a different disk sector offset) then you will need to take extra care.

Usually, Windows will not be able to boot, unless you copy, move or restore NTFS to the same partition which starts at the same sector on the same type of disk having the same BIOS legacy cylinder setting as the original partition and disk had.

The ntfsclone utility guarantees to make an exact copy of NTFS but it won't deal with booting issues. This is by design: ntfsclone is a filesystem, not system utility. Its aim is only NTFS cloning, not Windows cloning. Hereby ntfsclone can be used as a very fast and reliable build block for Windows clonning but itself it's not enough. You can find useful tips following the related links on the below page

http://wiki.linux-ntfs.org/doku.php?id=ntfsclone

Edited by Jason Cooper
Link to comment
Share on other sites

I think you should look into hard drive imaging software. That's the only way of making an exact image of an hard drive and have it uploaded onto another hard drive.

Link to comment
Share on other sites

I copied my win vista installation a year age to a bigger disk. I used CloneZilla -linux to copy that partition. then used gparted to make partition bigger. It worked well even for a person who hasn't used linux before it. Now my only os is Ubuntu...

Link to comment
Share on other sites

1) screw imaging software

2) dd had the same trouble

3) I have a solution, and I will post it when I get more time. Basically, the partitions had different starting sectors (63 vs 2048) and this is written in the NTFS superblock. gotta go.

PCHOOOOO

Link to comment
Share on other sites

And now for a less hasty message. Thanks, all, for your responses. I usually tend to deal with terrible problems with terrible solutions, but I was still happy not to hear an echo. First some individual problems, then my solution:

Thanks Jason for that first nice reply. Grub looked like it was doing its job properly, but Windows didn't show even the smallest hint of starting. I saw that part of the man page shortly after I made the topic. Why do they have to be so vague about it, really?

I prefer to use open source software whenever possible. And look, paying for packaged software is not 'the only way of making an exact image'. I mean, dd makes an 'exact' image. I also used xfs_dump to transfer my Linux partitions. Does any packaged software give a shit about xfs? It isn't made for people like me.

I don't know if dd would have worked, but ntfsclone is at least as good (i.e. it may handle the migration better than dd). It will also allow you to create images of partitions that aren't sector-for-sector copies, which is what you want a lot of the time.

I am swapping out disks because I want to, really. The specifics is that I give system Alpha the metric terabyte disk, move the 466 GB drive from Alpha to Beta, and move that 186 GB drive from Beta to Alpha.

Now for the new steps, step 4 being the magic part:

1) Create partition on new disk that is at least as large as the old (at least as many sectors and cylinders, I don't know which).

2) Clone (sdb1 -> sda1)

# ntfsclone --overwrite /dev/sda1 /dev/sdb1

3) Enlarge

# ntfsresize /dev/sda1

4) Reset the filesystem start sector (http://osdir.com/ml/linux.file-systems.ntfs.devel/2006-09/msg00073.html; also pasted at the end of this reply to ensure this wonderful program's survival)

# ./relocntfs /dev/sda1 # just show what would happen
NTFS Start Sector:
partition=2048
filesystem=63
# ./relocntfs -w /dev/sda1 # make the change
NTFS Start Sector:
partition=2048
filesystem=63
Filesystem start sector altered to 2048

5) Install bootloader (you can dd this if you don't use Grub; I installed Grub by booting with the Gentoo install disk, chrooting, using the 'grub' CLI)

6) Use Windows again and despair.

I should also mention that at no point after (2) should you run the Windows startup repair with both disks plugged in. I think this is what caused my migrated Windows to switch to F: and refuse to start; this was after I ran relocntfs, and I just ended up going back to step (1).

Now excuse me while I write a love letter to relocntfs' author :).

Here's the relocntfs source:

/*
relocntfs - deals with braindeadness with moving NTFS filesystems.

Copyright (C) 2006  Daniel J. Grace

I don't claim any major knowledge of the NTFS filesystem.
This program is merely an implementation of the process documented at
Michael Dominok's website: <http://www.dominok.net/en/it/en.it.clonexp.html>

Like any other program that tinkers with the contents of your HD, this
program may cause data corruption. USE AT YOUR OWN RISK. You have been warned.



This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <linux/hdreg.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

unsigned long fliplong(unsigned long v) {
	/* Flip a long value -- if the architecture depends on it */
	unsigned long rv;
	char buf[4], t;
	int iter;

	/* Determine system architecture */
	rv = 1;
	memcpy(&buf, &rv, 1);

	if(buf[0]) return v;


	/* If we reach here, byte-swapping is neccessary */
	memcpy(&buf, &v, 4);
	for(iter = 0 ; iter < 2 ; ++iter) {
		t = buf[iter];
		buf[iter] = buf[3-iter];
		buf[3-iter] = t;
	}
	memcpy(&rv, &buf, 4);

	return rv;
}

int usage(char *progname) {
	fprintf(stderr, 
		"ntfsreloc - adjust filesystem start sector of an NTFS partition"
		"\nUsage: %s [-s start] [-w] [-b] [-f] device"
		"\nwhere device points to an NTFS partition"
		"\n"
		"\nOptions:"
		"\n-w\n\tWrite new start sector to the partition."
		"\n-s start\n\tNew start sector to write.  If omitted, determined via ioctl."
		"\n\tMust be specified if -b option is used."
		"\n-b\n\tProceed even if the specified device is not a partition (e.g. a"
		"\n-b\n\tregular file)"
		"\n-f\n\tForce the operation to occur even if device does not look like a valid"
		"\n\tNTFS partition."
		"\n"
		"\nThis utility displays the current starting sector as defined by the"
		"\nthe filesystem.  No change will actually be made without the -w"
		"\noption."
		"\n"
		"\nExit status is 2 if an error occured, 1 if a change was made or is needed"
		"\nor 0 if the filesystem already has the correct values."
		"\n", progname
	);
	return 0;
}

char *optDeviceName = NULL;
int device = 0;

char optSpecifyStartSector = 0, optWrite = 0, optPrint = 0, optBlock = 0, optForce = 0;

unsigned long optStartSector = 0, geomStartSector = 0, useStartSector = 0, fsStartSector = 0;

char haveGeomStartSector = 0;

int main(int argc, char **argv) {
	int i;
	int readopts = 1;

	if(argc <= 1) {
		usage(argv[0]);
	}

	for(i = 1 ; i < argc ; ++i) {
		if(argv[i][0] == '-' && readopts) { 
			/* -s is special */
			if(argv[i][1] == 's') {
				optSpecifyStartSector = 1;

				char *sizePtr, *endPtr;
				if(argv[i][2]) {
					sizePtr = &argv[i][2];
				} else if(i+1 < argc) {
					sizePtr = argv[++i];
				} else {
					fprintf(stderr, "ERROR: Size must be specified for option -s\n");
					usage(argv[0]);
					return 1;
				}

				optStartSector = strtoul(sizePtr, &endPtr, 10);
				if(endPtr == sizePtr || *endPtr) {
					fprintf(stderr, "ERROR: Invalid size specified for option -s\n");
					usage(argv[0]);
					return 1;
				}
				continue;
			}

			if(argv[i][1] && argv[i][2]) {
				fprintf(stderr, "Unknown option '%s'\n", argv[i]);
				usage(argv[0]);
				return 1;
			}

			switch(argv[i][1]) {
				case '-': readopts = 0; break;
				case 'w': optWrite = 1; break;
				case 'p': optPrint = 1; break;
				case 'f': optForce = 1; break;
				case 'b': optBlock = 1; break;
				default:
					fprintf(stderr, "Unknown option '%s'\n", argv[i]);
					usage(argv[0]);
					return 1;
			}
			continue;
		}

		/* If we reach here, we're reading a device name */
		if(optDeviceName) {
			fprintf(stderr, "Only one device may be specified\n", argv[i]);
			usage(argv[0]);
			return 1;
		}
		optDeviceName = argv[i];
	}

	if(!optDeviceName) {
		fprintf(stderr, "No device name specified\n", argv[i]);
		usage(argv[0]);
		return 1;
	}

	/* If we reach this point, we can actually do work */

	/* Verify that we can open the device in readonly mode */
	if(!(device = open(optDeviceName, (optWrite ? O_RDWR : O_RDONLY) | O_SYNC))) {
		perror("open");
		return 2;
	}

	/* Check to see if it's a partition */
	struct hd_geometry geom;
	if(ioctl(device, HDIO_GETGEO, &geom)) {
		if(!optBlock) {
			fprintf(stderr, "Failed to read disk geometry.  Perhaps this is not a partition?\n");
			fprintf(stderr, "Verify that you are using the correct device or use the -b option.\n");
			fprintf(stderr, "The exact error was:\n");
			perror("ioctl");
			return 2;
		} else if(!optSpecifyStartSector && optWrite) {
			fprintf(stderr, "Failed to read disk geometry, and -s option was not specified.\n");
			fprintf(stderr, "No update can be made without this information.\n");
			fprintf(stderr, "The exact error was:\n");
			perror("ioctl");
			return 2;
		}			
	} else {
		geomStartSector = geom.start;
		haveGeomStartSector = 1;

		if(!optForce && !geomStartSector) {
			fprintf(stderr, "This looks like an entire disk (start=0) instead of a single partition.\n");
			fprintf(stderr, "I won't modify this without the -f (force) option.\n");
			if(optWrite) {
				return 2;
			}
		}
	}

	/* Determine if it's an NTFS partition or not */
	if(lseek(device, 3L, SEEK_SET) < 0) {
		perror("lseek");
		return 2;
	}

	/* Read "NTFS" magic, or at least what should be */
	char ntfsMagic[4];
	if(read(device, &ntfsMagic, 4) != 4 || memcmp(ntfsMagic, "NTFS", 4)) {
		if(!optForce) {
			fprintf(stderr, "This device does not appear to be a real NTFS volume.\n");
			if(!optWrite) {
				return 2;
			}
		}
	}

	/* Determine partition's start sector */
	if(lseek(device, 28L, SEEK_SET) < 0) {
		perror("lseek");
		return 2;
	}

	if(read(device, &fsStartSector, 4) != 4) {
		fprintf(stderr, "Unable to read filesystem start sector.\n");
		return 2;
	}

	fsStartSector = fliplong(fsStartSector);

	printf("NTFS Start Sector:\n");
	if(haveGeomStartSector) {
		printf("partition=%lu\n", geomStartSector);
		useStartSector = geomStartSector;
	}

	if(optSpecifyStartSector) {
		printf("specified=%lu\n", optStartSector);
		useStartSector = optStartSector;
	}

	printf("filesystem=%lu\n", fsStartSector);
	if(useStartSector == fsStartSector) {
		printf("No changes are neccessary.\n");
		return 0;
	}

	if(!optWrite) return 0;
	if(lseek(device, 28L, SEEK_SET) < 0) {
		perror("lseek");
		return 2;
	}

	fsStartSector = fliplong(useStartSector);

	if(write(device, &fsStartSector, 4) != 4) {
		perror("write");
		return 2;
	}
	if(fsync(device)) {
		perror("fsync");
		return 2;
	}
	if(close(device)) {
		perror("close");
		return 2;
	}

	printf("Filesystem start sector altered to %lu\n", useStartSector);
	return 1;
}

Edited by incripshin
Link to comment
Share on other sites

I just moved a 4gb XP partition to a 16gb partition using gparted. When it booted I was getting blue screens, even though I told gparted to make the new one the bootable one. I ended up using a live disc of XP (UBCD4WIN) and one of the tools called TestDISK(I think thats what I used) to search for the drive and then rewrite the partition table info, then rebooted and it was fine. Not too fond of gparted though. Really buggy and I had to use the alt+mouse click to move the windows around since the mouse only seems to work on part of the screen area for some reason. Could just be the version of gparted I had though, as it was an ISO I had on the machine for probably at least 5 or more years or so now.

I have however used Clonezilla in the past with no major issues for image to image copying, but it doesn't do the resizing of the partition on the fly for you and you end up with an additional partition of unused space. I would prefer a tool that could do everything, such as resize, copy, and fix the boot records all in one shot(which gparted nearly did minus the boot issues) but some times you have to try multiple things, as in your case, to get the job done. Whatever, it works and that is the important thing.

I may give it another try just with the UBCD4WIN disc, since it has some disk tools on there to do it as well, but only for NTFS and FAT.

edit: Just went back and checked, and I was using gparted-livecd-0.3.3-0.iso. They are now at version 0.7.1, so maybe the newer one would have went without a hitch.

Edited by digip
Link to comment
Share on other sites

So it didn't *actually* work. Apparently I had left both disks plugged in, and the new hard drive's windows started the old hard drive's windows transparently. Just booting into the new hard drive's copy doesn't work ... the drive letter is not C: so it doesn't know what to do.

Apparently there is a builtin way to get Windows to copy itself to another disk, which I find acceptable. Unfortunately, Windows somehow borked itself ... maybe I was screwing around too much. Anyway, I will reinstall soon and make a proper backup. I don't know why I didn't do that earlier.

Can you believe all I had to do to migrate Linux was xfs_dump/dd the partitions? Man ... WAVE OF THE FUCKING FUTURE RIGHT THERE.

I will not come back to this thread ever again.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...