Hi,

after the announcement of my ideas for a Storage Redesign in YaST I present
now the first draft of the API that libstorage will provide. Remember that
this API should be used by all YaST modules using functions from yast2-storage
so far since the infamous target map will vanish.


Device Graph
------------

The basic data structure is a directed graph of device objects as already
explained (https://github.com/aschnell/libstorage-bgl-eval/wiki). Compared to
the target map there are a few new objects, e.g. PartitionTable, Encryption
and Filesystem.


How to get a Device Graph
-------------------------

Libstorage works with several device graphs, mainly the "probed" and the
"current". Somehow you will have access to the main storage objects and can
use that to get a device graph:

  DeviceGraph* device_graph = storage->getCurrent();


Manipulating the Device Graph
-----------------------------

There are "constructors" for all concrete objects (e.g. Ext4 and Swap are
concrete while Filesystem is abstract).

    Disk* sda = Disk::create(device_graph, "/dev/sda");

The device_graph is the owner of the objects. Creating disks will of course
only be allowed in the image/KIWI mode.

Most objects will be created by calling member functions of the parent:

    PartitionTable* gpt = sda->createPartitionTable(GPT);
  
    Partition* sda1 = gpt->createPartition("/dev/sda1");  // parameter will 
change

Manipulating is done with member functions, e.g.:

    filesystem->addMountPoint("/boot");

There is also a low level interface where the vertices and edges of the graph
are manipulated directly, e.g.:
  
    PartitionTable* gpt = Gpt::create(device_graph);   // creates vertex
    Using::create(device_graph, sda, gpt);             // creates edge

    Partition* sda1 = Partition::create("/dev/sda1");  // creates vertex
    Subdevice::create(device_graph, gpt, sda1);        // creates edge

But this low level interface should be reserved for the expert partitioner if
needed at all.


Querying the Device Graph
-------------------------

Generic functions to query relatives of a device:

    vector<Device*> children = device->getChildren();

Here getChildren, getParents, getSiblings, getDescendants, getAncestors,
getLeafs and getRoots is available.

Special functions to query relatives of a device, e.g. the partitions of a
partition table:

    vector<Partition*> partitions = gpt->getPartitions();

Functions to find specific devices, e.g. filesystems by mount point:

    Filesystem::findByMountPoint(device_graph, "/boot");

Combining query functions in a complex example: Suppose the bootloader has to
know whether the device mounted at "/" uses a LVM logical volume:

    for (const Filesystem* filesystem : 
Filesystem::findByMountPoint(device_graph, "/"))
    {
        for (const Device* device : filesystem->getAncestors(false))
        {
            if (dynamic_cast<const LvmLv*>(device))
                cout << "mount point \"/\" somehow uses a logical volume" << 
endl;
        }
    }

    
https://github.com/aschnell/libstorage-bgl-eval/blob/master/examples/find1.cc


Bindings
--------

I have swig generated bindings for Ruby, Python and Perl5. The repository
contains a few examples for each of them:

https://github.com/aschnell/libstorage-bgl-eval/tree/master/bindings


Help
----

The Makefile.am for Perl bindings needs improvement and the bindings should
get a tiny testsuite.


RFC
---

If you see problems with this API for your module, generally miss something or
have ideas for improvement please comment now.


ciao
  Arvin

-- 
Arvin Schnell, <[email protected]>
Senior Software Engineer, Research & Development
SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 21284 
(AG Nürnberg)
Maxfeldstraße 5
90409 Nürnberg
Germany
-- 
To unsubscribe, e-mail: [email protected]
To contact the owner, e-mail: [email protected]

Reply via email to