|
|
c401cc |
From 62a72076e2fe3431de116d0ddc9f5811a9bbbce0 Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <62a72076e2fe3431de116d0ddc9f5811a9bbbce0@dist-git>
|
|
|
c401cc |
From: Eric Blake <eblake@redhat.com>
|
|
|
c401cc |
Date: Wed, 26 Feb 2014 14:54:28 +0100
|
|
|
c401cc |
Subject: [PATCH] storage: probe qcow2 volumes in gluster pool
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
|
|
|
c401cc |
|
|
|
c401cc |
Putting together pieces from previous patches, it is now possible
|
|
|
c401cc |
for 'virsh vol-dumpxml --pool gluster volname' to report metadata
|
|
|
c401cc |
about a qcow2 file stored on gluster. The backing file is still
|
|
|
c401cc |
treated as raw; to fix that, more patches are needed to make the
|
|
|
c401cc |
storage backing chain analysis recursive rather than halting at
|
|
|
c401cc |
a network protocol name, but that work will not need any further
|
|
|
c401cc |
calls into libgfapi so much as just reusing this code, and that
|
|
|
c401cc |
should be the only code outside of the storage driver that needs
|
|
|
c401cc |
any help from libgfapi. Any additional use of libgfapi within
|
|
|
c401cc |
libvirt should only be needed for implementing storage pool APIs
|
|
|
c401cc |
such as volume creation or resizing, where backing chain analysis
|
|
|
c401cc |
should be unaffected.
|
|
|
c401cc |
|
|
|
c401cc |
* src/storage/storage_backend_gluster.c
|
|
|
c401cc |
(virStorageBackendGlusterReadHeader): New helper function.
|
|
|
c401cc |
(virStorageBackendGlusterRefreshVol): Probe non-raw files.
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
c401cc |
(cherry picked from commit 14daa81280dfabb8c553c4d5a84cfcc4a0235366)
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/storage/storage_backend_gluster.c | 79 ++++++++++++++++++++++++++++++++++-
|
|
|
c401cc |
1 file changed, 78 insertions(+), 1 deletion(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
|
|
|
c401cc |
index f0ec357..01af4bd 100644
|
|
|
c401cc |
--- a/src/storage/storage_backend_gluster.c
|
|
|
c401cc |
+++ b/src/storage/storage_backend_gluster.c
|
|
|
c401cc |
@@ -147,6 +147,37 @@ error:
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
|
|
|
c401cc |
+static ssize_t
|
|
|
c401cc |
+virStorageBackendGlusterReadHeader(glfs_fd_t *fd,
|
|
|
c401cc |
+ const char *name,
|
|
|
c401cc |
+ ssize_t maxlen,
|
|
|
c401cc |
+ char **buf)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ char *s;
|
|
|
c401cc |
+ size_t nread = 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (VIR_ALLOC_N(*buf, maxlen) < 0)
|
|
|
c401cc |
+ return -1;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ s = *buf;
|
|
|
c401cc |
+ while (maxlen) {
|
|
|
c401cc |
+ ssize_t r = glfs_read(fd, s, maxlen, 0);
|
|
|
c401cc |
+ if (r < 0 && errno == EINTR)
|
|
|
c401cc |
+ continue;
|
|
|
c401cc |
+ if (r < 0) {
|
|
|
c401cc |
+ VIR_FREE(*buf);
|
|
|
c401cc |
+ virReportSystemError(errno, _("unable to read '%s'"), name);
|
|
|
c401cc |
+ return r;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ if (r == 0)
|
|
|
c401cc |
+ return nread;
|
|
|
c401cc |
+ buf += r;
|
|
|
c401cc |
+ maxlen -= r;
|
|
|
c401cc |
+ nread += r;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ return nread;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
/* Populate *volptr for the given name and stat information, or leave
|
|
|
c401cc |
* it NULL if the entry should be skipped (such as "."). Return 0 on
|
|
|
c401cc |
* success, -1 on failure. */
|
|
|
c401cc |
@@ -159,6 +190,10 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
|
|
|
c401cc |
char *tmp;
|
|
|
c401cc |
int ret = -1;
|
|
|
c401cc |
virStorageVolDefPtr vol = NULL;
|
|
|
c401cc |
+ glfs_fd_t *fd = NULL;
|
|
|
c401cc |
+ virStorageFileMetadata *meta = NULL;
|
|
|
c401cc |
+ char *header = NULL;
|
|
|
c401cc |
+ ssize_t len = VIR_STORAGE_MAX_HEADER;
|
|
|
c401cc |
|
|
|
c401cc |
*volptr = NULL;
|
|
|
c401cc |
|
|
|
c401cc |
@@ -208,15 +243,57 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- /* FIXME - must open files to determine if they are non-raw */
|
|
|
c401cc |
vol->type = VIR_STORAGE_VOL_NETWORK;
|
|
|
c401cc |
vol->target.format = VIR_STORAGE_FILE_RAW;
|
|
|
c401cc |
+ /* No need to worry about O_NONBLOCK - gluster doesn't allow creation
|
|
|
c401cc |
+ * of fifos, so there's nothing it would protect us from. */
|
|
|
c401cc |
+ if (!(fd = glfs_open(state->vol, name, O_RDONLY | O_NOCTTY))) {
|
|
|
c401cc |
+ /* A dangling symlink now implies a TOCTTOU race; report it. */
|
|
|
c401cc |
+ virReportSystemError(errno, _("cannot open volume '%s'"), name);
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if ((len = virStorageBackendGlusterReadHeader(fd, name, len, &header)) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if ((vol->target.format = virStorageFileProbeFormatFromBuf(name,
|
|
|
c401cc |
+ header,
|
|
|
c401cc |
+ len)) < 0)
|
|
|
c401cc |
+ goto clenaup;
|
|
|
c401cc |
+ if (!(meta = virStorageFileGetMetadataFromBuf(name, header, len,
|
|
|
c401cc |
+ vol->target.format)))
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (meta->backingStore) {
|
|
|
c401cc |
+ vol->backingStore.path = meta->backingStore;
|
|
|
c401cc |
+ meta->backingStore = NULL;
|
|
|
c401cc |
+ vol->backingStore.format = meta->backingStoreFormat;
|
|
|
c401cc |
+ if (vol->backingStore.format < 0)
|
|
|
c401cc |
+ vol->backingStore.format = VIR_STORAGE_FILE_RAW;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ if (meta->capacity)
|
|
|
c401cc |
+ vol->capacity = meta->capacity;
|
|
|
c401cc |
+ if (meta->encrypted) {
|
|
|
c401cc |
+ if (VIR_ALLOC(vol->target.encryption) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ if (vol->target.format == VIR_STORAGE_FILE_QCOW ||
|
|
|
c401cc |
+ vol->target.format == VIR_STORAGE_FILE_QCOW2)
|
|
|
c401cc |
+ vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ vol->target.features = meta->features;
|
|
|
c401cc |
+ meta->features = NULL;
|
|
|
c401cc |
+ vol->target.compat = meta->compat;
|
|
|
c401cc |
+ meta->compat = NULL;
|
|
|
c401cc |
|
|
|
c401cc |
*volptr = vol;
|
|
|
c401cc |
vol = NULL;
|
|
|
c401cc |
ret = 0;
|
|
|
c401cc |
cleanup:
|
|
|
c401cc |
+ virStorageFileFreeMetadata(meta);
|
|
|
c401cc |
virStorageVolDefFree(vol);
|
|
|
c401cc |
+ if (fd)
|
|
|
c401cc |
+ glfs_close(fd);
|
|
|
c401cc |
+ VIR_FREE(header);
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
--
|
|
|
c401cc |
1.9.0
|
|
|
c401cc |
|