提交 14daa812 编写于 作者: E Eric Blake

storage: probe qcow2 volumes in gluster pool

Putting together pieces from previous patches, it is now possible
for 'virsh vol-dumpxml --pool gluster volname' to report metadata
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
(virStorageBackendGlusterReadHeader): New helper function.
(virStorageBackendGlusterRefreshVol): Probe non-raw files.
Signed-off-by: NEric Blake <eblake@redhat.com>
上级 79eb21f9
...@@ -147,6 +147,37 @@ error: ...@@ -147,6 +147,37 @@ error:
} }
static ssize_t
virStorageBackendGlusterReadHeader(glfs_fd_t *fd,
const char *name,
ssize_t maxlen,
char **buf)
{
char *s;
size_t nread = 0;
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 /* Populate *volptr for the given name and stat information, or leave
* it NULL if the entry should be skipped (such as "."). Return 0 on * it NULL if the entry should be skipped (such as "."). Return 0 on
* success, -1 on failure. */ * success, -1 on failure. */
...@@ -159,6 +190,10 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state, ...@@ -159,6 +190,10 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
char *tmp; char *tmp;
int ret = -1; int ret = -1;
virStorageVolDefPtr vol = NULL; virStorageVolDefPtr vol = NULL;
glfs_fd_t *fd = NULL;
virStorageFileMetadata *meta = NULL;
char *header = NULL;
ssize_t len = VIR_STORAGE_MAX_HEADER;
*volptr = NULL; *volptr = NULL;
...@@ -208,15 +243,57 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state, ...@@ -208,15 +243,57 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
goto cleanup; goto cleanup;
} }
/* FIXME - must open files to determine if they are non-raw */
vol->type = VIR_STORAGE_VOL_NETWORK; vol->type = VIR_STORAGE_VOL_NETWORK;
vol->target.format = VIR_STORAGE_FILE_RAW; vol->target.format = VIR_STORAGE_FILE_RAW;
/* No need to worry about O_NONBLOCK - gluster doesn't allow creation
* of fifos, so there's nothing it would protect us from. */
if (!(fd = glfs_open(state->vol, name, O_RDONLY | O_NOCTTY))) {
/* A dangling symlink now implies a TOCTTOU race; report it. */
virReportSystemError(errno, _("cannot open volume '%s'"), name);
goto cleanup;
}
if ((len = virStorageBackendGlusterReadHeader(fd, name, len, &header)) < 0)
goto cleanup;
if ((vol->target.format = virStorageFileProbeFormatFromBuf(name,
header,
len)) < 0)
goto clenaup;
if (!(meta = virStorageFileGetMetadataFromBuf(name, header, len,
vol->target.format)))
goto cleanup;
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; *volptr = vol;
vol = NULL; vol = NULL;
ret = 0; ret = 0;
cleanup: cleanup:
virStorageFileFreeMetadata(meta);
virStorageVolDefFree(vol); virStorageVolDefFree(vol);
if (fd)
glfs_close(fd);
VIR_FREE(header);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册