On Fri, Nov 22, 2013 at 08:20:30PM -0700, Eric Blake wrote:
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: Eric Blake <eblake(a)redhat.com>
---
src/storage/storage_backend_gluster.c | 76 ++++++++++++++++++++++++++++++++++-
1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/src/storage/storage_backend_gluster.c
b/src/storage/storage_backend_gluster.c
index e935583..b239880 100644
--- a/src/storage/storage_backend_gluster.c
+++ b/src/storage/storage_backend_gluster.c
@@ -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;
+ }
Further down you're requesting O_NONBLOCK, and here you are
not handling EAGAIN explicitly. Is is desirable that we turn
EAGAIN into a fatal error, or should we remove the O_NONBLOCK
flag ?
@@ -208,15 +243,54 @@
virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
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;
+ if (!(fd = glfs_open(state->vol, name, O_RDONLY| O_NONBLOCK | O_NOCTTY))) {
+ /* A dangling symlink now implies a TOCTTOU race; report it. */
+ virReportSystemError(errno, _("cannot open volume '%s'"),
name);
+ goto cleanup;
+ }
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|