disklabel cross-platform compatability ideas...
So, I recently set up an alpha box running freebsd (first time for
everything) - not too painful. Are there any web resources to refer to in
relation to the quirks and differences of the alpha port?
After doing all of my 'normal' fiddling with a new box I attached an
external disk case with two 9G viking II disks in it. The alpha box
replaced an ia32 box as a server in my home, and the disks had ufs
partitions on them.
Turns you, and most of you probably already know this, that because of
partition table location differences between alpha and ia32 I couldn't
mount the disks. The disk label seemed to be invalid. It seems like
there must be more than just me that are affected by this problem.
Google found a conversation from 98 or so about this exact issue and a bit
of code-digging put me squarely in /usr/src/sys/ufs/ufs/ufs_disksubr.c in
the function readdisklabel().
It appears that a single sector is read off the disk, which should have
the label in it (which sector is controlled by LABELSECTOR which works out
to be 0 for ia32 and 1 for alpha). The code works its way through the
resulting data looking for a valid table every sizeof(long) bytes. If it
finds the right magic numbers, it does a bit of further sanity-checking
and then returns that data as the disklabel.
The problem here is that on ia32 we read only sector 0, on alpha sector 1.
If I wanted a 'readdisklabel()' that was cross-platform compatable, then
I'd either have to put a second code-block in, after sector 0 was checked,
then sector 1 could be checked etc...
As a quick hack to see if this worked, I merely doubled the size of the
buffer, read 2 sectors, starting at 0, and then let the rest of the code
work like normal.
I was able to mount and use my disks that were ia32-labeled. (shortly
after this, while moving data from one drive to the other, I toasted the
power-supply on the disk-enclosure - growl - one of the disks was hosed
beyond all recognition and the other one is still working fine days later
- fortunately this was my staging area for spooling stuff to tape and I
had most stuff on tape in one form or another...)
The diffs for 4.5-R are (approximately)
< bp = geteblk((int)lp->d_secsize*2);
> bp = geteblk((int)lp->d_secsize);
< bp->b_blkno = 0 * ((int)lp->d_secsize/DEV_BSIZE);
> bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE);
< lp->d_secsize*2 - sizeof(*dlp));
> lp->d_secsize - sizeof(*dlp));
Note that I'm not suggesting we actually make this change in the code as
it is kind of ugly - it has a magic number, and now, instead of having
cross-platform code, we have code dependent on the specific implementation
of two platforms (ie it depends on ia32 table at sec 0 and alpha table
at sec 1)...
The above code 'works for me' and it meets my 'minimum-change' requirement
for personal-local patches to keep reapplying.
Would there be a better way to do this? one that would be worth commiting?
I'm willing to do some work on this to clean things up and make something
more proper but with the current mechanism in the code there doesn't
appear to be a 'right' way to do things :). Also, I guess the 'right' way
to do things would be to put -current on the box, make the changes w.r.t
current and then get someone to MFC? That isn't a really pratical
approach for me since harmony in my home is somewhat affected by hosing
the print-server and I dont really want to take the box down again while I
reinstall it's os...
Oh, and this doesn't take care of label writing either, but that code
looks less fun to munge, and has it's own issues already.
I know there are other efforts out there to port FreeBSD to different
platforms -- how is this type of thing handled there? Should any possible
solution include more than just alpha and ia32?
Fred Clift - fclift@xxxxxxxxx -- Remember: If brute
force doesn't work, you're just not using enough.
To Unsubscribe: send mail to majordomo@xxxxxxxxxxx
with "unsubscribe freebsd-alpha" in the body of the message