[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

Reply via email to