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:
+ */
smime.p7s
Description: S/MIME Cryptographic Signature
-- Libvir-list mailing list [email protected] https://www.redhat.com/mailman/listinfo/libvir-list
