[crossposted to -hackers in a hope to have more information, sorry if
this is inappropriate]
Hi.
I'm currently working a bit on libh, which includes a libhdisk library
to interface libdisk(3), newfs, etc, in short, a interface to operate
disk partition/slice edition à la sysinstall.
The thing is that I'm trying to figure out how all this stuff works.
libdisk(3) is not very informative, in fact, it doesn't document
anything below the "slice" level (FS_SWAP macro and structure of a
Disk/Chunk tree, for example).
I made a little graphic (ASCII!) to show how such a tree (Disk/Chunk) is
made, along with an algorithm from sysinstall's label.c that extract
relevant data out of it.
I will make documentation for the Disk/Chunk class hierarchy and
functions, and that will imply investigating libdisk's functions.
I think libdisk(3) should be split and rewrote. Anyways, isn't it policy
to have *functions* instead of *libraries* documented in manpages? :)
The thing is that I might not be the best person to do it, and I do not
understand everything clearly yet. If anyone has any other source of
information (apart from source code), please share. :) I will probably
end up posting prs about libdisk's doc...
One thing I haven't figured out yet is why there is an intermediate
"Chunk" between Disk and slices (see picture, the first chunk on the
right of the Disk box).
I think the graphic is quite good, and should be included somewhere, for
reference because it took me a while to figure it out.
A.
We have the structures:
+--------+ +-------+
| Disk | | Chunk |
| | | | This chunk represents the disk in itself
| chunks--->| part |
+--------+ +--|----+
|
+--------------|---------------------------+
|Slices (e.g. | freebsd, linux, dos) |
| V |
| +-----------+ +-----------+ |
| | Chunk | | Chunk | |
| | | | | |
| | type=fbsd | | type=fat | |
| | | | | |
| | part next----->| part next----> ... |
| | | | | | | |
| +--|--------+ +---|-------+ |
| | ? |
+------|-----------------------------------+
|
+------|-----------------------------------+
|Partitions (eg. fs, swap) |
| V |
| +--------------+ +--------+ |
| | Chunk | | Chunk | |
| | | | | |
| | type=part | | ... | |
| | | | | |
| | next----->| next----> ... |
| | | | | |
| | subtype=swap | | ... | |
| | | | | |
| +--------------+ +--------+ |
| |
+------------------------------------------+
/* All the chunks currently displayed on the screen */
static struct {
struct chunk *c;
PartType type;
} label_chunk_info[MAX_CHUNKS + 1];
/* this function flattens such a tree in a single array */
static void
record_label_chunks(Device **devs, Device *dev)
{
int i, j, p;
struct chunk *c1, *c2;
Disk *d;
j = p = 0;
/* First buzz through and pick up the FreeBSD slices */
for (i = 0; devs[i]; i++) {
if ((dev && devs[i] != dev) || !devs[i]->enabled)
continue;
d = (Disk *)devs[i]->private;
if (!d->chunks)
msgFatal("No chunk list found for %s!", d->name);
/* Put the slice entries first */
for (c1 = d->chunks->part; c1; c1 = c1->next) {
if (c1->type == freebsd) {
label_chunk_info[j].type = PART_SLICE;
label_chunk_info[j].c = c1;
++j;
}
}
}
/* Now run through again and get the FreeBSD partition entries */
for (i = 0; devs[i]; i++) {
if (!devs[i]->enabled)
continue;
d = (Disk *)devs[i]->private;
/* Then buzz through and pick up the partitions */
for (c1 = d->chunks->part; c1; c1 = c1->next) {
if (c1->type == freebsd) {
for (c2 = c1->part; c2; c2 = c2->next) {
if (c2->type == part) {
if (c2->subtype == FS_SWAP)
label_chunk_info[j].type = PART_SWAP;
else
label_chunk_info[j].type = PART_FILESYSTEM;
label_chunk_info[j].c = c2;
++j;
}
}
}
else if (c1->type == fat) {
label_chunk_info[j].type = PART_FAT;
label_chunk_info[j].c = c1;
++j;
}
}
}
label_chunk_info[j].c = NULL;
if (here >= j) {
here = j ? j - 1 : 0;
}
}
PGP signature