storage: Make virStorageFileReadHeader more universal

Allow specifying offset to read an arbitrary position in the file. This
warrants a rename to virStorageFileRead.
This commit is contained in:
Peter Krempa 2017-05-12 13:57:25 +02:00
parent 9506bd25a3
commit 204f373a91
6 changed files with 67 additions and 45 deletions

View File

@ -11584,8 +11584,7 @@ qemuStorageLimitsRefresh(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
} else { } else {
if ((len = virStorageFileReadHeader(src, VIR_STORAGE_MAX_HEADER, if ((len = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, &buf)) < 0)
&buf)) < 0)
goto cleanup; goto cleanup;
} }

View File

@ -154,9 +154,10 @@ typedef int
struct stat *st); struct stat *st);
typedef ssize_t typedef ssize_t
(*virStorageFileBackendReadHeader)(virStorageSourcePtr src, (*virStorageFileBackendRead)(virStorageSourcePtr src,
ssize_t max_len, size_t offset,
char **buf); size_t len,
char **buf);
typedef const char * typedef const char *
(*virStorageFileBackendGetUniqueIdentifier)(virStorageSourcePtr src); (*virStorageFileBackendGetUniqueIdentifier)(virStorageSourcePtr src);
@ -186,7 +187,7 @@ struct _virStorageFileBackend {
* error on failure. */ * error on failure. */
virStorageFileBackendInit backendInit; virStorageFileBackendInit backendInit;
virStorageFileBackendDeinit backendDeinit; virStorageFileBackendDeinit backendDeinit;
virStorageFileBackendReadHeader storageFileReadHeader; virStorageFileBackendRead storageFileRead;
virStorageFileBackendGetUniqueIdentifier storageFileGetUniqueIdentifier; virStorageFileBackendGetUniqueIdentifier storageFileGetUniqueIdentifier;
/* The following group of callbacks is expected to set errno /* The following group of callbacks is expected to set errno

View File

@ -779,9 +779,10 @@ virStorageFileBackendFileStat(virStorageSourcePtr src,
static ssize_t static ssize_t
virStorageFileBackendFileReadHeader(virStorageSourcePtr src, virStorageFileBackendFileRead(virStorageSourcePtr src,
ssize_t max_len, size_t offset,
char **buf) size_t len,
char **buf)
{ {
int fd = -1; int fd = -1;
ssize_t ret = -1; ssize_t ret = -1;
@ -793,7 +794,14 @@ virStorageFileBackendFileReadHeader(virStorageSourcePtr src,
return -1; return -1;
} }
if ((ret = virFileReadHeaderFD(fd, max_len, buf)) < 0) { if (offset > 0) {
if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
virReportSystemError(errno, _("cannot seek into '%s'"), src->path);
goto cleanup;
}
}
if ((ret = virFileReadHeaderFD(fd, len, buf)) < 0) {
virReportSystemError(errno, virReportSystemError(errno,
_("cannot read header '%s'"), src->path); _("cannot read header '%s'"), src->path);
goto cleanup; goto cleanup;
@ -850,7 +858,7 @@ virStorageFileBackend virStorageFileBackendFile = {
.storageFileCreate = virStorageFileBackendFileCreate, .storageFileCreate = virStorageFileBackendFileCreate,
.storageFileUnlink = virStorageFileBackendFileUnlink, .storageFileUnlink = virStorageFileBackendFileUnlink,
.storageFileStat = virStorageFileBackendFileStat, .storageFileStat = virStorageFileBackendFileStat,
.storageFileReadHeader = virStorageFileBackendFileReadHeader, .storageFileRead = virStorageFileBackendFileRead,
.storageFileAccess = virStorageFileBackendFileAccess, .storageFileAccess = virStorageFileBackendFileAccess,
.storageFileChown = virStorageFileBackendFileChown, .storageFileChown = virStorageFileBackendFileChown,
@ -865,7 +873,7 @@ virStorageFileBackend virStorageFileBackendBlock = {
.backendDeinit = virStorageFileBackendFileDeinit, .backendDeinit = virStorageFileBackendFileDeinit,
.storageFileStat = virStorageFileBackendFileStat, .storageFileStat = virStorageFileBackendFileStat,
.storageFileReadHeader = virStorageFileBackendFileReadHeader, .storageFileRead = virStorageFileBackendFileRead,
.storageFileAccess = virStorageFileBackendFileAccess, .storageFileAccess = virStorageFileBackendFileAccess,
.storageFileChown = virStorageFileBackendFileChown, .storageFileChown = virStorageFileBackendFileChown,

View File

@ -151,20 +151,20 @@ virStorageBackendGlusterOpen(virStoragePoolObjPtr pool)
static ssize_t static ssize_t
virStorageBackendGlusterReadHeader(glfs_fd_t *fd, virStorageBackendGlusterRead(glfs_fd_t *fd,
const char *name, const char *name,
ssize_t maxlen, size_t len,
char **buf) char **buf)
{ {
char *s; char *s;
size_t nread = 0; size_t nread = 0;
if (VIR_ALLOC_N(*buf, maxlen) < 0) if (VIR_ALLOC_N(*buf, len) < 0)
return -1; return -1;
s = *buf; s = *buf;
while (maxlen) { while (len) {
ssize_t r = glfs_read(fd, s, maxlen, 0); ssize_t r = glfs_read(fd, s, len, 0);
if (r < 0 && errno == EINTR) if (r < 0 && errno == EINTR)
continue; continue;
if (r < 0) { if (r < 0) {
@ -175,7 +175,7 @@ virStorageBackendGlusterReadHeader(glfs_fd_t *fd,
if (r == 0) if (r == 0)
return nread; return nread;
s += r; s += r;
maxlen -= r; len -= r;
nread += r; nread += r;
} }
return nread; return nread;
@ -246,7 +246,7 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
glfs_fd_t *fd = NULL; glfs_fd_t *fd = NULL;
virStorageSourcePtr meta = NULL; virStorageSourcePtr meta = NULL;
char *header = NULL; char *header = NULL;
ssize_t len = VIR_STORAGE_MAX_HEADER; ssize_t len;
int backingFormat; int backingFormat;
*volptr = NULL; *volptr = NULL;
@ -292,7 +292,8 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
goto cleanup; goto cleanup;
} }
if ((len = virStorageBackendGlusterReadHeader(fd, name, len, &header)) < 0) if ((len = virStorageBackendGlusterRead(fd, name, VIR_STORAGE_MAX_HEADER,
&header)) < 0)
goto cleanup; goto cleanup;
if (!(meta = virStorageFileGetMetadataFromBuf(name, header, len, if (!(meta = virStorageFileGetMetadataFromBuf(name, header, len,
@ -721,9 +722,10 @@ virStorageFileBackendGlusterStat(virStorageSourcePtr src,
static ssize_t static ssize_t
virStorageFileBackendGlusterReadHeader(virStorageSourcePtr src, virStorageFileBackendGlusterRead(virStorageSourcePtr src,
ssize_t max_len, size_t offset,
char **buf) size_t len,
char **buf)
{ {
virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; virStorageFileBackendGlusterPrivPtr priv = src->drv->priv;
glfs_fd_t *fd = NULL; glfs_fd_t *fd = NULL;
@ -737,8 +739,16 @@ virStorageFileBackendGlusterReadHeader(virStorageSourcePtr src,
return -1; return -1;
} }
ret = virStorageBackendGlusterReadHeader(fd, src->path, max_len, buf); if (offset > 0) {
if (glfs_lseek(fd, offset, SEEK_SET) == (off_t) -1) {
virReportSystemError(errno, _("cannot seek into '%s'"), src->path);
goto cleanup;
}
}
ret = virStorageBackendGlusterRead(fd, src->path, len, buf);
cleanup:
if (fd) if (fd)
glfs_close(fd); glfs_close(fd);
@ -851,7 +861,7 @@ virStorageFileBackend virStorageFileBackendGluster = {
.storageFileCreate = virStorageFileBackendGlusterCreate, .storageFileCreate = virStorageFileBackendGlusterCreate,
.storageFileUnlink = virStorageFileBackendGlusterUnlink, .storageFileUnlink = virStorageFileBackendGlusterUnlink,
.storageFileStat = virStorageFileBackendGlusterStat, .storageFileStat = virStorageFileBackendGlusterStat,
.storageFileReadHeader = virStorageFileBackendGlusterReadHeader, .storageFileRead = virStorageFileBackendGlusterRead,
.storageFileAccess = virStorageFileBackendGlusterAccess, .storageFileAccess = virStorageFileBackendGlusterAccess,
.storageFileChown = virStorageFileBackendGlusterChown, .storageFileChown = virStorageFileBackendGlusterChown,

View File

@ -64,7 +64,7 @@ virStorageFileSupportsBackingChainTraversal(virStorageSourcePtr src)
} }
return backend->storageFileGetUniqueIdentifier && return backend->storageFileGetUniqueIdentifier &&
backend->storageFileReadHeader && backend->storageFileRead &&
backend->storageFileAccess; backend->storageFileAccess;
} }
@ -263,20 +263,22 @@ virStorageFileStat(virStorageSourcePtr src,
/** /**
* virStorageFileReadHeader: read the beginning bytes of a file into a buffer * virStorageFileRead: read bytes from a file into a buffer
* *
* @src: file structure pointing to the file * @src: file structure pointing to the file
* @max_len: maximum number of bytes read from the storage file * @offset: number of bytes to skip in the storage file
* @buf: buffer to read the data into. buffer shall be freed by caller) * @len: maximum number of bytes read from the storage file
* @buf: buffer to read the data into. (buffer shall be freed by caller)
* *
* Returns the count of bytes read on success and -1 on failure, -2 if the * Returns the count of bytes read on success and -1 on failure, -2 if the
* function isn't supported by the backend. * function isn't supported by the backend.
* Libvirt error is reported on failure. * Libvirt error is reported on failure.
*/ */
ssize_t ssize_t
virStorageFileReadHeader(virStorageSourcePtr src, virStorageFileRead(virStorageSourcePtr src,
ssize_t max_len, size_t offset,
char **buf) size_t len,
char **buf)
{ {
ssize_t ret; ssize_t ret;
@ -286,18 +288,19 @@ virStorageFileReadHeader(virStorageSourcePtr src,
return -1; return -1;
} }
if (!src->drv->backend->storageFileReadHeader) { if (!src->drv->backend->storageFileRead) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("storage file header reading is not supported for " _("storage file reading is not supported for "
"storage type %s (protocol: %s)"), "storage type %s (protocol: %s)"),
virStorageTypeToString(src->type), virStorageTypeToString(src->type),
virStorageNetProtocolTypeToString(src->protocol)); virStorageNetProtocolTypeToString(src->protocol));
return -2; return -2;
} }
ret = src->drv->backend->storageFileReadHeader(src, max_len, buf); ret = src->drv->backend->storageFileRead(src, offset, len, buf);
VIR_DEBUG("read of storage header %p: ret=%zd", src, ret); VIR_DEBUG("read '%zd' bytes from storage '%p' starting at offset '%zu'",
ret, src, offset);
return ret; return ret;
} }
@ -444,8 +447,8 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
if (virHashAddEntry(cycle, uniqueName, (void *)1) < 0) if (virHashAddEntry(cycle, uniqueName, (void *)1) < 0)
goto cleanup; goto cleanup;
if ((headerLen = virStorageFileReadHeader(src, VIR_STORAGE_MAX_HEADER, if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
&buf)) < 0) &buf)) < 0)
goto cleanup; goto cleanup;
if (virStorageFileGetMetadataInternal(src, buf, headerLen, if (virStorageFileGetMetadataInternal(src, buf, headerLen,
@ -565,8 +568,8 @@ virStorageFileGetBackingStoreStr(virStorageSourcePtr src)
if (virStorageFileAccess(src, F_OK) < 0) if (virStorageFileAccess(src, F_OK) < 0)
return NULL; return NULL;
if ((headerLen = virStorageFileReadHeader(src, VIR_STORAGE_MAX_HEADER, if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
&buf)) < 0) &buf)) < 0)
return NULL; return NULL;
if (!(tmp = virStorageSourceCopy(src, false))) if (!(tmp = virStorageSourceCopy(src, false)))

View File

@ -32,9 +32,10 @@ int virStorageFileCreate(virStorageSourcePtr src);
int virStorageFileUnlink(virStorageSourcePtr src); int virStorageFileUnlink(virStorageSourcePtr src);
int virStorageFileStat(virStorageSourcePtr src, int virStorageFileStat(virStorageSourcePtr src,
struct stat *stat); struct stat *stat);
ssize_t virStorageFileReadHeader(virStorageSourcePtr src, ssize_t virStorageFileRead(virStorageSourcePtr src,
ssize_t max_len, size_t offset,
char **buf); size_t len,
char **buf);
const char *virStorageFileGetUniqueIdentifier(virStorageSourcePtr src); const char *virStorageFileGetUniqueIdentifier(virStorageSourcePtr src);
int virStorageFileAccess(virStorageSourcePtr src, int mode); int virStorageFileAccess(virStorageSourcePtr src, int mode);
int virStorageFileChown(const virStorageSource *src, uid_t uid, gid_t gid); int virStorageFileChown(const virStorageSource *src, uid_t uid, gid_t gid);