mirror of https://gitee.com/openkylin/libvirt.git
storage: don't require caller to pre-allocate metadata struct
Requiring pre-allocation was an unusual idiom. It allowed iteration over the backing chain to use fewer mallocs, but made one-shot clients harder to read. Also, this makes it easier for a future patch to move away from opening fds on every iteration over the chain. * src/util/storage_file.h (virStorageFileGetMetadataFromFD): Alter signature. * src/util/storage_file.c (virStorageFileGetMetadataFromFD): Allocate return value. (virStorageFileGetMetadata): Update clients. * src/conf/domain_conf.c (virDomainDiskDefForeachPath): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo): Likewise. * src/storage/storage_backend_fs.c (virStorageBackendProbeTarget): Likewise.
This commit is contained in:
parent
35c74c1733
commit
1fc9593271
|
@ -14848,16 +14848,11 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
size_t depth = 0;
|
size_t depth = 0;
|
||||||
char *nextpath = NULL;
|
char *nextpath = NULL;
|
||||||
virStorageFileMetadata *meta;
|
virStorageFileMetadata *meta = NULL;
|
||||||
|
|
||||||
if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (VIR_ALLOC(meta) < 0) {
|
|
||||||
virReportOOMError();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disk->format > 0) {
|
if (disk->format > 0) {
|
||||||
format = disk->format;
|
format = disk->format;
|
||||||
} else {
|
} else {
|
||||||
|
@ -14900,7 +14895,7 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virStorageFileGetMetadataFromFD(path, fd, format, meta) < 0) {
|
if (!(meta = virStorageFileGetMetadataFromFD(path, fd, format))) {
|
||||||
VIR_FORCE_CLOSE(fd);
|
VIR_FORCE_CLOSE(fd);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -14934,6 +14929,8 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
||||||
/* Allow probing for image formats that are safe */
|
/* Allow probing for image formats that are safe */
|
||||||
if (format == VIR_STORAGE_FILE_AUTO_SAFE)
|
if (format == VIR_STORAGE_FILE_AUTO_SAFE)
|
||||||
format = VIR_STORAGE_FILE_AUTO;
|
format = VIR_STORAGE_FILE_AUTO;
|
||||||
|
virStorageFileFreeMetadata(meta);
|
||||||
|
meta = NULL;
|
||||||
} while (nextpath);
|
} while (nextpath);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
|
@ -9313,14 +9313,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(meta) < 0) {
|
if (!(meta = virStorageFileGetMetadataFromFD(path, fd, format)))
|
||||||
virReportOOMError();
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virStorageFileGetMetadataFromFD(path, fd,
|
|
||||||
format,
|
|
||||||
meta) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Get info for normal formats */
|
/* Get info for normal formats */
|
||||||
|
|
|
@ -68,12 +68,7 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
virStorageFileMetadata *meta;
|
virStorageFileMetadata *meta = NULL;
|
||||||
|
|
||||||
if (VIR_ALLOC(meta) < 0) {
|
|
||||||
virReportOOMError();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
*backingStore = NULL;
|
*backingStore = NULL;
|
||||||
*backingStoreFormat = VIR_STORAGE_FILE_AUTO;
|
*backingStoreFormat = VIR_STORAGE_FILE_AUTO;
|
||||||
|
@ -96,9 +91,8 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virStorageFileGetMetadataFromFD(target->path, fd,
|
if (!(meta = virStorageFileGetMetadataFromFD(target->path, fd,
|
||||||
target->format,
|
target->format))) {
|
||||||
meta) < 0) {
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -851,41 +851,43 @@ virStorageFileProbeFormat(const char *path)
|
||||||
* backing store. Callers are advised against probing for the
|
* backing store. Callers are advised against probing for the
|
||||||
* backing store format in this case.
|
* backing store format in this case.
|
||||||
*
|
*
|
||||||
* Caller MUST free @meta after use via virStorageFileFreeMetadata.
|
* Caller MUST free the result after use via virStorageFileFreeMetadata.
|
||||||
*/
|
*/
|
||||||
int
|
virStorageFileMetadataPtr
|
||||||
virStorageFileGetMetadataFromFD(const char *path,
|
virStorageFileGetMetadataFromFD(const char *path,
|
||||||
int fd,
|
int fd,
|
||||||
int format,
|
int format)
|
||||||
virStorageFileMetadata *meta)
|
|
||||||
{
|
{
|
||||||
|
virStorageFileMetadata *meta = NULL;
|
||||||
unsigned char *head = NULL;
|
unsigned char *head = NULL;
|
||||||
ssize_t len = STORAGE_MAX_HEAD;
|
ssize_t len = STORAGE_MAX_HEAD;
|
||||||
int ret = -1;
|
virStorageFileMetadata *ret = NULL;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
memset(meta, 0, sizeof(*meta));
|
if (VIR_ALLOC(meta) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (fstat(fd, &sb) < 0) {
|
if (fstat(fd, &sb) < 0) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("cannot stat file '%s'"),
|
_("cannot stat file '%s'"),
|
||||||
path);
|
path);
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No header to probe for directories */
|
/* No header to probe for directories, but also no backing file */
|
||||||
if (S_ISDIR(sb.st_mode)) {
|
if (S_ISDIR(sb.st_mode))
|
||||||
return 0;
|
return meta;
|
||||||
}
|
|
||||||
|
|
||||||
if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
|
if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
|
||||||
virReportSystemError(errno, _("cannot seek to start of '%s'"), path);
|
virReportSystemError(errno, _("cannot seek to start of '%s'"), path);
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC_N(head, len) < 0) {
|
if (VIR_ALLOC_N(head, len) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((len = read(fd, head, len)) < 0) {
|
if ((len = read(fd, head, len)) < 0) {
|
||||||
|
@ -903,9 +905,13 @@ virStorageFileGetMetadataFromFD(const char *path,
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = virStorageFileGetMetadataFromBuf(format, path, head, len, meta);
|
if (virStorageFileGetMetadataFromBuf(format, path, head, len, meta) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
ret = meta;
|
||||||
|
meta = NULL;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
virStorageFileFreeMetadata(meta);
|
||||||
VIR_FREE(head);
|
VIR_FREE(head);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -933,21 +939,12 @@ virStorageFileGetMetadataRecurse(const char *path, int format,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(ret) < 0) {
|
ret = virStorageFileGetMetadataFromFD(path, fd, format);
|
||||||
virReportOOMError();
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (virStorageFileGetMetadataFromFD(path, fd, format, ret) < 0) {
|
|
||||||
virStorageFileFreeMetadata(ret);
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VIR_CLOSE(fd) < 0)
|
if (VIR_CLOSE(fd) < 0)
|
||||||
VIR_WARN("could not close file %s", path);
|
VIR_WARN("could not close file %s", path);
|
||||||
|
|
||||||
if (ret->backingStoreIsFile) {
|
if (ret && ret->backingStoreIsFile) {
|
||||||
if (ret->backingStoreFormat == VIR_STORAGE_FILE_AUTO && !allow_probe)
|
if (ret->backingStoreFormat == VIR_STORAGE_FILE_AUTO && !allow_probe)
|
||||||
ret->backingStoreFormat = VIR_STORAGE_FILE_RAW;
|
ret->backingStoreFormat = VIR_STORAGE_FILE_RAW;
|
||||||
else if (ret->backingStoreFormat == VIR_STORAGE_FILE_AUTO_SAFE)
|
else if (ret->backingStoreFormat == VIR_STORAGE_FILE_AUTO_SAFE)
|
||||||
|
|
|
@ -73,10 +73,9 @@ virStorageFileMetadataPtr virStorageFileGetMetadata(const char *path,
|
||||||
int format,
|
int format,
|
||||||
uid_t uid, gid_t gid,
|
uid_t uid, gid_t gid,
|
||||||
bool allow_probe);
|
bool allow_probe);
|
||||||
int virStorageFileGetMetadataFromFD(const char *path,
|
virStorageFileMetadataPtr virStorageFileGetMetadataFromFD(const char *path,
|
||||||
int fd,
|
int fd,
|
||||||
int format,
|
int format);
|
||||||
virStorageFileMetadata *meta);
|
|
||||||
|
|
||||||
void virStorageFileFreeMetadata(virStorageFileMetadataPtr meta);
|
void virStorageFileFreeMetadata(virStorageFileMetadataPtr meta);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue