Subject: Re: Any disklabel experts out there?
To: Hisashi T Fujinaka <htodd@twofifty.com>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: port-i386
Date: 05/25/2002 16:19:49
--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, May 22, 2002 at 11:19:11PM -0700, Hisashi T Fujinaka wrote:
> I was moving disks and using partition magic, and I deleted my partition
> table. And my disk label.
> 
> The data, I'm pretty sure, is still there. There's a win98 partition still
> alive, and the netbsd stuff is hidden behind it. I figured (incorrectly)
> that everything was standard, so if I just did a sysinstall with a
> "preserve," I would have my correct disklabel back. Nope. Bad magic number
> in the superblock. I must be off on my offsets.
> 
> Anyone have any hints for me? There's only one program I really need off
> the disk (the perl program I was writing.)
> 
> Oh, I need to figure out how to rsync to my solaris box (the only one
> which has a daily backup program.)

You can find supeblocks by scanning the disk looking for the magic
number: 0x011954 (in a u_int32_t)
The small attached program will look for this magic number, and print infos
about the (supposed superblock). Of course there's a lot of flase positive,
and it will also print alternate superblocks. Usage: ./lookforfs /dev/wd0d
(better use the block device, it's much faster).
One you have the offset of the first superblock of the filesystem you
can create a entry in disklabel. It may not be the offset returnedby the
program; superblocks may be at some offset from the start of the partition.
For example, on my i386, the program gave offset 7968255 for my /
when the partition starts at 7968240 (so the superblock is at an offset
of 15 sectors for i386).

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 23 ans d'experience feront toujours la difference
--

--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="lookforfs.c"

#include <fcntl.h>
#include <unistd.h>
#include <sys/param.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>

main(int argc, char **argv)
{
	static char buf[2048];
	struct fs *fs;
	int fd;
	u_int64_t i;
	int j;

	fd = open(argv[1], O_RDONLY, 0);
	if (fd < 0) {
		perror("open");
		exit(1);
	}
	for (i = 0;;i++) {
		if (lseek(fd, i * 512, SEEK_SET) < 0) {
			perror("seek");
			exit(1);
		}
		if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
			perror("read");
			exit(1);
		}
		for (j = 0; j < sizeof(buf) - sizeof(struct fs); j+=4) {
			fs = (struct fs*)&buf[j];
			if (fs->fs_magic == FS_MAGIC) {
				printf("superblock in sector %qd:", i);
				printf("%u blocks, last mounted on %s\n",
				    fs->fs_size, fs->fs_fsmnt);
			}
		}
	}
	exit(0);
}

--jI8keyz6grp/JLjh--