Subject: Re: libahdi [Re: CVS commit: basesrc]
To: NetBSD tech-userlevel mailing list <>
From: Julian Coleman <>
List: tech-userlevel
Date: 02/13/2000 18:41:23
Jason Thorpe wrote:
> I think what we want here is some sort of "disklabel handle", where you
> open some device with a partition scheme name, i.e.:
>         struct disklabel_handle *h;
>         h = disklabel_open("sd0", "ahdi"); 
>         disklabel_read(h, ...);
>         disklabel_write(h, ...);

Do you mean something like :

  struct disklabel_handle {
	int (*reading_routine) (...);
	int (*writing_routine) (...);
	int (*check_consistency_routine) (...);
	int (*convert_to_struct_disklabel) (...);
	int (*convert_from_struct_disklabel) (...);

?  Then the functions :

  nativelabel_read (h.reading_routine, ...);
  nativelabel_write (h.writing_routine, ...);
  nativelabel_check (h.check_consistency_routine, ...);
  native_to_disklabel (h.convert_to_struct_disklabel, ...);
  disklabel_to_native (h.convert_from_struct_disklabel, ...);
  update_incore (struct disklabel);
  write_disktab (struct disklabel);

der Mouse wrote:
> Or are you talking about the fact that on some ports, native labels
> aren't the same as NetBSD labels?

Yes.  And in some cases (e.g. Atari), you'll need to parse the native label
before you can parse the NetBSD label.  In the Atari case, the NetBSD label
is stored at the beginning of the first NetBSD partition (there's no room
in the native label).  Then again, maybe you want to read a native label
where there is no NetBSD label on the disk.

> The major problem I see with this is that some ports' native labels
> contain information (such as partition names) that cannot be
> represented in a struct disklabel.

Yes.  This is especially important if you want to edit the native label.
As this was the original goal of libahdi, I don't want to lose this
functionality.  So, it would be nice if 'native' tools can also use the
library, e.g. editahdi, editmbr, sysinst.

> What's the "root sector"?  Perhaps some of the more elaborate native
> disklabel formats keep a per-partition info sector, but this should be
> hidden by that port's read/write functions, no?  Certainly all the
> label formats I'm familiar with (which admittedly isn't that many) keep
> the entire label, including all the partition info, in a single sector.

The Atari partitioning format only has room for 4 partitions in the area
reserved at the start of the disk.  In order to support more partitions,
one of these can be a 'pointer' to another disk (root) sector that contains
the information about another partition (and possibly another 'pointer').

> I'm not entirely sure why there have to be header files describing the
> various label formats.  After all, nobody but libdisklabel is ever
> supposed to be messing with them, right?

At the moment, ports have MD (e.g. sys/arch/atari/include/disklabel.h) and
MI (e.g. sys/sys/disklabel_mbr.h) headers describing their label formats.
If there is a library to manipulate these labels, it seemed sensible to me
to make all the header files MI.  That might also mean they need to be
modified for endianness and data sizes considerations.

> As for Suns, well, I've got 16-partition disks on /sparc and /sun3
> already.

Is this compatible with native Sun disklabels?  BTW, I seem to remember a
proposal to move all ports to a common format (slices?) ...

> >   Data sizes
> >     All data sizes must be explicitly specified.
> Only if there are structs describing "foreign" on-disk data structures
> (often a bad idea anyway, if only for endianness reasons).

But, see above.  I think the same struct should be able to describe one
ports on-disk data structure for all ports.

> >   Endian
> >     The routines must be endian-independent.

> some sense.  For example, I think Sun labels are always
> big-endian (does anyone happen to know what the RoadRunner did for disk
> labels?).

I really meant that the routines need to know the endianness of the native
label and the port reading the label.  So, the code will need to convert the
on-disk data structures to the local endianness (if different).

> SWAP_PART?  I don't recall seeing that anywhere.  Siccing grep on the
> kernel source tree makes it look like a mac68k-specific thing; it's
> defined in sys/arch/mac68k/mac68k/disksubr.c (along with a bunch of
> other _PART defines) and as far as I can see nowhere else.

Well, I've just added it to the Atari headers, as the both the kernel and
libahdi use it.  Previously, only the kernel used it, so there was no need
to have it in a header file.

> I think it is likely to be.  Let's suppose, arguendo, that a new port,
> NetBSD/foobox, is added.  The FooBox native scheme uses partition 0 as
> the "whole disk" partition, so NetBSD/foobox defines RAW_PART as 0.
> Now I take my Sun disk and put it on my NetBSD/foobox machine. What
> happens?  Is Sun partition a inaccessible?  Or is the Sun RAW_PART of 2
> mapped to the FooBox RAW_PART of 0, shuffling partitions 0, 1, and 2 to
> make up for the difference?  Or what?

Yes ... I'm still not sure what to do about this.  If we want the same
headers to be used for all ports, how do we handle multiple different
definitions, all currently called RAW_PART?  Perhaps the the value of
RAW_PART can go in the disklabel handle?  Then it'll be defined in both
the MD header and also the libdisklabel header ...  Or, maybe they could
all be renamed RAW_PORT_XXX, where XXX is port/disktype/???.

> True, but not of that much code.  There are only a handful of places
> that are affected: disklabel, mbrlabel (which presumably would turn
> into a more generic program using libdisklabel), and possibly the
> label-reading code for the various ports...anything else?

As I was thinking of modifying the MI header files, I thought there might
be quite a shake up required ...

Manuel Bouyer wrote:
> No, just return a 'struct disklabel *'. The calling program can stick it in
> the in-core label if it's his putpose, but we may need a struct disklabel *
> for other purposes.

Agreed.  Something like the *convert_to_struct_disklabel() and
native_to_disklabel() above?

> I think we need a separate data type for each native partition. Your
> structure doesn't work well for MS-DOS partitions for example (we
> need start sector, size and start c/h/s , size c/h/s, partition type and 
> eventually addidtionnal opaque data for this partition, in case it's an
> extended partition, or a FreeBSD slice).

Um, why do you need start c/h/s and size c/h/s?  Can you not calculate them
from a single c/h/s and the values for start sector and size?  (Sorry if I'm
missing something obvious.)  The Atari also uses a partition 'type' - a
3 byte partition id.  Presumably not compatible with the DOS partition type?

> Maybe some common parts can be extracted and the rest be put in a void *.

Yes.  Alternatively, all the functions take a union of the various types ...

> At this point I think we have to handle the max number of partitions possible.
> It's hup to the calling program to truncate it if needed.

There is the definition MAXMAXPARTITIONS.  The code could use that.  Or use
the same solution to handle multiple definitions of RAW_PART ...

Hope I haven't missed anything out ...


                    My other computer also runs NetBSD