I've tried to follow as far as possible operations which are needed in order to make virt-install / virt-manager work in the remote case, and also to support discovery and creation of partitions / LVs / iSCSI LUNs.
The new API calls are: virStorageFileLocations - returns a list of locations which can be used for creating file-backed guests virStorageFileStat virStorageFileStatVFS virStorageCreateFile - for creating file-backed guest storage virStorageListGroups virStorageCreateVolume - for discovering and creating partitions, LVs, LUNs, &c. Rich. -- Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/ Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 03798903
Index: src/libvirt.c =================================================================== RCS file: /data/cvs/libvirt/src/libvirt.c,v retrieving revision 1.103 diff -u -p -r1.103 libvirt.c --- src/libvirt.c 15 Oct 2007 21:38:56 -0000 1.103 +++ src/libvirt.c 18 Oct 2007 17:03:06 -0000 @@ -3357,6 +3357,356 @@ virNetworkSetAutostart(virNetworkPtr net return -1; } +/*----------------------------------------------------------------------*/ +/* The storage API starts here. */ + +/** + * virStorageFileLocations: + * @conn: pointer to the hypervisor connection + * @len: length of array returned (OUT) + * + * Some hypervisors only allow file-backed storage in certain disk + * locations. This function returns an array of permitted locations + * (wildcards). + * + * A candidate path may be checked against the list of wildcards by + * using the POSIX.2 function fnmatch with FNM_PATHNAME flag set. + * + * Note that wildcards can describe more than just a simple + * directory (eg. "/var/lib/xen/images/xen*.img"). + * + * Returns array of 'names' on success or NULL on failure. + * + * On success, 'names' and 'len' describe an array of strings + * of length len. After use, the caller should use + * virStorageFileLocationsFree to free the array. + */ +char ** +virStorageFileLocations (virConnectPtr conn, size_t *len) +{ + DEBUG("conn=%p, len=%p", conn, len); + + /* + Implementation notes: + + /etc/libvirt/libvirt.conf contains the list of wildcards + permitted for each hypervisor. There is a default list + or the system administrator can override. + + ---- /etc/libvirt/libvirt.conf ---------- + + file_locations[xen] = [ "/var/lib/xen/images/ *.img" ] + + file_locations[qemu] = [ "/var/lib/qemu/ *" ] + # ^^ can't put / * in a C comment + -------------------- + + Although there are different paths returned for each + hypervisor type, we can centralise the code in this + function. Remote will still need to be done by the remote + driver. + */ + TODO; + return NULL; +} + +/** + * virStorageFileLocationsFree: + * @conn: pointer to the hypervisor connection + * @names: array of names + * @len: length of array + * + * Free the list of storage locations previously returned by + * virStorageFileLocations. + * + * Returns 0 on success or -1 on failure. + */ +int +virStorageFileLocationsFree (virConnectPtr conn, char **names, size_t len) +{ + int i; + DEBUG("conn=%p, names=%p, len=%zi", conn, names, len); + + if (!names) { + virLibConnError (conn, VIR_ERR_INVALID_ARG, "names"); + return -1; + } + + for (i = 0; i < len; ++i) + free (names[i]); + free (names); + return 0; +} + +/** + * virStorageFileStat: + * @conn: pointer to the hypervisor connection + * @path: pathname of file + * @statbuf: pointer to caller-allocated stat buffer (OUT) + * @size: caller should set this to sizeof(*statbuf). + * + * This does a stat or equivalent operation on the file named by + * 'path'. + * + * The hypervisor may reject the request if the file does not match + * a valid location (see virStorageFileLocations) or an acceptable + * block device name. + * + * Returns 0 if successful and the file exists ('statbuf' structure + * is filled in this case). Returns 1 if the file does not exist. + * Returns -1 if there is an error. + */ +int +virStorageFileStat (virConnectPtr conn, const char *path, + virStorageStatBufferPtr statbuf, size_t size) +{ + DEBUG("conn=%p, path=%s, statbuf=%p, size=%zu", conn, path, statbuf, size); + + /* + Implementation notes: + + Check the path against permitted locations. + + Use stat(2). + + For block devices, do an additional lseek because the + st_size field is always 0. + + virStorageStatBuffer is greatly simplified, hopefully + doesn't make any Unix assumptions. + */ + TODO; + return -1; +} + +/** + * virStorageFileStatVFS: + * @conn: pointer to the hypervisor connection + * @path: pathname of a file on the filesystem + * @statvfsbuf: pointer to caller-allocated stat buffer (OUT) + * @size: caller should set this to sizeof(*statvfsbuf). + * + * This does a statvfs or equivalent operation on the filesystem. + * You can use this to find out how much disk space is available + * for file-backed guests to use. + * + * The hypervisor may reject the request if the file does not + * match a valid location (see virStorageFileLocations). + * + * Note that this call will fail if 'path' does not exist, which + * is typically the case when you are creating a file-backed + * guest. Instead pass the parent directory name as 'path' by + * chopping off everything after the final '/' character. + * + * Returns 0 if successful ('statvfsbuf' structure is filled in). + * Returns -1 if there was an error. + */ +int +virStorageFileStatVFS (virConnectPtr conn, const char *path, + virStorageStatVFSBufferPtr statvfsbuf, size_t size) +{ + DEBUG("conn=%p, path=%s, statvfsbuf=%p, size=%zu", conn, path, statvfsbuf, size); + + /* + Implementation notes: + + Check the path against permitted locations. + + Use statvfs(2). + + virStorageStatVFSBuffer is greatly simplified, hopefully + doesn't make any Unix assumptions. + */ + TODO; + return -1; +} + +/** + * virStorageCreateFile: + * @conn: pointer to the hypervisor connection + * @path: pathname of file + * @size: size (in kilobytes) + * @flags: flags + * + * This creates an empty file which can be used as storage (a disk + * image) for file-backed guests. + * + * 'path' is the full pathname of the file. + * + * 'size' is the size to create (in KB). + * + * 'flags' is a set of flags. Currently only VIR_STORAGE_SPARSE_FILE + * is defined, which means to create a sparse file. + * + * The hypervisor may reject the file creation if the file does not + * a valid location (see virStorageFileLocations), or if the file exists + * already (see also virStorageFileStat), or if there is not enough + * disk space even in sparse mode for the full file (see also + * virStorageFileStatVFS). + * + * File creation can be a lengthy operation, and there is currently + * no way to get any updates on the progress of the operation. + * + * Returns 0 on success or -1 on failure. + */ +int +virStorageCreateFile (virConnectPtr conn, const char *path, + unsigned long long size, int flags) +{ + DEBUG("conn=%p, path=%s, size=%llu, flags=%d", conn, path, size, flags); + + /* + Implementation notes: + + Check the path against permitted locations. + + Check the file doesn't exist. + + Check enough space using statvfs. + + Create the file. + */ + TODO; + return -1; +} + +/** + * virStorageListGroups: + * @conn: pointer to the hypervisor connection + * @len: length of returned array (OUT) + * + * This lists out the available storage groups and some extra information + * about each one such as name and amount of free space. + * + * Callers can use this to present lists of available storage for + * partition-backed guests, in conjunction with the + * virStorageCreateVolume call. + * + * Returns an array of 'groups' on success or NULL on failure. + * + * On success, 'groups' and 'len' describe an array of virStorageGroupPtr + * of length len. After use, the caller should use + * virStorageListGroupsFree to free the array. + */ +virStorageGroupPtr * +virStorageListGroups (virConnectPtr conn, size_t *len) +{ + DEBUG("conn=%p, len=%p", conn, len); + + /* + Implementation notes: + + ---- /etc/libvirt/libvirt.conf ---------- + + list_groups = + "vgs --noheadings --nosuffix --units k --separator : --unbuffered | + vgs2xml" + + -------------------- + + The scriptlet will be different depending on the underlying + technology. In the instance above, it's Linux LVM & volume + groups. It might also be sfdisk (for partitions), iscsiadm + (for iSCSI), or some sort of proprietary SAN command. + + vgs2xml is a command that we supply which takes the output + of vgs and formats it to some standard XML. + + This code runs the scriptlet and parses the XML into + virStorageGroup structures. + */ + TODO; + return NULL; +} + +/** + * virStorageListGroupsFree: + * @conn: pointer to the hypervisor connection + * @groups: array of groups + * @len: length of array + * + * Free the list of groups previously returned by + * virStorageListGroups. + * + * Returns 0 on success or -1 on failure. + */ +int +virStorageListGroupsFree (virConnectPtr conn, + virStorageGroupPtr *groups, size_t len) +{ + int i; + DEBUG("conn=%p, groups=%p, len=%zu", conn, groups, len); + + if (!groups) { + virLibConnError (conn, VIR_ERR_INVALID_ARG, "groups"); + return -1; + } + + for (i = 0; i < len; ++i) { + if (groups[i]->magic != VIR_STORAGE_GROUP_MAGIC_VER1) { + virLibConnError (conn, VIR_ERR_INVALID_ARG, "group magic"); + return -1; + } + } + + for (i = 0; i < len; ++i) { + free (groups[i]->name); + free (groups[i]); + } + free (groups); + return 0; +} + +/** + * virStorageCreateVolume: + * @conn: pointer to the hypervisor connection + * @name: volume name + * @group: group name + * @size: size (in kilobytes) + * @flags: (currently unused, caller should pass 0) + * + * This allocates a partition or logical volume within the named + * volume group ('group'). + * + * Group names and available space may be found by calling + * virStorageListGroups. + * + * Returns the name (eg. device name) of the partition or volume + * if successful. The name should be freed by the caller after + * use. Returns NULL on failure. + */ +char * +virStorageCreateVolume (virConnectPtr conn, + const char *name, const char *group, + unsigned long long size, int flags) +{ + DEBUG("conn=%p, name=%s, group=%s, size=%llu, flags=%d", conn, name, group, + size, flags); + + /* + Implementation notes: + + ---- /etc/libvirt/libvirt.conf ---------- + + create_volume = + "lvcreate -L %size -n %name %group && echo /dev/%group/%name" + + -------------------- + + The scriptlet will be different depending on the underlying + technology. + + The scriptlet needs to print out the device name (if created). + + The %fields need to be quoted properly if they contain any + shell meta-characters. + + This code runs the scriptlet and returns the device name. + */ + TODO; + return NULL; +} + /* * vim: set tabstop=4: * vim: set shiftwidth=4: Index: include/libvirt/libvirt.h.in =================================================================== RCS file: /data/cvs/libvirt/include/libvirt/libvirt.h.in,v retrieving revision 1.38 diff -u -p -r1.38 libvirt.h.in --- include/libvirt/libvirt.h.in 15 Oct 2007 21:38:56 -0000 1.38 +++ include/libvirt/libvirt.h.in 18 Oct 2007 17:03:06 -0000 @@ -686,8 +686,76 @@ int virNetworkGetAutostart (virNetwork int virNetworkSetAutostart (virNetworkPtr network, int autostart); + +/* Storage structures. */ +#define VIR_STORAGE_STAT_BUFFER_TYPE_BLOCK 1 /* Block device. */ +#define VIR_STORAGE_STAT_BUFFER_TYPE_FILE 2 /* Regular file. */ +#define VIR_STORAGE_STAT_BUFFER_TYPE_DIR 3 /* Directory. */ + +struct virStorageStatBuffer { + int type; /* Device type. */ + unsigned long long size; /* Size in bytes. */ +}; +typedef struct virStorageStatBuffer *virStorageStatBufferPtr; + +struct virStorageStatVFSBuffer { + unsigned long bsize; /* Block size. */ + unsigned long long bavail; /* Blocks available. */ +}; +typedef struct virStorageStatVFSBuffer *virStorageStatVFSBufferPtr; + +#define VIR_STORAGE_GROUP_MAGIC_VER1 0x57083001 + +#define VIR_STORAGE_GROUP_FLAGS_READONLY 1 + +struct virStorageGroup { + int magic; /* Magic / structure version. */ + char *name; /* Volume group name. */ + int flags; /* Flags. */ + unsigned long long size; /* Total size in kilobytes. */ + unsigned long long avail; /* Available (free) space in kilobytes. */ +}; +typedef struct virStorageGroup *virStorageGroupPtr; + +/* Flags for virStorageCreateFile */ +#define VIR_STORAGE_SPARSE_FILE 1 + +/* Storage calls. */ +char **virStorageFileLocations (virConnectPtr conn, size_t *len); +int virStorageFileLocationsFree (virConnectPtr conn, + char **names, size_t len); +int virStorageFileStat (virConnectPtr conn, const char *path, + virStorageStatBufferPtr statbuf, + size_t size); +int virStorageFileStatVFS (virConnectPtr conn, const char *path, + virStorageStatVFSBufferPtr statvfsbuf, + size_t size); +int virStorageCreateFile (virConnectPtr conn, const char *path, + unsigned long long size, int flags); +virStorageGroupPtr * + virStorageListGroups (virConnectPtr conn, size_t *len); +int virStorageListGroupsFree (virConnectPtr conn, + virStorageGroupPtr *groups, size_t len); +char * virStorageCreateVolume (virConnectPtr conn, + const char *name, const char *group, + unsigned long long size, int flags); + #ifdef __cplusplus } #endif #endif /* __VIR_VIRLIB_H__ */ + +/* + * vim: set tabstop=4: + * vim: set shiftwidth=4: + * vim: set expandtab: + */ +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list