[libvirt] [PATCHv3 4/4] storage: probe qcow2 volumes in gluster pool
Peter Krempa
pkrempa at redhat.com
Tue Nov 12 16:00:39 UTC 2013
On 11/12/13 05:19, Eric Blake wrote:
> Putting together pieces from previous patches, it is now possible
> for 'virsh dumpxml --pool gluster volname' to report metadata
Did you mean 'virsh vol-dumpxml --pool ... '?
> about a qcow2 file stored on gluster. The backing file is still
> treated as raw; to fix that, more patches are needed to make the
> storage backing chain analysis recursive rather than halting at
> a network protocol name, but that work will not need any further
> calls into libgfapi so much as just reusing this code, and that
> should be the only code outside of the storage driver that needs
> any help from libgfapi. Any additional use of libgfapi within
> libvirt should only be needed for implementing storage pool APIs
> such as volume creation or resizing, where backing chain analysis
> should be unaffected.
>
> * src/storage/storage_backend_gluster.c
> (virStorageBackendGlusterOpen): Make relative name handling easier.
> (virStorageBackendGlusterReadHeader): New helper function.
> (virStorageBackendGlusterRefreshVol): Probe non-raw files.
>
> Signed-off-by: Eric Blake <eblake at redhat.com>
> ---
> src/storage/storage_backend_gluster.c | 87 +++++++++++++++++++++++++++++++++++
> 1 file changed, 87 insertions(+)
>
> diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
> index bc90de9..69e8e61 100644
> --- a/src/storage/storage_backend_gluster.c
> +++ b/src/storage/storage_backend_gluster.c
...
> @@ -124,6 +130,37 @@ error:
> }
>
>
> +static int
This function is declared as an int, but ...
> +virStorageBackendGlusterReadHeader(glfs_fd_t *fd,
> + const char *name,
> + int maxlen,
> + char **buf)
> +{
> + char *s;
> + size_t nread = 0;
.. returns size_t. This could overflow normally, but is guarded by
maxlen. Okay.
> +
> + if (VIR_ALLOC_N(*buf, maxlen) < 0)
> + return -1;
> +
> + s = *buf;
> + while (maxlen) {
> + ssize_t r = glfs_read(fd, s, maxlen, 0);
> + if (r < 0 && errno == EINTR)
> + continue;
> + if (r < 0) {
> + VIR_FREE(*buf);
> + virReportSystemError(errno, _("unable to read '%s'"), name);
> + return r;
> + }
> + if (r == 0)
> + return nread;
> + buf += r;
> + maxlen -= r;
> + nread += r;
> + }
> + return nread;
> +}
> +
> /* Populate *volptr for the given name and stat information, or leave
> * it NULL if the entry should be skipped (such as "."). Return 0 on
> * success, -1 on failure. */
...
> @@ -162,11 +203,57 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
> }
> state->uri->path = tmp;
>
> + if (!(fd = glfs_open(state->vol, name, O_RDONLY| O_NONBLOCK | O_NOCTTY))) {
> + if ((errno == ENOENT || errno == ELOOP) &&
> + S_ISLNK(st->st_mode)) {
> + VIR_WARN("ignoring dangling symlink '%s'", name);
> + ret = 0;
> + } else {
> + virReportSystemError(errno, _("cannot open volume '%s'"), name);
> + }
> + goto cleanup;
> + }
Now that you actually open the volume file and probe it, you need to
kill the comment added in previous patch:
+ if (VIR_ALLOC(vol) < 0 ||
+ VIR_STRDUP(vol->name, name) < 0 ||
+ virAsprintf(&vol->key, "%s%s/%s",
+ *pool == '/' ? "" : "/", pool, vol->name) < 0)
+ goto cleanup;
+
+ /* FIXME - must open files to determine if they are non-raw */
+ vol->type = VIR_STORAGE_VOL_NETWORK;
+ vol->target.format = VIR_STORAGE_FILE_RAW;
+ vol->capacity = vol->allocation = st->st_size;
+ tmp = state->uri->path;
+ state->uri->path = vol->key;
+ if (!(vol->target.path = virURIFormat(state->uri))) {
+ state->uri->path = tmp;
+ goto cleanup;
> +
> + if ((len = virStorageBackendGlusterReadHeader(fd, name, len, &header)) < 0)
> + goto cleanup;
> +
> + if ((vol->target.format = virStorageFileProbeFormatFromBuf(name,
> + header,
> + len)) < 0 ||
> + !(meta = virStorageFileGetMetadataFromBuf(name, header, len,
> + vol->target.format)))
> + goto cleanup;
Also as you are erroring out in case of failure, you can remove the
lines setting some of the defaults.
> +
> + if (meta->backingStore) {
> + vol->backingStore.path = meta->backingStore;
> + meta->backingStore = NULL;
> + vol->backingStore.format = meta->backingStoreFormat;
> + if (vol->backingStore.format < 0)
> + vol->backingStore.format = VIR_STORAGE_FILE_RAW;
> + }
> + if (meta->capacity)
> + vol->capacity = meta->capacity;
> + if (meta->encrypted) {
> + if (VIR_ALLOC(vol->target.encryption) < 0)
> + goto cleanup;
> + if (vol->target.format == VIR_STORAGE_FILE_QCOW ||
> + vol->target.format == VIR_STORAGE_FILE_QCOW2)
> + vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
> + }
> + vol->target.features = meta->features;
> + meta->features = NULL;
> + vol->target.compat = meta->compat;
> + meta->compat = NULL;
> +
> *volptr = vol;
> vol = NULL;
> ret = 0;
> cleanup:
> + virStorageFileFreeMetadata(meta);
> virStorageVolDefFree(vol);
> + if (fd)
> + glfs_close(fd);
> + VIR_FREE(header);
> return ret;
> }
>
ACK with the comment nit fixed.
Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20131112/8f00ac2d/attachment-0001.sig>
More information about the libvir-list
mailing list