I played around a bit more with storages, pools and snapshots and I
arrived at one conclusion.
In my case I am talking about:
Directory pools: I am managing only this kind of pools.
qcow2 image files: They may be new and empty, populated with a fresh
guest installation or with a full lifecycle (several snapshots etc.)
I need to handle them both with copy on write and without.
These files may be everywhere in every kind of FS: NFS, on a USB stick...
The pool conception is pretty valuable, easy to use and gives the
capability of managing disk resources in a good way.
But the pool management itself is quite confusing.
To create a pool I need to call many functions in the following order:
- virStoragePoolDefineXML(): coherent with persistent domain definition, OK
- virStoragePoolBuild(): to create the proper directory, can be easily
merged in the next one function.
- virStoragePoolCreate(): coherent again with persistent domain , OK
To delete a pool:
- virStoragePoolDelete()
- virStoragePoolDestroy()
- virStoragePoolFree()
- virStoragePoolUndefine()
Too many functions, not documented at all, not coherent with domain management.
The result is confusion, if they're not called in the right order they
don't work.
The most important thing is, in my opinion, to have clear ideas
whether to manage FS resources or not.
With the virStoragePoolBuild() libvirt allows to create a new folder,
then remove it is quite complicated: even if the cleanup is made
properly (removal of all the storage files and removal of the pool in
the right way) it fails if in the directory there are still some
files.
If libvirt wants to offer the capability of manage files and
directories (as volumes and pool obviously) it must then offer a
complete and clear interface.
Really useful missing functions for example are the
virStoragePoolGetPath() and virStoragePoolLookupByPath(), I can create
the folders but then I need to track them down manually.
In this case better to leave the developer the responsibility of
creating the FS resources and just link them to the libvirt layer.
Same problems with volume management.
I ran in this really tedious issue:
I create a disk from a snapshot through qemu-img (external process) as
it is missing a libvirt feature that allows me to do so; I create it
in the pool directory but it is not tracked by the pool itself so I
need to "manually" add it through virStorageVolCreateXML().
Then, in the same directory, I copy through a UNIX terminal command
another image, again I need to run virStorageVolCreateXML() to add it
to the pool.
Now with my code I copy (I'm using python bindings so through any
python command) a third image in the pool folder; used to the two
cases I listed I run virStorageVolCreateXML(); in this case I get:
libvirtError: Storage volume not found: storage vol already exists
I spent much time figuring out the problem debugging my code and
eventually I arrived at the conclusion that was not my code creating
this problem.
In conclusion what is missing in libvirt, considering only the
directory pool management (every resource as a file or directory), is
a realisting mapping through FS objects and libvirt pointers or
resources.
In my opinion before trying to manage FS resources libvirt should be able to:
- from a (.qcow2, .img, .raw) file path ----> virStorageVolPtr and vice versa
- from a path in which is mapped a pool ----> virStoragePoolPtr and vice versa
- from a virDomainSnapshotPtr ----> virStoragePoolPtr ----> (.qcow2,
.img, .raw) file path
In a clear way and at any moment of the lifecycle of libvirt.
The FS management itself should be removed if not complete and clear,
a programmer can always prepare the resources beforehand.
If I can suggest this interface:
- virStoragePoolDefineXML(): it defines a persistent pool like a
domain. The dir path in the XML must already exist with correct
permissions.
- virStoragePoolCreate(): it creates and start the pool.
- virStoragePoolDestroy(): unlink all the volume storages, stops the
pool and keep persistent information
- virStoragePoolFree(): free the pointer
- virStoragePoolUndefine(): remove persistent information
- virStoragePoolGetPath()
- virStoragePoolLookupByPath()
For the volumes:
- virStorageVolPtr virStorageVolCreateXML(virStoragePoolPtr pool,
const char * xmldesc, virStorageVolPtr clonevol, unsigned int flags)
Creates a new storage volume according to the XML description,
clonevol is optional, if present the volume will be cloned by the
clonevol one.
- virStorageVolPtr virStorageVolAdd(virStoragePoolPtr pool, const
char * path, unsigned int flags)
Add the storage volume IF NOT ALREADY PRESENT. If it is used by other
pools or even worse: by other domains the function will fail (in the
future may be added a forcing flag).
For the snapshots:
http://www.redhat.com/archives/libvir-list/2011-June/msg00761.html