Encapsulate the storage metadata and add support for blockSD

This creates an encapsulation class that is responsible for
creation and usage of storage metadata directory.

It allows to specify arbitrary number of services and then
initializes the proper files and mappings for the broker
to use them.

The example usage is:

b = FilesystemBackend("uuid-of-the-storage-domain", "nfs")
b.create({
  "hosted-engine.lockspace": 1048576,
  "hosted-engine.metadata": 1048576
})
b.connect()

Supported storage types are: nfs, block and glusterfs

The type serves only as a hint, the storage domain has to exist
and be already connected for the above to work. The class does
autodetection of the SD type in all cases except glusterSD.

To force a clean metadata files pass force_new=True argument
to the create call.

Change-Id: Iaced4ac08936fc9314ff821343ce33d29a5897cf
Signed-off-by: Martin Sivak <msivak@redhat.com>
Add metadata storage support for raw block device

This adds support for using raw partition or drive as the metadata
storage device. It implements partitioning schema to support
multiple metadata files and also allows for future extension.

Once the backend is connected to, it uses device mapper interface
to create the devices for all registered metadata files.

The underlying block device uses the following block based
structure. The first block on the device is meta block.

Each meta block (512B) contains:

4B signature (HEs0)
8B index of next meta block or 0 if this is the last one
64 bytes with service name (first byte equals the used length)
8B + 8B pointers to data section (start block, length)
... more data sections if needed
16B of 0 acting as a sentinel
4B CRC32 checksum

If there is need to use lots of data sections for a single service,
is is possible tp use the service name multiple times and the data
blocks will be concatenated using device mapper.

Change-Id: Id6ab21fb2075fc59b444b5754ade8a1569b83b18
Signed-off-by: Martin Sivak <msivak@redhat.com>