mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
storage: Add file storage APIs in the default storage driver
Add APIs that will allow to use the storage driver to assist in operations on files even for remote filesystems without native representation as files in the host.
This commit is contained in:
parent
6fb5a397bf
commit
e32268184b
@ -121,6 +121,12 @@ static virStorageBackendPtr backends[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static virStorageFileBackendPtr fileBackends[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
TOOL_QEMU_IMG,
|
||||
TOOL_KVM_IMG,
|
||||
@ -1152,6 +1158,37 @@ virStorageBackendForType(int type)
|
||||
}
|
||||
|
||||
|
||||
virStorageFileBackendPtr
|
||||
virStorageFileBackendForType(int type,
|
||||
int protocol)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; fileBackends[i]; i++) {
|
||||
if (fileBackends[i]->type == type) {
|
||||
if (type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
|
||||
fileBackends[i]->protocol != protocol)
|
||||
continue;
|
||||
|
||||
return fileBackends[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("missing storage backend for network files "
|
||||
"using %s protocol"),
|
||||
virDomainDiskProtocolTypeToString(protocol));
|
||||
} else {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("missing storage backend for '%s' storage"),
|
||||
virDomainDiskTypeToString(type));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allows caller to silently ignore files with improper mode
|
||||
*
|
||||
|
@ -29,6 +29,7 @@
|
||||
# include "internal.h"
|
||||
# include "storage_conf.h"
|
||||
# include "vircommand.h"
|
||||
# include "storage_driver.h"
|
||||
|
||||
typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn,
|
||||
const char *srcSpec,
|
||||
@ -189,4 +190,44 @@ virStorageBackendCreateQemuImgCmd(virConnectPtr conn,
|
||||
const char *create_tool,
|
||||
int imgformat);
|
||||
|
||||
/* ------- virStorageFile backends ------------ */
|
||||
typedef int
|
||||
(*virStorageFileBackendInit)(virStorageFilePtr file);
|
||||
|
||||
typedef void
|
||||
(*virStorageFileBackendDeinit)(virStorageFilePtr file);
|
||||
|
||||
typedef int
|
||||
(*virStorageFileBackendCreate)(virStorageFilePtr file);
|
||||
|
||||
typedef int
|
||||
(*virStorageFileBackendUnlink)(virStorageFilePtr file);
|
||||
|
||||
typedef int
|
||||
(*virStorageFileBackendStat)(virStorageFilePtr file,
|
||||
struct stat *st);
|
||||
|
||||
typedef struct _virStorageFileBackend virStorageFileBackend;
|
||||
typedef virStorageFileBackend *virStorageFileBackendPtr;
|
||||
|
||||
virStorageFileBackendPtr virStorageFileBackendForType(int type, int protocol);
|
||||
|
||||
struct _virStorageFileBackend {
|
||||
int type;
|
||||
int protocol;
|
||||
|
||||
/* All storage file callbacks may be omitted if not implemented */
|
||||
|
||||
/* The following group of callbacks is expected to set a libvirt
|
||||
* error on failure. */
|
||||
virStorageFileBackendInit backendInit;
|
||||
virStorageFileBackendDeinit backendDeinit;
|
||||
|
||||
/* The following group of callbacks is expected to set errno
|
||||
* and return -1 on error. No libvirt error shall be reported */
|
||||
virStorageFileBackendCreate storageFileCreate;
|
||||
virStorageFileBackendUnlink storageFileUnlink;
|
||||
virStorageFileBackendStat storageFileStat;
|
||||
};
|
||||
|
||||
#endif /* __VIR_STORAGE_BACKEND_H__ */
|
||||
|
@ -2589,6 +2589,7 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static virStorageDriver storageDriver = {
|
||||
.name = "storage",
|
||||
.storageOpen = storageOpen, /* 0.4.0 */
|
||||
@ -2653,3 +2654,147 @@ int storageRegister(void)
|
||||
virRegisterStateDriver(&stateDriver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ----------- file handlers cooperating with storage driver --------------- */
|
||||
void
|
||||
virStorageFileFree(virStorageFilePtr file)
|
||||
{
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
if (file->backend &&
|
||||
file->backend->backendDeinit)
|
||||
file->backend->backendDeinit(file);
|
||||
|
||||
VIR_FREE(file->path);
|
||||
virDomainDiskHostDefFree(file->nhosts, file->hosts);
|
||||
VIR_FREE(file);
|
||||
}
|
||||
|
||||
|
||||
static virStorageFilePtr
|
||||
virStorageFileInitInternal(int type,
|
||||
const char *path,
|
||||
int protocol,
|
||||
size_t nhosts,
|
||||
virDomainDiskHostDefPtr hosts)
|
||||
{
|
||||
virStorageFilePtr file = NULL;
|
||||
|
||||
if (VIR_ALLOC(file) < 0)
|
||||
return NULL;
|
||||
|
||||
file->type = type;
|
||||
file->protocol = protocol;
|
||||
file->nhosts = nhosts;
|
||||
|
||||
if (VIR_STRDUP(file->path, path) < 0)
|
||||
goto error;
|
||||
|
||||
if (!(file->hosts = virDomainDiskHostDefCopy(nhosts, hosts)))
|
||||
goto error;
|
||||
|
||||
if (!(file->backend = virStorageFileBackendForType(file->type,
|
||||
file->protocol)))
|
||||
goto error;
|
||||
|
||||
if (file->backend->backendInit &&
|
||||
file->backend->backendInit(file) < 0)
|
||||
goto error;
|
||||
|
||||
return file;
|
||||
|
||||
error:
|
||||
VIR_FREE(file->path);
|
||||
virDomainDiskHostDefFree(file->nhosts, file->hosts);
|
||||
VIR_FREE(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
virStorageFilePtr
|
||||
virStorageFileInitFromDiskDef(virDomainDiskDefPtr disk)
|
||||
{
|
||||
return virStorageFileInitInternal(virDomainDiskGetActualType(disk),
|
||||
disk->src,
|
||||
disk->protocol,
|
||||
disk->nhosts,
|
||||
disk->hosts);
|
||||
}
|
||||
|
||||
|
||||
virStorageFilePtr
|
||||
virStorageFileInitFromSnapshotDef(virDomainSnapshotDiskDefPtr disk)
|
||||
{
|
||||
return virStorageFileInitInternal(virDomainSnapshotDiskGetActualType(disk),
|
||||
disk->file,
|
||||
disk->protocol,
|
||||
disk->nhosts,
|
||||
disk->hosts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* virStorageFileCreate: Creates an empty storage file via storage driver
|
||||
*
|
||||
* @file: file structure pointing to the file
|
||||
*
|
||||
* Returns 0 on success, -2 if the function isn't supported by the backend,
|
||||
* -1 on other failure. Errno is set in case of failure.
|
||||
*/
|
||||
int
|
||||
virStorageFileCreate(virStorageFilePtr file)
|
||||
{
|
||||
if (!file->backend->storageFileCreate) {
|
||||
errno = ENOSYS;
|
||||
return -2;
|
||||
}
|
||||
|
||||
return file->backend->storageFileCreate(file);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virStorageFileUnlink: Unlink storage file via storage driver
|
||||
*
|
||||
* @file: file structure pointing to the file
|
||||
*
|
||||
* Unlinks the file described by the @file structure.
|
||||
*
|
||||
* Returns 0 on success, -2 if the function isn't supported by the backend,
|
||||
* -1 on other failure. Errno is set in case of failure.
|
||||
*/
|
||||
int
|
||||
virStorageFileUnlink(virStorageFilePtr file)
|
||||
{
|
||||
if (!file->backend->storageFileUnlink) {
|
||||
errno = ENOSYS;
|
||||
return -2;
|
||||
}
|
||||
|
||||
return file->backend->storageFileUnlink(file);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virStorageFileStat: returns stat struct of a file via storage driver
|
||||
*
|
||||
* @file: file structure pointing to the file
|
||||
* @stat: stat structure to return data
|
||||
*
|
||||
* Returns 0 on success, -2 if the function isn't supported by the backend,
|
||||
* -1 on other failure. Errno is set in case of failure.
|
||||
*/
|
||||
int
|
||||
virStorageFileStat(virStorageFilePtr file,
|
||||
struct stat *st)
|
||||
{
|
||||
if (!(file->backend->storageFileStat)) {
|
||||
errno = ENOSYS;
|
||||
return -2;
|
||||
}
|
||||
|
||||
return file->backend->storageFileStat(file, st);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* storage_driver.h: core driver for storage APIs
|
||||
*
|
||||
* Copyright (C) 2006-2008 Red Hat, Inc.
|
||||
* Copyright (C) 2006-2008, 2014 Red Hat, Inc.
|
||||
* Copyright (C) 2006-2008 Daniel P. Berrange
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -25,6 +25,36 @@
|
||||
# define __VIR_STORAGE_DRIVER_H__
|
||||
|
||||
# include "storage_conf.h"
|
||||
# include "conf/domain_conf.h"
|
||||
# include "conf/snapshot_conf.h"
|
||||
|
||||
typedef struct _virStorageFileBackend virStorageFileBackend;
|
||||
typedef virStorageFileBackend *virStorageFileBackendPtr;
|
||||
|
||||
typedef struct _virStorageFile virStorageFile;
|
||||
typedef virStorageFile *virStorageFilePtr;
|
||||
struct _virStorageFile {
|
||||
virStorageFileBackendPtr backend;
|
||||
void *priv;
|
||||
|
||||
char *path;
|
||||
int type;
|
||||
int protocol;
|
||||
|
||||
size_t nhosts;
|
||||
virDomainDiskHostDefPtr hosts;
|
||||
};
|
||||
|
||||
virStorageFilePtr
|
||||
virStorageFileInitFromDiskDef(virDomainDiskDefPtr disk);
|
||||
virStorageFilePtr
|
||||
virStorageFileInitFromSnapshotDef(virDomainSnapshotDiskDefPtr disk);
|
||||
void virStorageFileFree(virStorageFilePtr file);
|
||||
|
||||
int virStorageFileCreate(virStorageFilePtr file);
|
||||
int virStorageFileUnlink(virStorageFilePtr file);
|
||||
int virStorageFileStat(virStorageFilePtr file,
|
||||
struct stat *stat);
|
||||
|
||||
int storageRegister(void);
|
||||
|
||||
|
@ -433,6 +433,9 @@ qemu_LDADDS = ../src/libvirt_driver_qemu_impl.la
|
||||
if WITH_NETWORK
|
||||
qemu_LDADDS += ../src/libvirt_driver_network_impl.la
|
||||
endif WITH_NETWORK
|
||||
if WITH_STORAGE
|
||||
qemu_LDADDS += ../src/libvirt_driver_storage_impl.la
|
||||
endif WITH_STORAGE
|
||||
if WITH_DTRACE_PROBES
|
||||
qemu_LDADDS += ../src/libvirt_qemu_probes.lo
|
||||
endif WITH_DTRACE_PROBES
|
||||
|
Loading…
Reference in New Issue
Block a user