|
|
c401cc |
From 85f4948dd875586b7fa36370d74f0eee828d8322 Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <85f4948dd875586b7fa36370d74f0eee828d8322@dist-git>
|
|
|
c401cc |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
c401cc |
Date: Wed, 26 Feb 2014 14:55:25 +0100
|
|
|
c401cc |
Subject: [PATCH] storage: Add file storage APIs in the default storage driver
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
|
|
|
c401cc |
|
|
|
c401cc |
Add APIs that will allow to use the storage driver to assist in
|
|
|
c401cc |
operations on files even for remote filesystems without native
|
|
|
c401cc |
representation as files in the host.
|
|
|
c401cc |
|
|
|
c401cc |
(cherry picked from commit e32268184b4fd1611ed5ffd3c758b8f6a34152e6)
|
|
|
c401cc |
|
|
|
c401cc |
Conflicts:
|
|
|
c401cc |
tests/Makefile.am - minor context conflict
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/storage/storage_backend.c | 37 +++++++++++
|
|
|
c401cc |
src/storage/storage_backend.h | 41 ++++++++++++
|
|
|
c401cc |
src/storage/storage_driver.c | 145 ++++++++++++++++++++++++++++++++++++++++++
|
|
|
c401cc |
src/storage/storage_driver.h | 32 +++++++++-
|
|
|
c401cc |
tests/Makefile.am | 3 +
|
|
|
c401cc |
5 files changed, 257 insertions(+), 1 deletion(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
|
|
|
c401cc |
index 17168a7..aa620f7 100644
|
|
|
c401cc |
--- a/src/storage/storage_backend.c
|
|
|
c401cc |
+++ b/src/storage/storage_backend.c
|
|
|
c401cc |
@@ -121,6 +121,12 @@ static virStorageBackendPtr backends[] = {
|
|
|
c401cc |
NULL
|
|
|
c401cc |
};
|
|
|
c401cc |
|
|
|
c401cc |
+
|
|
|
c401cc |
+static virStorageFileBackendPtr fileBackends[] = {
|
|
|
c401cc |
+ NULL
|
|
|
c401cc |
+};
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
enum {
|
|
|
c401cc |
TOOL_QEMU_IMG,
|
|
|
c401cc |
TOOL_KVM_IMG,
|
|
|
c401cc |
@@ -1123,6 +1129,37 @@ virStorageBackendForType(int type)
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
|
|
|
c401cc |
+virStorageFileBackendPtr
|
|
|
c401cc |
+virStorageFileBackendForType(int type,
|
|
|
c401cc |
+ int protocol)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ size_t i;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ for (i = 0; fileBackends[i]; i++) {
|
|
|
c401cc |
+ if (fileBackends[i]->type == type) {
|
|
|
c401cc |
+ if (type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
|
|
|
c401cc |
+ fileBackends[i]->protocol != protocol)
|
|
|
c401cc |
+ continue;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return fileBackends[i];
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
+ _("missing storage backend for network files "
|
|
|
c401cc |
+ "using %s protocol"),
|
|
|
c401cc |
+ virDomainDiskProtocolTypeToString(protocol));
|
|
|
c401cc |
+ } else {
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
+ _("missing storage backend for '%s' storage"),
|
|
|
c401cc |
+ virDomainDiskTypeToString(type));
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return NULL;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
/*
|
|
|
c401cc |
* Allows caller to silently ignore files with improper mode
|
|
|
c401cc |
*
|
|
|
c401cc |
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
|
|
|
c401cc |
index 378bc4d..1c7ad1e 100644
|
|
|
c401cc |
--- a/src/storage/storage_backend.h
|
|
|
c401cc |
+++ b/src/storage/storage_backend.h
|
|
|
c401cc |
@@ -29,6 +29,7 @@
|
|
|
c401cc |
# include "internal.h"
|
|
|
c401cc |
# include "storage_conf.h"
|
|
|
c401cc |
# include "vircommand.h"
|
|
|
c401cc |
+# include "storage_driver.h"
|
|
|
c401cc |
|
|
|
c401cc |
typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn,
|
|
|
c401cc |
const char *srcSpec,
|
|
|
c401cc |
@@ -189,4 +190,44 @@ virStorageBackendCreateQemuImgCmd(virConnectPtr conn,
|
|
|
c401cc |
const char *create_tool,
|
|
|
c401cc |
int imgformat);
|
|
|
c401cc |
|
|
|
c401cc |
+/* ------- virStorageFile backends ------------ */
|
|
|
c401cc |
+typedef int
|
|
|
c401cc |
+(*virStorageFileBackendInit)(virStorageFilePtr file);
|
|
|
c401cc |
+
|
|
|
c401cc |
+typedef void
|
|
|
c401cc |
+(*virStorageFileBackendDeinit)(virStorageFilePtr file);
|
|
|
c401cc |
+
|
|
|
c401cc |
+typedef int
|
|
|
c401cc |
+(*virStorageFileBackendCreate)(virStorageFilePtr file);
|
|
|
c401cc |
+
|
|
|
c401cc |
+typedef int
|
|
|
c401cc |
+(*virStorageFileBackendUnlink)(virStorageFilePtr file);
|
|
|
c401cc |
+
|
|
|
c401cc |
+typedef int
|
|
|
c401cc |
+(*virStorageFileBackendStat)(virStorageFilePtr file,
|
|
|
c401cc |
+ struct stat *st);
|
|
|
c401cc |
+
|
|
|
c401cc |
+typedef struct _virStorageFileBackend virStorageFileBackend;
|
|
|
c401cc |
+typedef virStorageFileBackend *virStorageFileBackendPtr;
|
|
|
c401cc |
+
|
|
|
c401cc |
+virStorageFileBackendPtr virStorageFileBackendForType(int type, int protocol);
|
|
|
c401cc |
+
|
|
|
c401cc |
+struct _virStorageFileBackend {
|
|
|
c401cc |
+ int type;
|
|
|
c401cc |
+ int protocol;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ /* All storage file callbacks may be omitted if not implemented */
|
|
|
c401cc |
+
|
|
|
c401cc |
+ /* The following group of callbacks is expected to set a libvirt
|
|
|
c401cc |
+ * error on failure. */
|
|
|
c401cc |
+ virStorageFileBackendInit backendInit;
|
|
|
c401cc |
+ virStorageFileBackendDeinit backendDeinit;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ /* The following group of callbacks is expected to set errno
|
|
|
c401cc |
+ * and return -1 on error. No libvirt error shall be reported */
|
|
|
c401cc |
+ virStorageFileBackendCreate storageFileCreate;
|
|
|
c401cc |
+ virStorageFileBackendUnlink storageFileUnlink;
|
|
|
c401cc |
+ virStorageFileBackendStat storageFileStat;
|
|
|
c401cc |
+};
|
|
|
c401cc |
+
|
|
|
c401cc |
#endif /* __VIR_STORAGE_BACKEND_H__ */
|
|
|
c401cc |
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
|
|
|
c401cc |
index 2eb751d..4e8c8ca 100644
|
|
|
c401cc |
--- a/src/storage/storage_driver.c
|
|
|
c401cc |
+++ b/src/storage/storage_driver.c
|
|
|
c401cc |
@@ -2568,6 +2568,7 @@ cleanup:
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
+
|
|
|
c401cc |
static virStorageDriver storageDriver = {
|
|
|
c401cc |
.name = "storage",
|
|
|
c401cc |
.storageOpen = storageOpen, /* 0.4.0 */
|
|
|
c401cc |
@@ -2630,3 +2631,147 @@ int storageRegister(void) {
|
|
|
c401cc |
virRegisterStateDriver(&stateDriver);
|
|
|
c401cc |
return 0;
|
|
|
c401cc |
}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+/* ----------- file handlers cooperating with storage driver --------------- */
|
|
|
c401cc |
+void
|
|
|
c401cc |
+virStorageFileFree(virStorageFilePtr file)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ if (!file)
|
|
|
c401cc |
+ return;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (file->backend &&
|
|
|
c401cc |
+ file->backend->backendDeinit)
|
|
|
c401cc |
+ file->backend->backendDeinit(file);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ VIR_FREE(file->path);
|
|
|
c401cc |
+ virDomainDiskHostDefFree(file->nhosts, file->hosts);
|
|
|
c401cc |
+ VIR_FREE(file);
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+static virStorageFilePtr
|
|
|
c401cc |
+virStorageFileInitInternal(int type,
|
|
|
c401cc |
+ const char *path,
|
|
|
c401cc |
+ int protocol,
|
|
|
c401cc |
+ size_t nhosts,
|
|
|
c401cc |
+ virDomainDiskHostDefPtr hosts)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ virStorageFilePtr file = NULL;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (VIR_ALLOC(file) < 0)
|
|
|
c401cc |
+ return NULL;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ file->type = type;
|
|
|
c401cc |
+ file->protocol = protocol;
|
|
|
c401cc |
+ file->nhosts = nhosts;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (VIR_STRDUP(file->path, path) < 0)
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (!(file->hosts = virDomainDiskHostDefCopy(nhosts, hosts)))
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (!(file->backend = virStorageFileBackendForType(file->type,
|
|
|
c401cc |
+ file->protocol)))
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (file->backend->backendInit &&
|
|
|
c401cc |
+ file->backend->backendInit(file) < 0)
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return file;
|
|
|
c401cc |
+
|
|
|
c401cc |
+error:
|
|
|
c401cc |
+ VIR_FREE(file->path);
|
|
|
c401cc |
+ virDomainDiskHostDefFree(file->nhosts, file->hosts);
|
|
|
c401cc |
+ VIR_FREE(file);
|
|
|
c401cc |
+ return NULL;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+virStorageFilePtr
|
|
|
c401cc |
+virStorageFileInitFromDiskDef(virDomainDiskDefPtr disk)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ return virStorageFileInitInternal(virDomainDiskGetActualType(disk),
|
|
|
c401cc |
+ disk->src,
|
|
|
c401cc |
+ disk->protocol,
|
|
|
c401cc |
+ disk->nhosts,
|
|
|
c401cc |
+ disk->hosts);
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+virStorageFilePtr
|
|
|
c401cc |
+virStorageFileInitFromSnapshotDef(virDomainSnapshotDiskDefPtr disk)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ return virStorageFileInitInternal(virDomainSnapshotDiskGetActualType(disk),
|
|
|
c401cc |
+ disk->file,
|
|
|
c401cc |
+ disk->protocol,
|
|
|
c401cc |
+ disk->nhosts,
|
|
|
c401cc |
+ disk->hosts);
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+/**
|
|
|
c401cc |
+ * virStorageFileCreate: Creates an empty storage file via storage driver
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * @file: file structure pointing to the file
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Returns 0 on success, -2 if the function isn't supported by the backend,
|
|
|
c401cc |
+ * -1 on other failure. Errno is set in case of failure.
|
|
|
c401cc |
+ */
|
|
|
c401cc |
+int
|
|
|
c401cc |
+virStorageFileCreate(virStorageFilePtr file)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ if (!file->backend->storageFileCreate) {
|
|
|
c401cc |
+ errno = ENOSYS;
|
|
|
c401cc |
+ return -2;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return file->backend->storageFileCreate(file);
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+/**
|
|
|
c401cc |
+ * virStorageFileUnlink: Unlink storage file via storage driver
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * @file: file structure pointing to the file
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Unlinks the file described by the @file structure.
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Returns 0 on success, -2 if the function isn't supported by the backend,
|
|
|
c401cc |
+ * -1 on other failure. Errno is set in case of failure.
|
|
|
c401cc |
+ */
|
|
|
c401cc |
+int
|
|
|
c401cc |
+virStorageFileUnlink(virStorageFilePtr file)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ if (!file->backend->storageFileUnlink) {
|
|
|
c401cc |
+ errno = ENOSYS;
|
|
|
c401cc |
+ return -2;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return file->backend->storageFileUnlink(file);
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+/**
|
|
|
c401cc |
+ * virStorageFileStat: returns stat struct of a file via storage driver
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * @file: file structure pointing to the file
|
|
|
c401cc |
+ * @stat: stat structure to return data
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Returns 0 on success, -2 if the function isn't supported by the backend,
|
|
|
c401cc |
+ * -1 on other failure. Errno is set in case of failure.
|
|
|
c401cc |
+*/
|
|
|
c401cc |
+int
|
|
|
c401cc |
+virStorageFileStat(virStorageFilePtr file,
|
|
|
c401cc |
+ struct stat *st)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ if (!(file->backend->storageFileStat)) {
|
|
|
c401cc |
+ errno = ENOSYS;
|
|
|
c401cc |
+ return -2;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return file->backend->storageFileStat(file, st);
|
|
|
c401cc |
+}
|
|
|
c401cc |
diff --git a/src/storage/storage_driver.h b/src/storage/storage_driver.h
|
|
|
c401cc |
index 8ccfd75..993bba5 100644
|
|
|
c401cc |
--- a/src/storage/storage_driver.h
|
|
|
c401cc |
+++ b/src/storage/storage_driver.h
|
|
|
c401cc |
@@ -1,7 +1,7 @@
|
|
|
c401cc |
/*
|
|
|
c401cc |
* storage_driver.h: core driver for storage APIs
|
|
|
c401cc |
*
|
|
|
c401cc |
- * Copyright (C) 2006-2008 Red Hat, Inc.
|
|
|
c401cc |
+ * Copyright (C) 2006-2008, 2014 Red Hat, Inc.
|
|
|
c401cc |
* Copyright (C) 2006-2008 Daniel P. Berrange
|
|
|
c401cc |
*
|
|
|
c401cc |
* This library is free software; you can redistribute it and/or
|
|
|
c401cc |
@@ -25,6 +25,36 @@
|
|
|
c401cc |
# define __VIR_STORAGE_DRIVER_H__
|
|
|
c401cc |
|
|
|
c401cc |
# include "storage_conf.h"
|
|
|
c401cc |
+# include "conf/domain_conf.h"
|
|
|
c401cc |
+# include "conf/snapshot_conf.h"
|
|
|
c401cc |
+
|
|
|
c401cc |
+typedef struct _virStorageFileBackend virStorageFileBackend;
|
|
|
c401cc |
+typedef virStorageFileBackend *virStorageFileBackendPtr;
|
|
|
c401cc |
+
|
|
|
c401cc |
+typedef struct _virStorageFile virStorageFile;
|
|
|
c401cc |
+typedef virStorageFile *virStorageFilePtr;
|
|
|
c401cc |
+struct _virStorageFile {
|
|
|
c401cc |
+ virStorageFileBackendPtr backend;
|
|
|
c401cc |
+ void *priv;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ char *path;
|
|
|
c401cc |
+ int type;
|
|
|
c401cc |
+ int protocol;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ size_t nhosts;
|
|
|
c401cc |
+ virDomainDiskHostDefPtr hosts;
|
|
|
c401cc |
+};
|
|
|
c401cc |
+
|
|
|
c401cc |
+virStorageFilePtr
|
|
|
c401cc |
+virStorageFileInitFromDiskDef(virDomainDiskDefPtr disk);
|
|
|
c401cc |
+virStorageFilePtr
|
|
|
c401cc |
+virStorageFileInitFromSnapshotDef(virDomainSnapshotDiskDefPtr disk);
|
|
|
c401cc |
+void virStorageFileFree(virStorageFilePtr file);
|
|
|
c401cc |
+
|
|
|
c401cc |
+int virStorageFileCreate(virStorageFilePtr file);
|
|
|
c401cc |
+int virStorageFileUnlink(virStorageFilePtr file);
|
|
|
c401cc |
+int virStorageFileStat(virStorageFilePtr file,
|
|
|
c401cc |
+ struct stat *stat);
|
|
|
c401cc |
|
|
|
c401cc |
int storageRegister(void);
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
|
|
c401cc |
index 88b2224..e49eadc 100644
|
|
|
c401cc |
--- a/tests/Makefile.am
|
|
|
c401cc |
+++ b/tests/Makefile.am
|
|
|
c401cc |
@@ -394,6 +394,9 @@ qemu_LDADDS = ../src/libvirt_driver_qemu_impl.la
|
|
|
c401cc |
if WITH_NETWORK
|
|
|
c401cc |
qemu_LDADDS += ../src/libvirt_driver_network_impl.la
|
|
|
c401cc |
endif
|
|
|
c401cc |
+if WITH_STORAGE
|
|
|
c401cc |
+qemu_LDADDS += ../src/libvirt_driver_storage_impl.la
|
|
|
c401cc |
+endif WITH_STORAGE
|
|
|
c401cc |
if WITH_DTRACE_PROBES
|
|
|
c401cc |
qemu_LDADDS += ../src/libvirt_qemu_probes.lo
|
|
|
c401cc |
endif
|
|
|
c401cc |
--
|
|
|
c401cc |
1.9.0
|
|
|
c401cc |
|